EdgeOne安全專項實踐:上傳檔案漏洞攻擊詳解與防範措施

努力的小雨發表於2024-07-30

前言

今天,我們將深入探討上傳檔案漏洞攻擊,這部分內容是EdgeOne專項實踐篇的一部分。在本章中,我們不會涉及檔案漏洞的含義、原理或站點配置等基礎教程,如果你對這些內容感興趣,可以參考這篇文章:探索網路安全:淺析檔案上傳漏洞

在本段之後將不再詳述如何購買套餐或配置站點等基礎應用。而當我們講解完攻擊之後,我還會分享一些防範措施,以保護您的伺服器免受攻擊。因此,本文的焦點依然集中在騰訊雲的EdgeOne上。

截圖

靶場搭建

當我們考慮到攻擊他人伺服器屬於違法行為時,我們需要思考如何更好地保護我們自己的伺服器。為了測試和學習,我們可以搭建一個專門的靶場來模擬檔案上傳漏洞攻擊。以下是我搭建靶場的環境和一些參考資料,供大家學習和參考,也可以自行探索相關內容。

使用騰訊雲輕量應用伺服器的Linux版本時,考慮到環境要求較為嚴格,自行搭建可能存在諸多錯誤。可以簡單地透過拉取他人封裝好的docker映象來快速部署。

docker pull c0ny1/upload-labs

docker run -d -p 8289:80 c0ny1/upload-labs

在啟動之後,請務必前往騰訊雲控制檯進行防火牆規則的配置,否則可能無法正常訪問。你可以使用自己配置的IP地址和埠號替換訪問地址:http://ip:8289

image

系統可以正常啟動。然而,當嘗試上傳檔案時,系統會提示找不到所需的upload目錄。為了解決這個問題,需要透過docker容器控制檯手動新增一個upload目錄。

image

進去之後執行下命令:

mkdir upload

chmod 777 upload

當下一切執行正常,靶場已成功搭建!請牢記,在學習完成後,請勿攻擊他人的伺服器。這一點至關重要,切記、切記、切記。

檔案上傳漏洞

靶場共設有20個關卡,每一個關卡都代表一個不同的漏洞案例。在這裡,我將選擇幾個典型的案例與大家分享和學習。那麼,我們現在就開始吧!

upload-labs靶場攻略

為了避免長篇文字對大家造成干擾,我已經準備了一張簡明的流程圖,幫助大家快速理解。請大家先看一下這張圖,相信你們會覺得一切都變得非常簡單。現在我們準備出發了,請繫好安全帶。

image

接下來,我們的所有任務都依賴於上傳一個或多個檔案來訪問伺服器配置資訊。攻擊指令碼的設計也極其簡單,其目標同樣明確:只需透過其他途徑訪問我們的攻擊指令碼併成功執行即可。

<?php
phpinfo();
?>

當我們談論獲取資訊的用處時,是否可以用於攻擊?實際上,我們的主要目的是執行指令碼。對於指令碼的內容並不重要,關鍵是能夠順利執行。你可以隨意替換指令碼的語句,例如像蟻劍的一句話指令碼來獲取shell。這裡只是為了演示攻擊的目的而已。

下面我們開始講解一下如何使用靶場,請注意每個頁面都配備了檢視原始碼和檢視提示的功能。如果檢視原始碼後仍不清楚如何進行攻擊,可以根據提示逐步闖關。那麼,讓我們開始吧。

image

前端頁面校驗漏洞

我們先看下原始碼:

image

當我們審視這段程式碼時,可以注意到,這裡僅僅是在前端進行了一個基本的字尾校驗。

image

那麼,我們可以選擇在不依賴於工具的情況下,透過修改前端程式碼以移除這一驗證步驟來實現上傳,或者手動修改請求以將檔案字尾改為.php的方式來進行。我們可以先從簡單的方法開始。

image

接下來,進行刪除操作並儲存檔案,隨後再次上傳我們的指令碼檔案。

image

請儲存更改後,確保重新整理頁面,以便介面能夠識別我們上傳的以.php結尾的檔案。

image

由於這並非一張圖片,因此它無法顯示。因此,請右鍵複製圖片路徑以檢視。操作已成功執行。

