文件上傳漏洞是Web安全中一種常見的漏洞在滲透測試中經常使用到,能夠直接快速地獲得服務器的權限,如果說一個沒有文件上傳防護規則的網站,只要傳一個一句話木馬就可以輕松拿到目標了。上傳文件上傳漏洞是指用戶上傳了如木馬、病毒、webshell等可執行文件到服務器,通過此文件使服務器執行命令從而控制網站。
0x01文件上傳檢驗
- 黑名單檢測
- 白名單檢測
- 文件頭檢測
- 正則檢測
- WAF檢測
- 前端JavaScript檢測
在客戶端進行檢測的時候一般是通過JavaScript的腳本對上床的文件名后綴進行檢測。有白名單也有黑名單,比如只允許上傳.jpg .png .gif .jpeg等后綴文件名。但前端檢測可以通過對代碼進行·修改輕松繞過。前端的代碼在瀏覽器執行,可以通過bp攔截進行修改。
文件上傳一般會進行檢測然后上傳到緩存文件(tmp)再通過后端代碼的移動移動到指定目錄重命名。
0x02文件上傳
2.1前端檢驗
通過抓取返回包並修改白名單規則加上.php或者直接刪去所有校驗代碼
上傳成功查看圖片路徑
蟻劍連接
2.2content-type
在服務端的檢測比如通過文件頭content-type進行檢測。
PHP校驗代碼,可以看到只允許上傳jpeg png 和gif的后綴文件
1 $is_upload = false; 2 $msg = null; 3 if (isset($_POST['submit'])) { 4 if (file_exists($UPLOAD_ADDR)) { 5 if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) { 6 if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) { 7 $img_path = $UPLOAD_ADDR . $_FILES['upload_file']['name']; 8 $is_upload = true; 9 10 } 11 } else { 12 $msg = '文件類型不正確,請重新上傳!'; 13 } 14 } else { 15 $msg = $UPLOAD_ADDR.'文件夾不存在,請手工創建!'; 16 } 17 }
補充一下content-type的知識:
HTTP協議(RFC2616)采用了請求/響應模型。客戶端向服務器發送一個請求,請求頭包含請求的方法、URI、協議版本、以及包含請求修飾符、客戶 信息和內容的類似於MIME的消息結構。服務器以一個狀態行作為響應,相應的內容包括消息協議的版本,成功或者錯誤編碼加上包含服務器信息、實體元信息以 及可能的實體內容。
通常HTTP消息由一個起始行,一個或者多個頭域,一個只是頭域結束的空行和可選的消息體組成。HTTP的頭域包括通用頭,請求頭,響應頭和實體頭四個部分。每個頭域由一個域名,冒號(:)和域值三部分組成。域名是大小寫無關的,域 值前可以添加任何數量的空格符,頭域可以被擴展為多行,在每行開始處,使用至少一個空格或制表符。
請求消息和響應消息都可以包含實體信息,實體信息一般由實體頭域和實體組成。實體頭域包含關於實體的原信息,實體頭包括Allow、Content- Base、Content-Encoding、Content-Language、 Content-Length、Content-Location、Content-MD5、Content-Range、Content-Type、 Etag、Expires、Last-Modified、extension-header。
Content-Type是返回消息中非常重要的內容,表示后面的文檔屬於什么MIME類型。Content-Type: [type]/[subtype]; parameter。例如最常見的就是text/html,它的意思是說返回的內容是文本類型,這個文本又是HTML格式的。原則上瀏覽器會根據Content-Type來決定如何顯示返回的消息體內容。
type有下面的形式
Text:用於標准化地表示的文本信息,文本消息可以是多種字符集和或者多種格式的;
Multipart:用於連接消息體的多個部分構成一個消息,這些部分可以是不同類型的數據;
Application:用於傳輸應用程序數據或者二進制數據;
Message:用於包裝一個E-mail消息;
Image:用於傳輸靜態圖片數據;
Audio:用於傳輸音頻或者音聲數據;
Video:用於傳輸動態影像數據,可以是與音頻編輯在一起的視頻數據格式。
修改content-type為 image/jpeg
上傳成功
2.3文件后綴
可以看到第5行定義了后綴為 asp aspx php jsp的文件不能上傳,黑名單對特定的后綴文件其效果,可以通過上傳xxx.a等不可能后綴的文件判斷是否為黑名單檢測。
1 $is_upload = false; 2 $msg = null; 3 if (isset($_POST['submit'])) { 4 if (file_exists($UPLOAD_ADDR)) { 5 $deny_ext = array('.asp','.aspx','.php','.jsp'); 6 $file_name = trim($_FILES['upload_file']['name']); 7 $file_name = deldot($file_name);//刪除文件名末尾的點 8 $file_ext = strrchr($file_name, '.'); 9 $file_ext = strtolower($file_ext); //轉換為小寫 10 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA 11 $file_ext = trim($file_ext); //收尾去空 12 13 if(!in_array($file_ext, $deny_ext)) { 14 if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR. '/' . $_FILES['upload_file']['name'])) { 15 $img_path = $UPLOAD_ADDR .'/'. $_FILES['upload_file']['name']; 16 $is_upload = true; 17 } 18 } else { 19 $msg = '不允許上傳.asp,.aspx,.php,.jsp后綴文件!'; 20 } 21 } else { 22 $msg = $UPLOAD_ADDR . '文件夾不存在,請手工創建!'; 23 } 24 }
那么 asp aspx php jsp的文件不能上傳還有沒有其它的后綴能被當成腳本進行解析呢。在默認狀態下一些后綴名也是能被解析的
jsp | jspx | jspf | |
asp | asa | cer | aspx |
php | phtml | php4 | php5 |
exe | exee |
文件后綴大小寫:也可以利用后綴大小寫進行嘗試繞過 PhP PHp等 但有些防護機制會將文件名同義轉換為小寫
$file_ext = strtolower($file_ext); //轉換為小寫
文件后綴為空:windows上在保存文件名的時候如果有空格 比如php空格和php是相同的,但是對於檢測來說php和php空格是不同的,那么他可能只會攔截php而不會攔截php空格的后綴文件。
加點進行繞過 php.空格.
雙寫 pphphp
2.4 .htaccess文件繞過
1 AddType application/x-httpd-php .php 2 AddType application/x-httpd-php .html 3 可以加入更多可以執行php的文件類型, 4 AddType application/x-httpd-php .htm 5 .htm文件也可以執行php程序, 6 AddType application/x-httpd-php .txt 普通的文本文件格式也能運行php程序。
創建htaccess寫入命令,在某些win10和win7上不能創建文件名為空的htaccess文件可以使用命令轉換
2.5 文件偷繞過
在一句話的基礎上添加文件頭,例如2.6 windows數據流繞過 :: $DATA
通俗點說就是其他文件可以寄宿在某個文件上,而在資源管理器中只能看到宿主文件找不到激素文件。
在cmd可以通過命令寫入
echo 9999>>a.txt:b.txt 數據寫入b.txt生成了一個a.txt
echo 9999>>c.php::$DATA 利用windows文件的特性Linux不行
2.7 %00和00截斷
在文件上傳的的時候如果白名單只允許上竄jpg等后綴的文件,在沒有解析漏洞的情況下jpg格式不會被解析,那么需要繞過上傳過濾。0x00實際上是一個十六進制的表示方式,表示acsii碼值為0,有些函數在處理的時候會把它當作結束符,讀取到這里的時候就結束了,%00是經過url編碼的。
php<5.3的一個漏洞
可以看到這里的移動路徑
那么進行修改
修改成功
將文件名為you.phpa的文件上傳抓包
在十六進制找到文件名這行,因為a的acsii為61 那么在這里修改為00
可以看到文件后綴名已經改變
有些會對文件后綴和內容進行檢測,那么可以上傳圖片馬,如果對圖片末尾進行檢測那么可以用圖片+木馬+圖片繞過。如果對於圖片進行了二次渲染進行繞過,那么可以用動態圖gif嘗試,通常在第四行胡總和第三行開始寫會比較好。
文件上傳的繞過方法有很多種,通過不斷測試選擇方法。