天天看點

上傳漏洞科普[1]-檔案上傳表單是Web安全主要威脅

上傳漏洞科普[1]-檔案上傳表單是Web安全主要威脅

為了讓最終使用者将檔案上傳到您的網站,就像是給危及您的伺服器的惡意使用者打開了另一扇門。即便如此,在今天的現代網際網路的Web應用程式,它是一種 常見的要求,因為它有助于提高您的業務效率。在Facebook和Twitter等社交網絡的Web應用程式,允許檔案上傳。也讓他們在部落格,論壇,電子 銀行網站,YouTube和企業支援門戶,給機會給最終使用者與企業員工有效地共享檔案。允許使用者上傳圖檔,視訊,頭像和許多其他類型的檔案。

向最終使用者提供的功能越多,Web應用受到攻擊的風險和機會就越大,這種功能會被惡意使用者利用,獲得到一個特定網站的權限,或危及伺服器的可能性是非常高的。

當 在測試幾個Web應用程式時,我們注意到,相當多的知名Web應用程式,不具備安全的檔案上傳形式。這些漏洞很容易被利用,我們可以通路這些Web應用程 序的伺服器托管到檔案系統。在這篇文章中,我們為您介紹8種常見的方式,我們遇到過的安全檔案上傳表單。同時,還将展示一個惡意的使用者,可以輕松地繞過這 些安全措施。

案例1:沒有任何驗證的簡單檔案上傳表單

一個簡單的檔案上傳表單通常包含一個HTML表單和PHP腳本。HTML表單的形式呈現給使用者,而需要檔案上傳功能的PHP腳本中包含的代碼。這種形式和PHP腳本下面是一個例子:

HTML Form:

<form enctype="multipart/form-data" action="uploader.php" method="POST"> 
<input type="hidden" name="MAX_FILE_SIZE" value="100000" /> 
Choose a file to upload: <input name="uploadedfile" type="file" /><br /> 
<input type="submit" value="Upload File" /> 
</form>
           

PHP Code:

<?php
    $target_path  =  "uploads/";
    $target_path  =  $target_path  .  basename($_FILES['uploadedfile']['name']);
    if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
    echo "The file " . basename($_FILES['uploadedfile']['name']) . " has been uploaded";
    echo "There was an error uploading the file, please try again!";
    } else {
    }
?>
           

當PHP接收POST請求且編碼類型是multipart/form-data,它會建立一個臨時檔案名随機的臨時目錄中(例如/ var/tmp/php6yXOVs)。 PHP也将填充全局數組$_FILES上傳的檔案的資訊:

$ _FILES ['UploadedFile的'] ['名稱']:在客戶機上的檔案的原始名稱
$ _FILES ['UploadedFile的'] ['類型']:檔案的MIME類型
$ _FILES ['UploadedFile的'] ['大小']:檔案的大小(以位元組為機關)
$_FILES ['UploadedFile的']['不對tmp_name']:上傳的檔案存儲在伺服器上的臨時檔案名。
           

PHP 函數move_uploaded_file将使用者提供的臨時檔案移動到一個位置。在這種情況下,目的地是伺服器根目錄以下。是以,檔案可以使 用的URL,如:http://www.domain.tld/uploads/uploadedfile.ext通路。在這個簡單的例子中,有允許上傳 的檔案類型沒有限制,是以攻擊者可以上傳一個PHP或NET帶有惡意代碼的檔案,可導緻伺服器妥協。

這可能看起來像很幼稚的例子,但我們在一些Web應用中沒有遇到這樣的代碼。

案例2:Mime類型驗證

另 一個常見的錯誤Web開發人員確定檔案上傳表單時,隻檢查從PHP傳回mime類型。當一個檔案被上傳到伺服器,PHP将設定變 量$_FILES[‘UploadedFile’][‘type’]所提供的Web浏覽器用戶端使用的MIME類型。然而,檔案上傳表單驗證不能依賴于這 個值。惡意使用者可以輕松地使用腳本或其他一些自動化的應用程式,允許發送HTTP POST請求,這讓他送一個假的mime類型的檔案上傳。

案例3:限制危險的拓展

在另一個例子裡,我們遇到了檔案上傳使用黑名單的做法,作為一項安全措施。從開發者收集制定的危險清單,如果正在上傳的檔案包含在清單中,通路會被拒絕。

使用危險的檔案擴充名,其主要缺點之一是,它幾乎不可能編制一份完整的清單,包括攻擊者可以使用的所有可能的擴充名。例如如果代碼運作在托管環境中,通常這樣的環境讓大量的腳本語言,如Perl,Python和Ruby等,清單可以是無窮無盡的。

