Apache解析漏洞詳解

不少次聽到人說apache的「解析漏洞」了,正好今天又有人問,那就簡單科普一下這個「解析漏洞」是何物。php

先來看測試過程和結果的對比吧。html

結果一web

首先,我安裝了apache 2.x版本,同時以module方式使apache與php結合,測試發現確實存在這樣的解析漏洞。shell

1.png

結果二apache

而後,我將apache與php的結合方式修改成fastcgi方式,測試發現爆500錯誤,不存在這樣的解析漏洞。瀏覽器

2.png

錯誤提示:服務器

1Bad file descriptor: mod_fcgid: don't know how to spawn child process: f4ck.php.xapp

意思就是不知道該如何解析這個文件。測試

結果出來了,那麼對於影響範圍這塊,在目前全部的apache版本中均存在此問題,但只適用於以module方式解析php的apache,使用fastcgi方式解析php的apache不受影響,使用cgi方式解析php的apache是否影響未測試。網站

下面來簡單分享一下測試過程當中我發現的一點經驗。

先來看一下apache的主配置文件httpd.conf,搜索「DefaultType」,就能夠看到這麼一段註釋和默認配置:

#
# DefaultType: the default MIME type the server will use for a document
# if it cannot otherwise determine one, such as from filename extensions.
# If your server contains mostly text or HTML documents, "text/plain" is
# a good value. If most of your content is binary, such as applications
# or images, you may want to use "application/octet-stream" instead to
# keep browsers from trying to display binary files as though they are
# text.
#10DefaultType text/plain

DefaultType存在的意義是告訴apache該如何處理未知擴展名的文件,好比f4ck.xxx這樣的文件,擴展名是xxx,這確定不是一個正常的網頁或腳本文件,這個參數就是告訴apache該怎麼處理這種未知擴展名的文件。

參數DefaultType的默認值是「text/plain」,也就是遇到未知擴展名的文件,就把它看成普通的txt文本或html文件來處理。

測試一

好比我將如下代碼保存爲f4ck.xxx:

1F4ckTeam apache test

訪問它,按照默認的apache配置,這個文件是會被瀏覽器顯示出來具體效果的:

3.png

這是對於文件內容爲HTML代碼的未知擴展名文件來講,文件中的HTML代碼會被瀏覽器執行。

測試二

那麼,對於文件內容爲php代碼的未知擴展名文件來講,這些php代碼會被解析嗎?

來看測試結果:

4.png

能夠看到,這裏包含php代碼的未知擴展名的文件被看成txt文檔處理了。

可是,若是將文件名改成f4ck.php.xxx,那麼就會被以module方式運行php的apache解析,爲何?

由於Apache認爲一個文件能夠擁有多個擴展名,哪怕沒有文件名,也能夠擁有多個擴展名。Apache認爲應該從右到左開始判斷解析方法的。若是最右側的擴展名爲不可識別的,就繼續往左判斷,直到判斷到文件名爲止。

官方解釋見:http://httpd.apache.org/docs/current/mod/directive-dict.html,搜索「extension」便可看到。

摘錄官方解釋:

extension

In general, this is the part of the filename which follows the last dot. However, Apache recognizes multiple filename extensions, so if a filename contains more than one dot, each dot-separated part of the filename following the first dot is an extension. For example, the filename file.html.en contains two extensions: .html and .en. For Apache directives, you may specify extensions with or without the leading dot. In addition, extensions are not case sensitive.

那麼,對於「測試一」和「測試二」來講,apache發現這個文件的擴展名是未知的,那麼它會先看在擴展名以前是否有其餘的可識別的擴展名,可是該 案例中的完整文件名爲「f4ck.xxxx」,在擴展名「xxxx」以前沒有其餘的可識別擴展名了,因此apache就按照httpd.conf中參數 DefaultType的值來決定該文件的處理方式,即做爲txt文檔處理。

一樣的,對於「結果一」和「結果二」來講,也是按照這樣的方式來逐步肯定未知擴展名文件的解析方式,首先apache發現這個文件的擴展名是未知 的,那麼它會先看在擴展名以前是否有其餘的可識別的擴展名,在該案例中的完整文件名爲「f4ck.php.x」,那麼apache就發如今未知擴展名 「x」以前有一個可識別的擴展名是「php」,那麼apache就會認爲這是一個php文件,就會把這個文件按照解析php文件的方式來解析。

說到這裏,就不得不提一下,apache對於擴展名的定義都是寫在conf/mime.types文件中的,看一下圖:

5.png

文件mime.types定義了apache處理不一樣擴展名文件的方法,文件httpd.conf中參數DefaultType的值定義了apache處理未知擴展名文件的方法。

另外,文件httpd.conf中語句塊「」中能夠用「AddType」語句來定義apache解析不一樣擴展名文件的方法。

處理和解析是徹底不一樣的概念,這就好像對於apache+php結合的網站來講,apache是應用服務器,php是中間件,apache只負責接 收/響應HTTP請求,php卻負責.php文件的解釋執行。Php將.php文件解釋執行完畢後,將生成的HTML代碼發送給apache,再由 apache將HTML代碼發送給客戶端。

另外說一下,擴展名rar並無在文件mime.types中出現,因此若是遇到能夠上傳rar文件且與php的結合方式爲module方式的apache,則能夠直接上傳相似「f4ck.php.rar」的文件來得到webshell。

解決方案一

在httpd.conf或httpd-vhosts.conf中加入如下語句,從而禁止文件名格式爲*.php.*的訪問權限:

<FilesMatch ".(php.|php3.|php4.|php5.)">
Order Deny,Allow
Deny from all
</FilesMatch>

解決方案二

若是須要保留文件名,能夠修改程序源代碼,替換上傳文件名中的「.」爲「_」:

$filename = str_replace('.', '_', $filename);

若是不須要保留文件名,能夠修改程序源代碼,將上傳文件名重命名爲時間戳+隨機數的格式。

總結:網上說的「低版本的apache存在未知擴展名解析漏洞」的說法是錯誤的,正確的說法應該是使用module模式與php結合的全部版本 apache存在未知擴展名解析漏洞,使用fastcig模式與php結合的全部版本apache不存在此漏洞。而且,想利用此漏洞必須保證文件擴展名中 至少帶有一個「.php」,不然將默認被做爲txt/html文檔處理。

相關文章
相關標籤/搜索