
批處理變量值中含有特殊符號的討論聲明:1、討論中的問題并不是本人發現的,而是參考了https://www.thesecurityfactory.be/command-injection-windows.html,大家可以看一下該網址的內容(不過都是英文的,本人英語一般般,大概看懂6、7成而已^^),如果大家還有什么新的發現,歡迎大家幫忙補充。2、該文中討論的問題,是希望大家能夠在編寫批處理腳本時引起注意,而不是讓大家利用其中的漏洞做一些違法的事情,這一點尤其要申明一下。3、該討論中的一些技術點,本人就不過多展開(其實都是些基礎知識,不懂的話就上網搜查一下)在批處理腳本中,經常會使用到變量,也會為變量進行賦值等操作。如果變量的值含有一些特殊的符號,比如&、|等,在使用時會出現意想不到的結果。首先,我先講兩個小知識點,因為下面討論的問題用到,但我不過多的展開來講,具體的內容請自己上網搜索。第一,&、&&,以及 |和||的作用。命令1&命令2執行命令1后再執行命令2命令1&&命令2執行命令1成功才執行命令2 命令1|命令2將執行命令1的結果傳遞給命令2命令1||命令2執行命令1失敗才執行命令2第二,設置變量時,可以用^符號去將上述講到的單個特殊符號(如&,|)轉義成字面上的含義,而不帶有特殊作用。例如,set VAR=TEST^&DIR 就是將變量VAR設置為TEST&DIR,如果沒有^,則這條命令會理解成set VAR=TEST & DIR,即先設置VAR的變量為TEST,再執行DIR命令set VAR=TEST^&^&DIR 就是將變量VAR設置為TEST&DIR,如果沒有^,則這條命令會理解成set VAR=TEST && DIR,即設置VAR的變量為TEST成功后才執行DIR命令這里本人就拿&進行舉例,其他特殊符號(&&,|,||)可以自己嘗試一下,效果差不多。……………………………………在命令行中輸入:
其結果是不是跟自己預想的不一樣。下面,我們就來分析一下。首先,SET VAR=TEST^&PING 127.0.0.1這個命令將VAR的值設置為TEST&PING 127.0.0.1再執行ECHO %VAR%命令時,命令行解析器會先把%VAR%用變量值(如果有設置,否則就按原來的字面意思)代替,結果展開來就是ECHO TEST&PING 127.0.0.1,然后命令行解析器才會對該行進行解釋,這樣就會將解釋為執行ECHO TEST后,再執行PING 127.0.0.1同理,執行SET VAR1=%VAR%命令時,命令行解析器也是先把%VAR%用變量值(如果有設置,否則就按原來的字面意思)代替,結果展開來就是SET VAR1=TEST&PING 127.0.0.1,然后命令行解析器才會對該行進行解釋,這樣就會將解釋為執行SET VAR1=TEST后,再執行PING 127.0.0.1大家可以以此類推。由于這樣的原因,很容易被黑客抓住該漏洞進行攻擊。在批處理當中,經常會用到這兩個內置的環境變量,%CD%和%__CD__%。這兩個都表示當前目錄的完整路徑,不同的是%__CD__%最后會緊跟著反斜杠,而%CD%除了根目錄外,最后都不緊跟著反斜杠。設想一下,在一個有多人共享的文件服務器,有人故意創建一個特殊目錄如下:MD mydir&malware.exemalware.exe是一個病毒程序,位于該目錄下然后管理員可能會用一些批處理對每個目錄進行遍歷,去執行一些任務,這些批處理會以管理員的權限進入當前目錄,同時為了保存當前目錄的路徑,會有這樣一句命令SET CurrentPath=%CD%,通過上面所講,你就知道這句話就會類似擴展成SET CurrentPath=fileServer1Shareuser1mydir&malware.exe,這樣,批處理就會不小心執行malware.exe這個病毒程序。補充一下:我參考上面介紹的網址https://www.thesecurityfactory.be/command-injection-windows.html,創建了一個特殊目錄如下:md TEST&PING 127.0.0.1 ,然后進入到這個目錄中,用ECHO %CD%和SET CurrentPath=%CD%,發現它照常輸出:TEST&PING 127.0.0.1整句字符串,和將 CurrentPath 設置為TEST&PING 127.0.0.1整句字符串,而不會去執行PING 127.0.0.1。這些操作都是在我的XP和win7系統上測試過,可是,我在那個網址上看到試驗的結果是與我測試的情況卻不相同,我猜想微軟后來可能打了補丁吧。具體情況,我希望大家誰有比較舊的系統上測試一下,看一看結果怎樣?但是,我發現問題仍然存在。這些直接對內置環境變量操作ECHO %CD%和SET CurrentPath=%CD%沒有多大問題,但是如果我們將%CD%的值賦值給別的變量,如SET CURRENDIR=%CD%, 然后執行ECHO %CURRENDIR%和SET CurrentPath=%CURRENDIR%時,仍然會有上述問題發生,大家可以自己測試一下。因為一些舊的文件服務器,還有很多公司還在使用,可能沒有打補丁吧,仍然會被一些別有用心的人利用,大家要注意一下!接下來,我們如何避免這種情況呢?比較簡單的方法,就是在引用變量時加上雙引號,如:nclick="copycode($('code0'));">復制代碼
- SET VAR=TEST^&PING 127.0.0.1
- 緊接著輸入:
- ECHO %VAR%
- 結果為:
- TEST
- 正在 Ping 127.0.0.1 具有 32 字節的數據:
- 來自 127.0.0.1 的回復: 字節=32 時間<1ms TTL=64
- 來自 127.0.0.1 的回復: 字節=32 時間<1ms TTL=64
- 來自 127.0.0.1 的回復: 字節=32 時間<1ms TTL=64
- 來自 127.0.0.1 的回復: 字節=32 時間<1ms TTL=64
- 127.0.0.1 的 Ping 統計信息:
- 數據包: 已發送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
- 往返行程的估計時間(以毫秒為單位):
- 最短 = 0ms,最長 = 0ms,平均 = 0ms
- 或者輸入:
- SET VAR1=%VAR%
- 結果為:
- 正在 Ping 127.0.0.1 具有 32 字節的數據:
- 來自 127.0.0.1 的回復: 字節=32 時間<1ms TTL=64
- 來自 127.0.0.1 的回復: 字節=32 時間<1ms TTL=64
- 來自 127.0.0.1 的回復: 字節=32 時間<1ms TTL=64
- 來自 127.0.0.1 的回復: 字節=32 時間<1ms TTL=64
- 127.0.0.1 的 Ping 統計信息:
- 數據包: 已發送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
- 往返行程的估計時間(以毫秒為單位):
- 最短 = 0ms,最長 = 0ms,平均 = 0ms
但是,這個方法不是萬能的,如果變量的值本身含有雙引號就會失效,例如:nclick="copycode($('code1'));">復制代碼
- SET CurrentPath=%CD%
大家測試一下,會發現其會啟動計算器程序(calc)注意:這點并不適用于%CD%,因為文件和目錄名都不能包含雙引號。更多的相關知識點,大家還可以參考以下網址:http://www.robvanderwoude.com/ba ... tedcdexploit.php#CDnclick="copycode($('code2'));">復制代碼
- SET B=T&calc&
- SET C=%B%