image

後端校驗檔案型別漏洞

當然,即使是最差勁的公司也不能僅僅依賴前端進行校驗,因此第二個階段就開始涉及後端操作。現在我們繼續檢視原始碼;

image

後端的主要功能是獲取上傳檔案的型別。要修改檔案型別,我們需要使用Burp Suite工具進行攔截。僅僅改變檔案字尾是不夠的,因為這裡傳輸的檔案型別是透過Content-Type標頭傳遞的,具體來說是application/octet-stream

image

當系統後臺基於檔案型別進行判斷時,我們只需調整檔案型別以符合後臺校驗的要求,具體如下所示:

image

不出所料,我們依然會發現上傳成功的情況。

image

剩下的步驟是右鍵點選開啟影像檔案的地址。在接下來的關卡中,我們不再需要演示檢視PHP資訊,只需透過驗證即可確保我們的程式碼成功執行。

image

老版本檔案字尾

這一關,如果發現無論如何都無法有效進行校驗,那麼最好的做法是直接限制可上傳檔案的字尾名。然而,單純依賴檔案字尾名來進行限制也存在潛在的安全隱患。讓我們深入分析一下這個問題。

image

在早期的Web開發階段,PHP檔案常以.php3結尾。這是因為舊版PHP僅支援.php3字尾,而不直接支援.php。儘管現代PHP版本不再強制要求特定的檔案字尾,仍有一些網站因為歷史或相容性原因仍在使用.php3字尾。為了支援這些老版本網站,Apache預設配置支援解析.php3字尾的PHP檔案。

現在問題就變得非常簡單了,我們只需上傳那些不在字尾限制陣列中的檔案,然後一切搞定。

image

利用Apache配置檔案

當談到上述情況時,一些人可能已經認識到,不再可以隨意使用簡單的檔案字尾名。我需要全面審查並加強這方面的限制,這樣我們就進入了第四階段。現在讓我們來仔細檢視原始碼。

image

當然,我們不必侷限於上傳 PHP 檔案。這次,我們可以利用另一個配置檔案的漏洞進行攻擊。

.htaccess 是一個用於配置 Apache Web 伺服器的配置檔案,其名稱是 "hypertext access" 的縮寫。它允許網站管理員在沒有修改主配置檔案(如 httpd.conf)的情況下,透過在網站根目錄或特定目錄下建立 .htaccess 檔案來進行配置和控制網站的行為。

.htaccess 檔案可以包含各種指令和規則,用於控制網站的訪問許可權、重定向 URL、設定自定義錯誤頁面、啟用壓縮、禁止目錄列表、限制訪問速率等等。透過 .htaccess 檔案,網站管理員可以在不需要伺服器級別訪問的情況下,實現對網站的靈活配置和管理。

需要注意的是,.htaccess 檔案只對 Apache Web 伺服器有效,而且其配置可能會影響網站的效能,特別是如果包含複雜的規則或需要頻繁讀取檔案時。

那我們先寫指令碼後傳檔案。

<FilesMatch "loudong.jpg">
SetHandler application/x-httpd-php
</FilesMatch>

這句話的意思就是當訪問到名為 loudong.jpg 的檔案時,Apache Web 伺服器會將其當作 PHP 指令碼來處理,而不是簡單地作為靜態檔案直接返回給使用者。

繼續上傳jpg圖片,儘管這個檔案實際上是一個偽裝成圖片的攻擊指令碼。

image

大小寫漏洞

當人員發現漏洞後,簡單地新增一個限制即可解決問題。因此,第五關的解決方案是直接禁止上傳.htaccess檔案。

image

當然,他未能察覺到另一個問題。再次檢視原始碼。

image

檔名都是小寫的,但是我們需要確認一下,PHP是否支援大寫檔名。我們可以試一試直接攔截請求並修改檔名來測試。

image

空格漏洞

在檢測大小寫後,經過詳細查閱原始碼後發現,沒有對空格進行限制。如果確實沒有空格限制,那麼檔案字尾的限制也將失效。

image

我們使用Burp Suite攔截請求進行傳送。我在檔名後面自行新增了一個空格,因為預設情況下並沒有檔名。

