1.文件包含小知識
1.1 包含函數
- PHP共有4個與文件包含相關的函數:
include
require
include_once
require_once
- 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會按代碼順序執行。
1.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:// ------處理交互式的流
1.3 常用偽協議
- file://
(1)這個協議可以展現本地文件系統,默認目錄是當前的工作目錄。
(2)例如:file:///etc/passwd、file://key.txt
- php://
(1) php://input是個可以訪問請求的原始數據的只讀流,可以訪問請求的原始數據的只讀流,將post請求中的數據作為php代碼執行。
(2) php://filter是一種元封裝器,設計用於數據流打開時的篩選過濾應用。
- phar://
(1)phar://數據流包裝器自PHP5.3.0起開始有效
(2)例如:phar://E:/phpstudy/www/1.zip/phpinfo.txt | phar://1.zip/phpinfo.txt
1.4 偽協議利用方式小總結
2.getshell總結
2.1 Getshell之session
條件:session文件路徑已知,且session文件中內容部分可控。
獲取session文件路徑:
- session文件的保存路徑可以在phpinfo的session.save_path看到。
-
默認路徑:
/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和惡意代碼已經正常解析和執行。
2.2 Getshell之日志
2.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
2.2.2 SSH log
條件:需要知道ssh-log的位置,且可讀。
ssh日志默認路徑:
1./var/log/auth.log
2./var/log/secure
利用:
1.用ssh連接:
ssh \'\<?php phpinfo(); ?>\'\@remotehost
之后會提示輸入密碼,隨便輸入就可以。
2.然后利用文件包含,包含日志文件:
2.3 Getshell之environ
條件:
-
php以cgi方式運行,這樣environ才會保持UA頭。
-
environ文件存儲位置已知,且有權限訪問environ文件。
environ文件默認位置:proc/self/environ
利用:
-
proc/self/environ中會保存user-agent頭。如果在user-agent中插入php代碼,則php代碼會被寫入到environ中。之后再包含它,即可。
-
例如我們現在訪問一個網站,使用burpsuite抓包,將惡意代碼插入到user-agent中。
3.利用文件包含漏洞去包含proc/self/environ,成功執行php代碼。
2.4 Getshell之利用phpinfo
條件:
存在phpinfo頁面並且存在文件包含漏洞
原理:
1.當我們給PHP發送POST數據包時,如果數據包里包含文件區塊,PHP就會將文件保存成一個臨時文件,路徑通常為:/tmp/php[6個隨機字符],這個臨時文件,在請求結束后就會被刪除。
2.因為phpinfo頁面會將請求上下文中的所有變量打出來,所以我們如果向phpinfo頁面發送包含文件區塊的數據包,就可以在返回包里找到臨時文件名,也就是\$_FILES變量中的內容。
利用:
- 首先我們使用vulhub的腳本(https://github.com/vulhub/vulhub/blob/master/php/inclusion/exp.py),他可以實現包含臨時文件,而這個臨時文件的內容是:<?php fileputcontents('/tmp/p','<?=eval($_REQUEST[1])?>')?>。成功包含這個文件后就會生成新的文件/tmp/p,這個文件就會永久的留在目標機器上。
- 寫入成功以后,我們利用文件包含來執行任意命令。
原理:
那么為什么vulhub的腳本是如何做到在臨時腳本文件刪除前去包含的呢,其實就是用到了條件競爭,具體流程大致如下:
1.首先發送包含webshell的數據包給phpinfo頁面,並用大量的垃圾數據將header和get等位置填滿。
2.因phpinfo頁面會將所有數據打印出來,第一個步驟中的垃圾數據就會將phpinfo頁面撐的非常大。而php默認輸出緩沖區大小為4096,也可以理解為php每次返回4096個字節給socket連接。
3.所以,這里直接操作原生socket,每次讀取4096個字節。只要我們讀取到字節里包含臨時文件名,就立刻發送文件包含漏洞利用的數據包。因為第一個數據包的socket連接沒有結束,所以臨時文件還沒有刪除,我們就可以文件包含成功。
2.5 Getshell之上傳文件
條件:
有上傳點,知道上傳上去的文件名和存放目錄。
利用:
-
這里用一個靶場簡單演示一下,找個文件上傳點,上傳一個帶有php惡意代碼的圖片。
-
我們現在已知文件名稱和路徑,可以利用文件包含漏洞去包含這個圖片,就可以成功執行php代碼了。
3.防護措施
1、在很多場景中都需要去包含web目錄之外的文件,如果php配置了open_basedir,則會包含失敗。
2、對可以包含的文件進行限制,可以采用白名單的方式,或設置可以包含的目錄。
3、對危險字符進行過濾。
4、盡量不使用動態包含等等