命令注入是指應用程序執行命令的字符串或字符串的一部分來源于不可信賴的數據源,程序沒有對這
些不可信賴的數據進行驗證、過濾,導致程序執行惡意命令的一種攻擊方式。
例 1 :以下代碼通過 Runtime.exec() 方法調用 Windows 的 dir 命令,列出目錄列表。
import java.io.*;
public class DirList {
public static void main(String[] str) throws Exception {
String dir = System.getProperty("dir");
Process proc = Runtime.getRuntime().exec("cmd.exe /c dir" + dir);
int result = proc.waitFor();
if (result != 0) {
System.out.println("process error: " + result);
}
InputStream in = (result == 0) ? proc.getInputStream() : proc.getErrorStream();
int c;
while ((c = in.read()) != -1) {
System.out.print((char) c);
}
}
}
攻擊者可以通過以下命令利用該程序。
java -Ddir='dummy & echo bad' DirList
該命令實際上執行的是以下兩條命令。
cmd.exe /c dir dummy & echo bad
例 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);
...
該段代碼沒有對來自用戶請求中的 backuptype 參數做任何校驗。
通常情況下, Runtime.exec() 函數不會執行多條命令,但在以上代碼中,為了執行多條命令,程序調用
Runtime.exec() 方法,首先運行了 cmd.exe 指令,因此能夠執行用兩個與號分隔的多條命令了。如果攻擊者
傳遞了一個形式為 "&& del c:\\dbms\\*.*" 的字符串,那么該段代碼將會在執行其他指定命令的同時執行這
條命令。