image

最終成功上傳檔案。關於繞過檔案字尾檢查的方法還有很多,我們不打算逐一列舉。問題主要在於解析程式碼時的不嚴謹,透過利用其中的某個漏洞直接上傳我們的指令碼檔案即可。

檔案包含漏洞

當這張圖片不再只是簡單的視覺元素時,它前面看起來可能十分尋常,然而實際上它的後半部分包含了一段程式碼。

image

這一關的原始碼看下

image

當我們只讀取前兩個位元組時,通常是為了獲取圖片檔案的檔案頭資訊,這些資訊包含了關於檔案型別和格式的重要資料。接下來,我們可以開啟這三個圖片檔案,使用記事本編輯,來探索它們是否有共同的特徵或屬性。

image

這一部分還有另一個需要注意的地方,那就是檔案包含漏洞。你知道檔案包含漏洞指的是什麼嗎?

<?php
/*
本頁面存在檔案包含漏洞,用於測試圖片馬是否能正常執行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
    include $file;
}else{
    show_source(__file__);
}
?>

由於直接使用 include 函式並且未對 $file 引數進行充分的過濾或驗證,攻擊者可以構造惡意請求,包含任意檔案,甚至是遠端的惡意檔案。那麼我們上傳檔案後,將檔案地址拿到,然後透過這個檔案包含漏洞試一下,結果顯示確實存在此風險。

image

二次渲染繞過

這一關原始碼很多,因此我決定僅複製並分享關鍵程式碼,供大家參考。

//使用上傳的圖片生成新的圖片
$im = imagecreatefromjpeg($target_path);

//使用上傳的圖片生成新的圖片
$im = imagecreatefrompng($target_path);

//使用上傳的圖片生成新的圖片
$im = imagecreatefromgif($target_path);

這一步驟的主要目的是確定使用者上傳的圖片格式,並重新生成新的圖片。在這個過程中需要特別關注 GIF 圖片的處理。GIF 圖片在重新渲染後改動很小,主要原因是其壓縮演算法的最佳化和格式的固定限制,使得大部分修改隻影響到少量的資料部分,而不會對整個影像檔案造成大幅度的變化。

我們需要對流程進行改進:首先,請確保不隨意修改圖片檔案,而是先上傳並下載圖片,再與本地圖片進行對比。識別未變化的部分,然後逐一複製貼上程式碼,如有錯誤則調整位置。

image

最後我們在這裡改下:

image

上傳後繼續使用檔案包含漏洞:

image

條件併發競爭

在這個階段,僅僅是將上傳的檔案儲存下來,然後進行校驗、重新命名並移動檔案。如果校驗失敗,則會將檔案刪除。表面看起來似乎沒有問題,但實際上存在許多潛在的漏洞。

image

首先,未進行檔案型別驗證便進行了儲存操作,隨後才進行驗證並刪除。這個漏洞為我們提供了攻擊伺服器的入口。我們可以利用Burp Suite攔截請求併發起集中攻擊。只要在刪除操作執行之前,我就能夠訪問到我上傳的檔案,便能執行指令碼。現在開始行動。

image

當我們成功攔截了請求後,接下來的步驟是配置併發請求的開發工作。我們計劃從預設的10個併發開始進行攻擊。

image

觀察這裡的攻擊效果,儘管它們通常會被及時清除,但只要我們成功訪問其中一個,攻擊就可以算是成功的。讓我們開始吧。

image

講解完了如何利用檔案上傳攻擊伺服器後,接下來的重點在於理解如何有效防禦這些攻擊。在伺服器端實施良好的防護措施至關重要,因為防守勝過進攻。接下來,我們將根據上述經典案例來探討如何加強伺服器的安全防護。

EdgeOne防護措施

假設我們無法對程式設計師編寫的程式碼進行檢查,或者我們本身沒有進行程式碼審計的能力,那麼我們只能依賴外部保護措施。在這種情況下,今天仍然建議採用EdgeOne來解決這些問題。為了讓大家更清楚地理解,我也簡單繪製了一張圖作為參考,看完圖後問題就變得非常簡單了,就像在架構中使用一個可插拔的中介軟體一樣輕鬆應用即可。

image

檔案漏洞防護手段

在前面我們詳細討論了多種攻擊方法,現在讓我們綜述一下應該從哪些方面進行防護:

  • 未限制檔案型別:允許上傳任何型別的檔案,包括可執行檔案。
  • 未進行檔案內容檢查:未檢查檔案內容是否包含惡意程式碼。
  • 未限制檔案上傳頻率:剛才我們演示的時候,可以看到透過頻繁上傳檔案達到條件競爭的狀態。

除了前面提到的措施外,還有一個需要注意的地方,即檔案大小的限制。考慮到我們擁有的是自己的伺服器資源,我們可以避免不必要的流量消耗。因此,我們也需要在這方面進行適當的控制。

接下來,我們將逐一實施這些防護措施,你將會看到,透過最小的調整,我們能夠達到最佳的安全效果。

檔案敏感字尾檢查

如果你打算上傳Webshell,檔案內容必定包含指令碼內容。因此,我們需要確認EdgeOne是否提供相關的檢查和校驗功能。一旦你購買了EdgeOne的標準版,無需進行任何修改,即可立即上傳檔案並檢查其是否能夠有效攔截。

image

在一般情況下,EdgeOne應該會攔截這類請求,但我們需要再次檢視樣本日誌,確認是否確實有請求未被攔截。

image

當我們注意到這一點時,我們發現請求不僅被捕獲,還被識別為防護規則,但實際上處於觀察狀態而非直接攔截狀態。這一點很重要,因為預設情況下,EdgeOne僅觀察並不會直接攔截請求。我們需要進一步檢視這個規則的ID,瞭解其具體功能。

image

首先進到自己配置的站點後,找到安全防護->web防護->託管規則->篩選規則id

這個問題相當繁瑣,因為在樣本日誌中,當前規則id的具體限制並不直接顯示出來,需要我們自己去查詢。不過,最終我們確實可以找到這些資訊。透過這種方式,我們可以識別檔案字尾,這樣一來,前端和後端在處理檔案字尾時就無需編寫大量的限制程式碼了。

事實上,前幾個案例中的檔案上傳漏洞主要都是由於檔案字尾問題導致的。EdgeOne技術能夠透過一種簡單的方法解決程式設計師程式碼不嚴謹的問題。

當涉及到相關的防護請求時,請記住關閉全域性觀察模式,這樣可以讓您單獨配置每個規則的攔截方式。因此,現在我們將全域性觀察模式關閉。

image

那麼讓我們再次發起請求,以確認是否能夠有效攔截這些請求。

image

難道我們表演翻車了嗎?怎麼還是觀察模式,我本以為我們應該處於攔截請求的狀態,而不是僅僅處於觀察模式。這涉及到一個防護等級的問題,我們需要檢視一下,預設設定可能偏向寬鬆了一些。

image

那麼我們需要調整防護等級,以確保它能夠攔截那些不應該直接訪問後臺的請求。然而,請注意,我們不能單獨設定一個規則,如果需要進行設定,也必須按照父類規則的方式進行設定。讓我們仔細檢視一下:

image

當然!那麼我們現在可以嘗試上傳一個檔案,以便檢視結果如何。

image

在實際應用中效果非常顯著。不再演示剩餘的各種奇葩敏感字尾,因為最終的攔截結果都是一致的。對於企業或個人而言,只需簡單操作兩次按鈕開關,使用體驗也非常出色。

偽檔案程式碼注入檢查

當我們試圖規避字尾檢查時,我們製作了一個檔案,其字尾名為.jpg,但實際上是一個偽裝的圖片檔案。讓我們首先驗證一下這個簡單的偽裝檔案是否有效。

image

當檔案內容實際上是PHP指令碼時,儘管我們的檔案字尾被設定為.jpg並不屬於敏感字尾檔案,因此可能可以規避EdgeOne的字尾規則檢查。因此,我們可以嘗試上傳並檢視是否能夠成功執行。

image

嘗試並未取得成功。那麼我們來看看他被那個安全防護規則攔截住了。

image

當我們成功繞過了敏感字尾的防護檢查,那麼現在需要進一步分析的是,這是哪一個具體的規則被規避了。

image

這防護措施真的蠻不錯,php指令碼已經被攔截了。

那麼,當我們測試更高階的偽裝檔案時,比如在一個看似正常的圖片檔案中嵌入程式碼指令碼,防護規則是否能夠檢測到它們呢?在我們探討繞過圖片二次渲染的方法時,我們進行了實驗,測試了在 GIF 檔案中注入 PHP 程式碼的情況,具體如下圖所示:

image

當然,我們可以看看是否有辦法繞過這個防護措施呢?不過看來防護措施還是能夠有效阻止的。

image

看看這些樣本日誌,因為它們都屬於同一個防護規則ID,我們就不再重複檢視了,而是繼續探索其他測試手段。

image

除了上述程式碼注入來防止圖片渲染外,如果沒有進行二次渲染,另一種方法是直接在圖片末尾新增內容。這種操作簡單,接下來我們看看它是否能提供額外的防護效果。

image

image

演示雖然出了點問題,但沒關係。如果防護不住,也不要緊,我們還可以聯絡騰訊客服,趕緊反饋情況。我會把所有的測試檔案和網站連結都交給他們,讓他們測試一下,找出問題所在。

image

經過長時間的深入溝通和分析,我們最終成功幫助他們發現了一個問題,剩下的就交給他們自行解決了。

image

這裡為什麼沒有演示條件競爭防護呢?難道不應該增加一個上傳頻率規則嗎?我不確定大家是否還記得,條件競爭攻擊是透過上傳一個PHP指令碼,然後在檢驗透過的短暫時間視窗內發動攻擊的。首先,PHP指令碼必須成功上傳,但EdgeOne已經攔截了這種指令碼,這樣怎麼能有效地實施後續的上傳速率限制呢?

檔案上傳速率限制

之前我們討論過避免演示條件競爭攻擊,但現在為什麼又有上傳速率限制呢?這個限制是為了防止頻繁的檔案上傳導致伺服器網路IO異常擁堵。這其實涉及到兩個問題:一方面,我們不是在談論透過指令碼攻擊伺服器,而是使用者可能透過頻繁上傳檔案來佔用伺服器資源。只要上傳足夠頻繁,就有可能使伺服器無法響應其他使用者的訪問,進而導致網站當機的情況發生。這種情況非常嚴重,影響可能相當惡劣。

話不多說,讓我們來進行演示並設定一些限制。由於上傳指令碼檔案會被攔截,因此我們將上傳一個正常的圖片來進行演示。同時,我們將使用Burp Suite來頻繁測試檔案上傳攻擊伺服器,具體如圖所示:

image

然後,我們直接發起併發請求。我們計劃按照以下幾個測試併發規則進行測試:每秒5、10、15、30和100次。首先,我們會使用10次每秒的併發量進行測試,然後再嘗試100次每秒的併發量。

image

我們多次傳送請求後,請檢視一下伺服器資源的情況。

image

這裡伺服器的流量封裝上漲,儘管網站仍可正常訪問,但我們的目的已經實現,大量消耗了網站的流量。

image

可以檢視EdgeOne的統計分析,這次不僅限於Web安全分析,而是重點在指標分析上。我們可以觀察到異常流量大量請求伺服器,面對這種情況,我們應該採取哪些措施?

image

可以再看下面的請求分析。如圖:

image

首先,透過分析該圖,我們可以確定請求的IP地址及其對哪些URL進行了頻繁請求,這些資訊將為我們制定有效策略提供基礎。

儘管這種方法並不是最優選擇,但我們可以將客戶的IP地址加入黑名單,以限制其訪問我們的網站。這種方法雖然笨拙,因為客戶IP可能會變動,導致我們需要不斷更新配置,但至少是一種可行的措施。

image

然後,我們接下來要做的是將IP地址新增到黑名單中,這樣可以簡單地增加安全防護措施。當然,你可以根據個人需求新增IP地址段。在這個示例中,我僅新增了一個IP地址作為演示。

image

好的,儲存完畢。接下來,我們試試傳送請求,看看是否已經被成功攔截。

image

當所有請求都被成功攔截後,我們可以再次檢視一下樣本日誌。

image

沒錯,這個規則ID就是剛剛由我們生成的唯一識別符號。

image

當考慮到這一情況時,第二種方法即為限制請求的頻率。

image

這裡的限制過於寬鬆,我們需要收緊一些。一個人不可能請求得這麼快。

image

當我們繼續傳送併發請求進行測試時,可以觀察到EdgeOne已經能夠識別到後續請求,並且使用了JavaScript挑戰指令碼,而非直接由伺服器響應。

image

當我們檢視樣本日誌時,同樣可以觀察到這一情況。

image

這是一個簡單的全侷限制。當然,某些企業使用者的網站可能要求允許客戶進行大量點選,這就需要考慮了。但不用著急,我們可以精確控制這個過程。接下來我們來討論如何設定針對特定URL的請求限制。我們根據指標分析異常請求的地方,來設定相應的控制策略。你可以根據個人需求自行設定限制。

image

我在這裡設定了所有涉及檔案上傳路徑的限制。我們需要再確認一下是否已經完全攔截了所有這些路徑。例如,/Pass-10/index.php

image

看起來確實成功阻止了潛在的攻擊。至於上傳速率的問題,我們就到這裡討論吧。

檔案大小限制

速度有限制,不能讓客戶上傳過大的檔案。我們只需上傳圖片,並非影片,所以設定個上限是合理的,比如不超過2M,這個範圍應該適應大多數需求。現在我們來具體操作一下。需要注意的是,這個操作不是在Web防護層進行,而是在站點加速層進行的設定。

image

為了更好地進行演示,我不會使用全域性配置,而是採用差異化配置的方式。這意味著我們會根據業務需求單獨配置特定路徑下的檔案上傳,具體如圖所示。

image

當我們試著上傳一個非常大的檔案,以便測試上傳過程。

image

結果是網站被攔截了,這讓我感覺好像我的網站無法訪問一樣。看起來我需要設定一下自定義響應頁面,以免讓訪問者誤以為網站不穩定。

image

我們需要在這裡進行響應頁面的設定,內容十分簡潔明瞭,完全遵循官方網站提供的示例進行展示。

image

上述頁面已建立,但尚未與413狀態碼繫結。接下來,我們將進一步完善剛才提到的規則。請參考下圖:

image

當我們再次審視其效果時,可以使其看起來更加穩定,這裡可以稍微美化一些,確保在滿足自己需求的同時,外觀也可以更為優美,具體如下圖所示。

image

截至目前,針對檔案上傳的所有潛在漏洞攻擊已經得到有效防範,但是道路漫漫,修行需持之以恆,少年仍需不懈努力。

總結

透過本文,我們深入探討了檔案上傳漏洞攻擊的多種案例和防範措施,以及在搭建攻擊靶場時的實際操作。從前端和後端的校驗漏洞,到利用Apache配置檔案和檔案包含漏洞的攻擊方式,每一步都展示了安全防護的重要性。

在學習和實踐過程中,我們不僅僅關注如何進行攻擊,更著重於如何保護自己的伺服器免受此類攻擊。我們使用了EdgeOne作為一個解決方案的示例,展示瞭如何利用其提供的防護規則來有效防禦檔案上傳漏洞。

無論是在靶場搭建過程中的細節操作,還是在攻擊案例的分析過程中,安全意識和防護措施的實施都顯得至關重要。透過本文,希望讀者能夠更深入地理解和應用這些安全原則,以保護自己的網路和伺服器免受攻擊的威脅。

在網路安全的道路上,學習永無止境。讓我們共同努力,不斷提升技能,保障網路環境的安全與穩定。


我是努力的小雨,一名 Java 服務端碼農,潛心研究著 AI 技術的奧秘。我熱愛技術交流與分享,對開源社群充滿熱情。身兼掘金優秀作者、騰訊雲內容共創官、阿里雲專家博主、華為云云享專家等多重身份。

💡 我將不吝分享我在技術道路上的個人探索與經驗,希望能為你的學習與成長帶來一些啟發與幫助。

🌟 歡迎關注努力的小雨!🌟

相關文章