一文簡單入門文件上傳

文件上傳

隨着Web應用發展和廣泛應用,很多的應用都允許用戶上傳自己的文件,以此提升用戶體驗。但是,這也就造成了一個web應用安全中很著名的漏洞,它就是文件上傳漏洞。由於Web應用的上傳功能的代碼實現沒有對用戶上傳文件的格式和後綴以及文件類型進行過濾,從而導致大家都可以任意上傳文件到服務器中,那麼攻擊者就會通過web訪問的目錄上傳任意的PHP文件,並且能夠將這些文件在PHP解釋器上運行,從而可以遠程控制服務器。這種方式很直接,沒有說明門檻,就是上傳控制。一般都會上傳木馬,然後利用木馬來讀/寫服務器上的文件。不過好在,現在很多的程序員都已經意識到這個問題了,上傳漏洞現在也比較少了,畢竟大家都開始做過濾了。但是作爲安全學習者,必須知道這個漏洞,並且瞭解其原理。

1、上傳漏洞原理

文件上傳漏洞一般是指上傳Web腳本能夠被服務器解析的問題。大多數情況下,攻擊者想要完成整個文件上傳漏洞攻擊時需要滿足一定條件的。

首先,上傳的文件能夠被Web容器解析執行,所以文件上傳後的目錄要是Web容器所覆蓋的路徑。其次,Web 服務器要能訪問到該文件,如果上傳成功了,但是攻擊者不能通過Web途徑進行訪問,那麼就廢了,攻擊是無法形成的。最後,如果上傳的文件被Web安全檢測格式化、圖片壓縮等改變其內容, 導致無法解析的話,攻擊也是無法形成的。
接下來我會通過DVWA上的上傳漏洞實例,學習整個漏洞攻擊的過程。
首先將DVWA的安全程度調至low,,不然開啓默認爲impossible,安全級別太高。

然後在自己本地編寫一句話PHP文件,代碼如下。

<?php
	phpinfo();
?>

然後把這個文件在DVWA中進行上傳

在這裏插入圖片描述

上傳後可以看到上傳路徑,那麼就可以根據這個路徑目錄去訪問上傳的文件,我的路徑是:http://127.0.0.1/DVWA/hackable/uploads/1.php

訪問之後就可以看到:

在這裏插入圖片描述

這個頁面就是文件中編寫的那句phpinfo()在Web服務器裏執行的效果。

如果上傳的腳本是一個Webshell的話,就可以直接獲取服務器的控制權限。

之前說到上傳後的文件會被Web容器解析,其實在文件解析過程中也會產生一些問題。下面就來說一說由哪些問題。

2、IIS文件解析問題

IIS是互聯網信息服務,使用IIS 5.x-6.x版本服務器,大多爲Windows Service 2003,網站比較古老,開發語句一般爲asp;該解析漏洞也只能解析asp文件,而不能解析aspx文件。

(1)目錄解析(IIS6.0)

形式:www.xxx.com/xx.asp/xx.jpg

原理:服務器默認會把.asp和.asp目錄下的文件都解析成asp文件。

(2)文件解析

形式:www.xxx.com/xx.asp;.jpg

原理:服務器默認不解析後面的內容,因此,xx.asp;.jpg便會被解析爲asp文件。

(3)解析文件類型

IIS6.0默認的可執行文件除了asp還包含一下3種:/test.asa、/test.cer、/test.cdx

這樣的話可能做了一些過濾,但是攻擊者把修改後綴名,繞過一些限制後,依舊可以上傳成功,這個假的jpg或其他文件還是成功地被執行了其中的asp代碼。

3、Apache文件解析問題

Apache解析文件的規則就是從由到左進行判斷解析,如果後綴名爲不可識別文件解析,就再往左判斷。例如test.php.qwe.rar,.qwe.rar這兩種後綴是Apache不可識別解析的,Apache就會把wooyun.php.qwe.rar解析爲PHP文件。

例如有一個網站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-http-php.jpg,即使拓展名是.jpg,一樣能以PHP方式執行。

4、PHP的CGI路徑解析問題

Nginx默認以CGI方式支持PHP解析,普通的做法是在Nginx配置文件中通過正則匹配設置SCRIPT_FILENAME。當訪問www.xx.com/phpinfo.jpg/1.php時,$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來進行解析。

在舉幾個例子:

www.xxx.com/uploadfile/image/1.jpg/1.php
www.xxx.com/uploadfile/image/1.jpg%00.php
www.xxx.com/uploadfiel/image/1.jpg/%20\0.php

這些例子和上面說的那個原理是一樣的,都是x.php作爲PAT_INFO,所以以PHP來解析。

另一種是上傳一個名字爲test.jpg的文件,文件裏是寫好的php代碼,只要上傳成功後訪問test.jpg/.php ,就可以在當前目錄下生成一個一句話shell木馬shell.php。代碼如下:

<?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd]) ?>'); ?>

5、上傳繞過漏洞

在上傳漏洞出現後,程序員們當然都意識到這個問題,企業也會開始避免這樣的風險,所以大多數網站現在對於上傳的文件都有進行一定限制,例如說常見的後綴限制,它們會規定哪些後綴名文件時允許上傳的,哪些時不允許的。比如有一個網站它只允許上傳後綴爲.jpg的圖片文件,那麼一個攻擊者需要使用上面手段去繞過後綴的限制和檢測,上傳一個木馬。這是一個值得思考的問題。

