指令是與電腦互動的一種方式,一般來說作業系統會包含至少一個 Shell 程式,例如 Linux 常見的 bash
、 Windows 內建的 cmd
。使用者可以在 Shell 中執行命令,藉此指揮作業系統處理任務。
這些命令可能是 Shell 自帶的功能,例如 pwd
、 test
、cd
等,又或者是執行檔,例如 nslookup
、 ip
、 grep
等。
有些時候,網頁程式欲達成的功能早已有相當成熟的指令可以使用,如果要重新實作,除了需要開發時間之外,還可能開發出來的執行效率、穩定性皆不如現有的指令。為了避免重複造輪子,網頁工程師便可能選擇直接呼叫現有的指令。此時,若前端使用者的輸入能夠影響到指令參數,便有可能改變指令行為,甚至呼叫其他額外的指令。
工程師為了方便處理,可能會直接撰寫執行外部程式的函數,若未對輸入做過濾,駭客就能注入惡意指令,造成危害
在 PHP 中,下列是常被用於呼叫外部指令的方法:
system
函數exec
函數shell_exec
函數passthru
函數例如網頁的 PHP 如下:
<?php
$dir = $_GET['cmd'];
system("echo ".$dir);
?>
<網址>?cmd=hello
,頁面會顯示 hello。此時駭客注入 <網址>?cmd=hi && ls
頁面除了顯示 hi
,也會顯示當前目錄底下的檔案以 bash
為例,連接多條指令的方法:
aaa && bbb
為例,只有在 aaa
成功執行時, bbb
才會跟著被執行。 (echo 基本上都為 true) (&&
在 URL 編碼中為 %26%26
)aaa || bbb
為例,只有在 aaa
執行失敗時, bbb
才會跟著被執行。 (||
URL編碼 %7C%7C
)aaa ; bbb
為例,無論 aaa
成功與否,都會執行 bbb
。aaa %0a bbb
為例,無論 aaa
成功與否,都會執行 bbb
。 (%0a
為 \n
)aaa %0d bbb
為例,無論 aaa
成功與否,都會執行 bbb
。 (%0d
為 \r
)此外, "$(指令)"
或 "
指令"
也會執行中間的指令 (注意,若將雙引號改成單引號,例如'$(指令)'
或 '
指令'
則會將單引號中的內容視為字串)
若網頁伺服器是使用 Windows 作業系統,以 cmd
為例,可以使用 &&
、 ||
、 %0a
,用法與 bash
相同。
在 Windows 中的跳脫字元為 ^
,Linux 的跳脫字元為 \
,可以把特殊符號(例如 &&
或 ||
)變成一般字串處理