惡意使用者可以很容易地繞過該檢查上傳一個檔案名為“.htaccess”,其中包含類似于下面的一行代碼:

AddType application/x-httpd-php .jpg

上 面的代碼行,訓示ApacheWeb伺服器執行jpg圖檔,好像他們是PHP腳本。攻擊者現在可以上傳一個jpg擴充名的檔案,其中包含PHP代碼。正如 下面的截圖,通過web浏覽器請求一個jpg檔案,其中包含PHP的指令phpinfo()函數,它仍然是從Web伺服器執行:

上傳漏洞科普[1]-檔案上傳表單是Web安全主要威脅

案例4: 雙擴充名 (第1部分)

本案例中使用的安全政策和案例3中所使用的非常相近. 盡管方式換成了簡單的檢查檔案名具有的擴充名, 開發者通過在檔案名中查找 ‘.’ 字元并提取點号之後的字元串來得到檔案擴充名.

繞過該途徑的方法有點兒複雜, 但是仍然是現實的. 首先, 讓我們看看 Apache 是怎麼處理具有多重擴充名的檔案的. Apache 手冊中有如下一段陳述:

“文 件可以有多個擴充名, 這些擴充名的順序一般情況下是無關緊要的.例如: 如果檔案 welcome.html.fr 被映射為内容類型是 text/html ,語言是法語的話, 檔案welcome.fr.html 将被映射為完全相同的内容. 如果一個以上的擴充名映射到同種類型的元資訊上, 那麼将使用最右邊的那個, 除了語言和内容編碼. 比如: .gif 的MIME類型是 image/gif , .html 的 MIME 類型是 text/html , 那麼 welcome.gif.html 的MIME類型将是text/html .”

是以一個名為 ‘filename.php.123’ 的檔案将會被解釋為一個PHP檔案并被執行.這僅限于最後的那個擴充名(本例中是 .123)沒有在web伺服器的 mime-types清單中被指定.web開發者通常不會意識到Apache還存在這麼一個 ‘特性’, 出于某些原因來說這可能非常危險.知道了這個以後,一個攻擊者可以上傳一個名為 shell.php.123 的檔案并繞過檔案上傳保護機制.背景腳本将會計算出最後的擴充名(.123)并作出該擴充名并不在危險的擴充名清單内的結論.話雖如此,想要預防某惡意用 戶可能會使用的所有随機擴充名來上傳一個檔案到你的web伺服器上是不可能的.

案例5: 雙擴充名 (第2部分)

一個更好的增強檔案上傳表單的安全性的途徑就是白名單機制. 在本例中, 開發者定義了一個 已知/可接受 的擴充名清單并且不允許使用未在名單中指定的擴充名.

然 而, 在某些情況下該途徑不會像期待的方式那樣工作. 當 Apache 被配置為執行 PHP 代碼的時候, 存在兩種方式來實作該機制: 使用 AddHandler 指令, 或者使用 AddType 指令. 如果 AddHandler 指令被使用, 所有包含 ‘.php’ 擴充名的檔案名(例如: ‘.php’ , ‘.php.jpg’)均被作為 PHP 腳本來執行. 是以, 如果你的 Apache 配置檔案包含如下一行的話, 你可能很容易受到攻擊:

AddHandler php5-script .php

一個攻擊者可以上傳名為 ‘filename.php.jpg’ 的檔案并繞過保護機制, 然後執行其中的代碼.

案例 6: 檢查圖檔頭部

當 僅允許上傳圖檔的時候, 開發者通常使用 PHP 的 getimagesize 函數來檢測圖檔的頭部資訊. 該函數在被調用時将會傳回圖檔的尺寸, 如果圖檔經驗證為無效的, 也就是說圖檔頭部資訊不正确, 則會傳回 false 值. 是以一個開發者一般會檢查該函數是否傳回 true 或 false, 并且通過該資訊來驗證上傳的檔案. 是以, 如果一個惡意使用者試着上傳一個内嵌有簡單 PHP shell 的 jpg 檔案的話, 該函數會傳回 false 然後他将不允許上傳此檔案. 然而, 即使這種方式也能被很容易的繞過. 如果一個圖檔在一個圖檔編輯器内打開, 就如 Gimp, 使用者就可以編輯圖檔的注釋區, 那兒就能插入 PHP 代碼, 就如下圖所示.

上傳漏洞科普[1]-檔案上傳表單是Web安全主要威脅