在很多CTF題裏都有上傳繞過的題目,更是讓我對這個%00的截斷方式印象深刻啊。%00似乎是最常用的方法,其實就是攻擊者通過手動地去改上傳過程中的POST數據報,在文件名的後面給添加一個%00,來達到截斷的作用。因爲函數在判斷一個文件名稱和後綴的時候遇到NULL就是代表結束了,而%00對應的正是NULL。(這裏的函數指的是C、PHP等語言字符串處理時用到的)

既然Web應用只允許我們上傳.jpg的文件,那麼我就如其所願,給他一個.jpg我們可以構造一個x.php[\0].jpg,其中,[\0]就是十六進制的0x00字符。這樣就可以成功繞過客戶端對於文件後綴的驗證,但是在server端,在解析時會被0x00截斷,就會解析爲x.php,所以就是成功解析爲我們想要達到的PHP文件了。這個就是前端繞過client端,後端截斷,解析爲PHP。

6、客戶端繞過(前端繞過)

上面對上傳繞過簡單講了一下,下面就詳細說一下客戶端繞過,我一般也叫它前端繞過。一些比較的CTF題目就會出現前端繞過就OK的情況。

既然要前端繞過,那就必須要稍微知道,前端時如何來判斷過濾的。一般client端都是使用JavaScript來進行一個文件名的校驗工作。對於這種方法,其實很簡單,我們可以client端輸入符合條件的後綴並上傳文件,關鍵在於要使用一個抓包工具,抓包改包重放。抓包就是要抓client驗證無誤後發給server端的POST分組,改包就是要修改POST請求中的部分內容,重放就是抓了改了當然要放行了。

介紹一下我用的工具,我一般都是使用Burpsuit來進行抓包的,這是一個很不錯的工具,推薦使用。對了專業版會比社區版用起來舒服很多,因爲專業版可以修改線程。

不多說DVWA裏演示一下:

工具:Firefox、burpsuit

環境:Windows(本機)、DVWA(靶場)

把安全級別設爲low,上傳一個後綴被改爲了.jpg的文件1.jpg,抓包後結果如下所示:

在這裏插入圖片描述

可以看到filename處顯示的時1.jpg我這個時候看到的是我上傳的情況,我只要把1.jpg改爲1.php就可以了。

在這裏插入圖片描述

然後再提交。結果會如下:

在這裏插入圖片描述

上傳成功,這樣就繞過了client端,也就是繞過前端了。我實際上傳的時1.php

7、服務端繞過(後端繞過)

server端繞過和client端繞過一樣,我們還是想了解一下,server端時如何來進行判斷的。一般來說server端會通過3種東西來進行判斷:content-type字段、文件頭、拓展名。那麼如果是單種方式,要想繞過驗證還是很容易的。但是組合之後就要想辦法去繞過每一個校驗,當然這也是可以實現的。

我們一個一個來:

1.content-type

這個字段我記得在之前的博客裏面有提到過,它其實就是表示上傳文件的類型,其實就是MIME格式表示標識文件。我之前有寫過一篇常見的MIME可以供大家查看,這裏舉幾個常見的:imag/jpeg、application/x-php等。

對於這個還是簡單事情我們是可以和client端一樣,使用burpsuit抓包改一下就好了。
在這裏插入圖片描述

把原本的類型用圖片的MIME來替換,這裏換成了image/jpeg,提交就可以繞過驗證了。

2.文件頭

這種校驗方法其實只需要在木馬的前加上文件類型所對應的文件頭就可以欺騙繞過了,比如把<?php phpinfo(); ?>變成GIF89A<? php phpinfo(); ?>服務器端就會認爲你上傳的是gif文件,也就繞過了。

3.拓展名

驗證拓展名其實也是在驗證MIME,MIME就是多用途互聯網郵件拓展類型,相信學習過計算機網絡的朋友應該都是知道的。它的作用很大的,比如我訪問一個文件,瀏覽器就會爲我尋找合適的應用去運行它,就是因爲MIME。

MIME的作用就是區分不同種類的數據,文件到達服務器後,服務器本地進行MIME的分類 ,這種方式比較驗證比較安全,要想繞過唯一方法就是去查找漏網之魚了,要找有沒有被黑名單漏掉的拓展名。這個比前兩種都要安全。

關於修復的思考和總結

上傳問題也算得上是老問題了。很多開發者也已經有了很多辦法來修復這個洞。我自己有一些想法,上傳漏洞傳上木馬後想要遠程控制,是需要知道路徑和文件可執行的。那麼我們可以從此下手,斷了他的路。一個是不要回顯路徑,這個目前基本都做到了,其次是之前在系統安全的博客裏有提到我們要善於利用系統的權限控制,我們完全可以把用來存儲上傳文件的目錄設置爲不可執行。從而讓攻擊者無法連上他的木馬。當然這是在木馬已經上服務器的情況下的一個好辦法,重點還是要避免木馬輕易就被上傳到服務器中。可以前端+後端多重驗證,後端的話拓展名驗證是個很好的選擇,之前說拓展名的時候有說到黑名單攔截,其實我們不一定使用黑名單,更可以使用白名單,因爲我們允許上傳的文件類型可能遠比不允許上傳的文件類型要少,白名單就是一個很好的選擇了。對了還有就是圖片馬,最好要使用圖片壓縮函數或resize函數,對圖片文件進行處理,同時破壞圖片中含有的惡意代碼。

發佈了22 篇原創文章 · 獲贊 27 · 訪問量 5592
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章