从一个ctf题中学到的多种php disable_functions bypass 姿势
题目介绍
题目是Lilctf2025 的php-jail-is-my-cry
比赛链接:https://lilctf.xinshi.fun/
题目环境前半部分是 php最近的phar 新 trick
大佬的原理分析
https://fushuling.com/index.php/2025/07/30/%e5%bd%93include%e9%82%82%e9%80%85phar-deadsecctf2025-baby-web/
具体题目操作可看出题人博客https://blog.kengwang.com.cn/archives/668/#php-jail-is-my-cry
这里重点讲学习到的disable_functions bypass 姿势
现在的条件是 题目有文件上传的功能以及可以写webshell,但有严格的disable_functions以及disable_classes
姿势1 fpc_cnext
题目不出网且要执行/readflag, 因此执行/readflag并写到web目录
disable_function ban了很多,剩下file_put_contents
和curl
相关函数以及其他没啥大用的
curl 可以用file协议读取任意文件,很容易想到打cnext,CVE-2024-2961
文件就用curl file协议读取,payload生成用柯佬的脚本https://github.com/kezibei/php-filter-iconv
但rce需要文件操作的函数来触发,这里只有file_put_contents
,不同于之前常见的file_get_contents
直接放payload就行,需要稍作修改,与之前 file_put_contents
绕过死亡exit的方式差不多
不用data协议,数据要自己手动填入,在filter链子前加上个base64-decode,而且filter要要用write=,用read=也可以,得写把payload先写到文件里 resource的文件名随意
姿势2 curlfile_cnext
这个方法是从出题人博客中学到的,非常牛
payload 如下
$cu = curl_init('http://localhost/');
curl_setopt($cu, CURLOPT_RETURNTRANSFER, true);
curl_setopt($cu, CURLOPT_POST, true);
$f = new CURLFile($_GET[0]);
curl_setopt($cu, CURLOPT_POSTFIELDS, ['f' => $f,
]);
$data = curl_exec($cu);
echo $data;
姿势3 curl加载so
这个姿势是我在比赛时的做法,搜到了国外的文章,说curl 有个 --engine选项可以加载so文件rce
https://hackerone.com/reports/3293801
那就利用题目的文件上传传个so,用curl_setopt
指定so文件来rce