該圖檔仍然有一個有效的頭部; 是以就繞過了 getimagesize 函數的檢查. 從下面截圖中可以看到, 當一個普通的 web 浏覽器請求該圖的時候, 插入到圖檔注釋區的 PHP 代碼仍然被執行了:

上傳漏洞科普[1]-檔案上傳表單是Web安全主要威脅

案例七:通過.htaccess保護上傳檔案夾

另一種流行的穿件安全的檔案上傳表單的方法是适用.htaccess保護好上傳檔案存放的檔案夾。辦法是限制這個檔案夾裡的腳本檔案的執行。這種情形一下,一個.htaccess檔案一般包含下面的代碼:

AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi

Options –ExecCGI

上面的是另一種形式的黑名單,本身并不是很安全。在PHP手冊中,move_uploaded_file一章中,有一個warning:若目标檔案已經存在,則會覆寫原檔案。

因為上傳的檔案能夠而且會覆寫已經存在的同名檔案,一個惡意使用者很輕易就能用他自己修改過的.htaccess替換掉原來的。這使得他可以執行特定的将會幫助他危害伺服器的腳本。

案例八:用戶端驗證

另一種在檔案上傳表單中常用的安全技術是在用戶端驗證上傳的檔案。一般而言,該技術在ASP.NET應用中更通用一些,因為ASP.NET提供了易用的驗證控件。

這些驗證控件允許開發者對要上傳的檔案做正則檢查,以查出待上傳的檔案擴充名是否在允許清單中。下面是一段來自微軟網站的示例代碼:

<asp:FileUpload ID="FileUpload1" runat="server" />

  <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Upload File" /> 

  <asp:Label ID="Label1" runat="server"></asp:Label>

  <asp:RegularExpressionValidator id="RegularExpressionValidator1" runat="server"

  ErrorMessage="Only mp3, m3u or mpeg files are allowed!"

  ValidationExpression="^(([a-zA-Z]:)|({2}w+)$?)((w[w].*))

  +(.mp3|.MP3|.mpeg|.MPEG|.m3u|.M3U)$" ControlToValidate="FileUpload1"></asp:RegularExpressionValidator>

  <asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server"

  ErrorMessage="This is a required field!"

  ControlToValidate="FileUpload1"></asp:RequiredFieldValidator>

   
           

這段ASP.NET代碼使用了驗證控件,是以最終使用者隻被允許上傳.mp3,.mpeg,或者.m3u檔案到伺服器。若檔案類型和這三個指定的檔案類型不一緻,驗證控件将跑出異常,檔案也就不會被上傳。

由于這種檔案驗證是在用戶端完成的,惡意使用者很容易就能繞過這一檢查。寫一段用戶端腳本來替換web應用的驗證腳本做驗證并非不可能。不用web浏覽器,入侵者可以使用可以發送HTTP POST請求的程式來實作上傳檔案。

推薦的解決方案

在允許上傳檔案的網站和web應用中,應當應用下面的一系列最佳實踐方法。這些實踐方法将有助于你保證web應用的上傳檔案的安全性。

定義一個.htaccess檔案,隻允許通路指定擴充名的檔案。

不要把.htaccess檔案和上傳檔案放在同一個目錄裡,應該放在父目錄裡。

一個典型的隻允許 gif, jpg, jpeg 和 png檔案的.htaccess檔案應當包含下面的代碼(根據你的需求做調整)。這樣也能阻止雙擴充名攻擊.

deny from all
<Files ~ "^w+.(gif|jpe?g|png)$">
order deny,allow
allow from all
</Files>
           

如果可能,把檔案上傳到root目錄以外的目錄裡。

禁止覆寫已存在的檔案(以阻止.htaccess覆寫攻擊)

建立一個mime-type白名單清單。(隻允許這個清單裡的Mime-type)

生成一個随機的檔案名,并且加上此前生成的檔案擴充名、

不要隻依賴用戶端驗證,這不夠。理想的是既有用戶端驗證也有伺服器端驗證。

總結

如上所述,惡意使用者有很多手段繞過檔案上傳表單安全驗證。是以,在web應用中實作檔案上傳表單時,應當尊徐正确的安全指導,并且做恰當的測試。不幸的是要做足夠的測試将會需要很多時間和更多的安全專家。

還好有了Acunetix WVS,不需要安全專家就可以自動完成上傳表單脆弱性檢查,Acunetix WVS用最少的時間為開發者提供了足夠多的能夠追蹤并修複問題的資訊。

繼續閱讀