NO.2
ID:CWE-78
Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
以下为CWE网站中对OS Command Injection的一些示范,
原网址:http://cwe.mitre.org/data/definitions/78.html#Detection%20Methods
有一小部分是机翻,感觉这种还是重在实践,望,共同进步~
例1
这个例子尝试获取username以及显示这个用户主目录下的内容。
Example Language: PHP (bad code)
$userName = $_POST["user"];
$command = 'ls -l /home/' . $userName;
system($command);
这个$username变量没有检查是否有恶意输入,攻击者可以将$username修改为任意的操作系统命令,如:
;rm -rf /
这将导致$command变为
ls -l /home/;rm -rf /
因为在unix中,分号分割了每一条命令,所以操作系统将先执行ls这条命令,然后再执行rm,删除整个文件系统。
例2
这个例子是一个对用户提供的域名进行DNS查找的网络应用程序。
Example Language: Perl (bad code)
use CGI qw(:standard);
$name = param('name');
$nslookup = "/path/to/nslookup";
print header;
if (open($fh, "$nslookup $name|")) {
while (<$fh>) {
print escapeHTML($_);
print "<br>\n";
}
close($fh);
}
如果攻击者提供这样的域名:
cwe.mitre.org%20%3B%20/bin/ls%20-l
%3B意指“;”,%20意指“ ”(一个空格),以上域名即为:
/path/to/nslookup cwe.mitre.org ; /bin/ls -l
攻击者可以执行“ /bin/ls -l”,以获得工作目录下的文件列表。
例3
这个例子可以读取要从系统中执行的shell脚本的名称。
Example Language: Java (bad code)
String script = System.getProperty("SCRIPTNAME");
if (script != null)
System.exec(script);
如果攻击者对该属性拥有控制权,则可以修改该属性以指向危险程序。
例4
这个例子使用了一种方法将地理坐标经度和纬度变换到UTM格式,该方法通过HTTP请求从用户获取输入坐标,并执行本地应用程序进行转换,通过纬度和经度坐标作为命令行选项的外部程序并且检索转换的结果,同时返回UTM坐标。
Example Language: Java (bad code)
public String coordinateTransformLatLonToUTM(String coordinates)
{
String utmCoords = null;
try {
String latlonCoords = coordinates;
Runtime rt = Runtime.getRuntime();
Process exec = rt.exec("cmd.exe /C latlon2utm.exe -" + latlonCoords);
// process results of coordinate transform
// ...
}
catch(Exception e) {...}
return utmCoords;
}
但是,该方法不验证坐标输入参数的内容是否包含正确的经纬度坐标。如果在调用此方法之前未验证输入坐标,恶意用户可以通过附加“&”,然后将另一个程序的命令附加到坐标字符串的结尾,向应用服务器本地执行另一个程序。“&”指示Windows操作系统执行另一个程序。
例5
这个例子从一个管理Web应用程序,允许用户开始使用一个批处理文件进行Oracle数据库备份,然后运行一个cleanup.bat脚本删除一些临时文件。rmandb.bat接受一个命令行参数,它指定要执行的备份类型。由于对数据库的访问受到限制,应用程序将备份作为特权用户运行。
Example Language: Java (bad code)
...
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);
...
这里的程序不从用户处阅读backuptype参数,不做任何验证的问题。通常情况下Runtime.exec()函数将不执行多个命令,但在这种情况下,程序首先运行cmd.exe,这样就可以只一个Runtime.exec()就可以运行多个命令。一旦外壳被调用,它会执行多个命令,这些命令是被两个符号分开的。如果攻击者传递了一个类似"& del c:\\dbms\\*.*"的字符串,那么应用程序将与程序指定的其他命令一起执行该命令。由于应用程序的特性,它与数据库交互所必需的特权一起运行,这意味着攻击者注入的任何命令也将与这些特权一起运行。