类型: 安全缺陷
命令注入是指,在应用程序执行的命令中包含来源于不可信数据时,程序本身没有对这些不可信数据做正确、合理的验证和过滤,导致系统执行恶意命令。
import java.io.*;
public class DirList {
public static void main(String[] args) {
String dir = System.getProperty("dir");
Process process = null;
InputStream istream = null;
try {
process = Runtime.getRuntime().exec("cmd.exe /c dir" + dir);
int result = process.waitFor();
if (result != 0) {
System.out.println("process error: " + result);
}
istream = (result == 0) ? process.getInputStream() : process.getErrorStream();
byte[] buffer = new byte[512];
while (istream.read(buffer) != -1) {
System.out.print(new String(buffer, "gb2312"));
}
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e2) {
e2.printStackTrace();
} finally {
if (istream != null) {
try {
istream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (process != null) {
process.destroy();
}
}
}
}
攻击者可以构造特殊命令参数来利用该程序,例如:
java -Ddir=”..\ & shutdown -s -t 60” DirList
上面的命令实际上执行下面两条命令:
cmd.exe /c dir ..\ & shutdown -s -t 60
例2:以下代码片段来自一个Web应用程序,它该段代码通过运行rmanDB.bat脚本启动Oracle数据库备份,然后运行cleanup.bat脚本删除一些临时文件。脚本文件rmanDB.bat接受一个命令行参数,指明需要执行的备份类型。
String btype = request.getParameter("backuptype");
String cmd = new String("cmd.exe /K \"c:\\util\\rmanDB.bat "+btype+"&& c:\\utl\\cleanup.bat\"");
System.Runtime.getRuntime().exec(cmd);
该段代码没有对来自用户请求中的参数做任何校验。
通常情况下,Runtime.exec()函数不会执行多条命令,但在以上代码中,为了执行多条命令,程序调用Runtime.exec()方法,首先运行了cmd.exe指令,因此能够执行用&&分隔的多条命令了。如果攻击者传递了一个形式为&& del c:\dbms\.的字符串,那么该段代码将会在执行其他指定命令的同时执行这条命令。
public String getResponse(String endpoint) {
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new URL(endpoint));
call.setOperation("list");
...
}
在搭建的Axis 1.4+Tomcat6的环境,将AdminService配置中的enableRemoteAdmin属性设置为true时,如果上面提供访问WebService的字符串变量endpoint是受外部可控的,那么攻击者很可能利用精心设计的字符串作为endpoint的输入值,从而构造出包含注入命令的SOAP请求协议,进而实施命令注入攻击。