php 代碼格式化工具PHP中對(duì)XSS進(jìn)行過(guò)濾的簡(jiǎn)單(繞過(guò))方法。php代碼格式化工具
2022-04-22
集成繞過(guò)。
接下來(lái)將展示一些簡(jiǎn)單(繞過(guò))過(guò)濾關(guān)鍵字的方法。
(1)過(guò)濾代碼
('/(and|or|||)/I',$id)
繞過(guò)方法:過(guò)濾關(guān)鍵字and,or,,,構(gòu)造代碼類似11|| ( user from by =1 ) = '' 繞過(guò)。
(2)過(guò)濾代碼
('/||||eval||||j
|link|'|%|/*|*|../|./|,|.|--|"|and,$str)
繞過(guò)方式:只過(guò)濾小寫注入關(guān)鍵字,大寫可以繞過(guò)。
三、XSS 審計(jì)
是近年來(lái)流行的一種攻擊方式。惡意攻擊者將惡意 html 代碼插入網(wǎng)頁(yè)。當(dāng)用戶瀏覽網(wǎng)頁(yè)時(shí),會(huì)執(zhí)行嵌入的html代碼,從而達(dá)到惡意攻擊用戶的特殊目的。 那么 PHP 中的 XSS 審計(jì)呢?
這是一段歷史,第一次在X3.1版本的補(bǔ)丁中修復(fù),但是對(duì)于仍然使用的舊版本的X3.1(其實(shí)大部分都在用老版本,因?yàn)閄3.1在出補(bǔ)丁的時(shí)候已經(jīng)放了很久了)和以下版本的網(wǎng)站,這個(gè)還是有效的。讓我們來(lái)看看審計(jì)過(guò)程。
此漏洞的代碼在下面的.php 中。
119 如果($){
120 if(($, 'ed2k://') != ) {
121 $ = ("/ed2k://(.+?)//e", "('1')",
$);
122 }
123 }
顯然,這段代碼是檢測(cè)ed2k協(xié)議是否開啟,并處理第121行的ed2k鏈接。為了讓大家更清楚的理解這些PHP代碼,這里簡(jiǎn)單介紹一下涉及到的一些API,假設(shè)你的PHP 的掌握處于入門階段。第121行的函數(shù)原型如下。
($,$,
$ [, int $ = -1 [, int &$]] )
// 進(jìn)行正則表達(dá)式搜索和替換:搜索的匹配部分被替換為
對(duì)于剛接觸的初學(xué)者,可能會(huì)覺得自己對(duì)代碼的掌握還不夠。不要緊。每種語(yǔ)言的官方手冊(cè)都有每個(gè)功能的詳細(xì)說(shuō)明,供開發(fā)者學(xué)習(xí)。對(duì)于有一定經(jīng)驗(yàn)的審計(jì)人員來(lái)說(shuō),開源項(xiàng)目的手冊(cè)或說(shuō)明文本中還有很多重要的部分,同一個(gè)廠商的過(guò)去也可能為審計(jì)指明方向,不要羞于站在巨人的肩膀上!
這個(gè)函數(shù)調(diào)用()函數(shù)對(duì)$進(jìn)行常規(guī)處理,我們來(lái)跟蹤處理函數(shù)()。
320 ($url) {
321 $_G;
322 list(,$type, $name, $size,) = ('|', $url);
//用于讀取連接的類型、名稱和大小
323 $url = 'ed2k://'.$url.'/';
324 $name = ($name);
325 if($type == '文件') {
326 $ = ''.(3);
327'
">'.(($name)).'
('.($size).')
$(''.$.'').=(
((''.$name.'')))+' ('.
($size).')';';
328 } 其他 {
329 ''.$url.'';
330 }
331 }
從這段代碼可以看出,()沒有對(duì)參數(shù)$size進(jìn)行安全處理,甚至沒有對(duì)$size進(jìn)行類型轉(zhuǎn)換(暫時(shí)認(rèn)為這是程序員的疏忽) ,所以在函數(shù)($size)中傳入的是字符串類型的$size變量。
下一個(gè) up()函數(shù),在.php同目錄下:
1601 ($size) {
1602 if($size >=) {
1603 $size = ($size/ * 100)/100 . 'GB';
1604 } 否則 if($size >= ) {
1605 $size = ($size / * 100) / 100 .'MB';
1606 } else if($size >= 1024) {
1607 $size = ($size / 1024 * 100) / 100 . 'KB';
1608 } 其他 {
1609 $size = $size 。 '';
1610 }
1611 美元大??;
1612 }
此代碼用于劃分文件大小。 類型的 $size 的值與類型比較時(shí),會(huì)被強(qiáng)制轉(zhuǎn)換為類型,然后進(jìn)行比較。如果傳入的$size不是純數(shù)字字符串,則將$size的值轉(zhuǎn)換為NaN(Not a),不會(huì)觸發(fā)前三個(gè)if語(yǔ)句,直接進(jìn)入else語(yǔ)句,函數(shù)在else 不正確 $size 進(jìn)行類型轉(zhuǎn)換,直接與 '' 配對(duì)。配對(duì)后的字符串最終返回到.php中第121行的$,然后輸出。
第 1609 行在 ×3.1 補(bǔ)丁中被替換為:
1609 $size = ($size)。' ';
函數(shù)將 $size 轉(zhuǎn)換為整數(shù),從而避免了對(duì) $size 的 XSS 攻擊。
讓我們測(cè)試一下:
在X3.1或以下版本的論壇發(fā)帖時(shí)插入這句話:
ed2k://|file|xss|'+(123)+'|xss/
圖 16 所示的對(duì)話框展示了漏洞的存在。
圖 16 XSS 對(duì)話框
順便說(shuō)一句,由于格式限制,這個(gè)不能包含各種引號(hào)。不要?dú)怵H,在這里你可以使用 .(.(... ...));寫html標(biāo)簽,比如這里的屬性src不需要引號(hào)來(lái)加載外部的js文件,然后就用這個(gè)吧。
通過(guò)簡(jiǎn)單分析可以發(fā)現(xiàn),程序員為了簡(jiǎn)化代碼(其實(shí)打補(bǔ)丁后并沒有簡(jiǎn)化),通過(guò)強(qiáng)制轉(zhuǎn)換將字符串類型的$size與整數(shù)類型進(jìn)行比較,然后直接比較 $size 和指示的文件大小,單位字符串連接,這種簡(jiǎn)化是一個(gè)很不好的習(xí)慣,在寫代碼的時(shí)候,應(yīng)該避免使用強(qiáng)制類型轉(zhuǎn)換來(lái)比較不同類型的變量,這種方法經(jīng)常被攻擊者使用(比如這里)。
四、變量覆蓋
關(guān)于變量覆蓋,首先要了解PHP的特點(diǎn)。 PHP 是一種松散類型的語(yǔ)言,它會(huì)根據(jù)變量的值自動(dòng)將變量轉(zhuǎn)換為正確的數(shù)據(jù)類型。變量覆蓋是指攻擊者在攻擊過(guò)程中給它一個(gè)特定的值,并覆蓋原來(lái)的固定值,從而引起一些安全問(wèn)題。常見的變量覆蓋如下所述。
1、變量初始化
這種類型的變量覆蓋需要 =on 才能發(fā)生。我們來(lái)看看《黑云與白帽》的一個(gè)漏洞。
這里的變量沒有初始化,而是直接代入查詢語(yǔ)句,導(dǎo)致變量覆蓋,這里觸發(fā)注入。注入格式為 ?=list&= 語(yǔ)句。
2、危險(xiǎn)函數(shù)導(dǎo)致的變量覆蓋
角色
() 函數(shù)是將數(shù)組中的變量導(dǎo)入到當(dāng)前符號(hào)表中。當(dāng)函數(shù)中的類型參數(shù)為默認(rèn)值且傳入的變量同名時(shí),會(huì)被覆蓋,導(dǎo)致其他安全問(wèn)題。我們來(lái)看一個(gè)開源程序代碼。
第4行的($)命令導(dǎo)致變量覆蓋,所以我們可以直接覆蓋$,完成注入語(yǔ)句。
五、命令執(zhí)行
命令執(zhí)行是PHP的一種常見類型,危害更大,直接威脅服務(wù)器的安全。在PHP中,命令執(zhí)行經(jīng)常發(fā)生在高危函數(shù)上,如eval()、()、()、exec()、()、()、()。由于開發(fā)者的疏忽,這些函數(shù)執(zhí)行的命令有時(shí)是用戶可控的,導(dǎo)致攻擊者提交惡意代碼達(dá)到攻擊目的。下面就來(lái)分析一下。
1、常用命令執(zhí)行函數(shù)
(1)eval()
此函數(shù)根據(jù) PHP 代碼執(zhí)行字符串。語(yǔ)法:
eval();
以下是問(wèn)題的代碼:
這是一個(gè)非常簡(jiǎn)單的代碼??梢钥吹酱a中將參數(shù)com的值傳遞給了變量com,然后變量com的值直接作為PHP代碼執(zhí)行,因此漏洞出現(xiàn)。當(dāng)參數(shù)com為();時(shí),結(jié)果如圖17所示。
圖 17 執(zhí)行命令
(2)()
該函數(shù)類似于C語(yǔ)言的()函數(shù),用于執(zhí)行指令并輸出結(jié)果。語(yǔ)法格式:
( , int []);
以下是問(wèn)題的代碼:
當(dāng)參數(shù)com為時(shí),結(jié)果如圖18所示。
圖 18 執(zhí)行命令
當(dāng)參數(shù)com為ping時(shí),結(jié)果如圖19所示。
圖 19 執(zhí)行 ping 命令
(3)()
此函數(shù)在應(yīng)用用戶自定義函數(shù)后返回?cái)?shù)組?;卣{(diào)函數(shù)接收的參數(shù)個(gè)數(shù)應(yīng)該和傳遞給()函數(shù)的數(shù)組個(gè)數(shù)一樣,語(yǔ)法格式:
(, , , ...)
以下是問(wèn)題的代碼:
讓上面代碼中的參數(shù)為 ,結(jié)果如圖20所示。
圖 20 執(zhí)行命令
2、動(dòng)態(tài)函數(shù)
在實(shí)際開發(fā)中,有些程序員希望動(dòng)態(tài)調(diào)用某些函數(shù),卻往往忽略了動(dòng)態(tài)函數(shù)的風(fēng)險(xiǎn)。
以下是問(wèn)題的代碼:
在上面的代碼中,程序員的初衷是動(dòng)態(tài)調(diào)用A函數(shù)和B函數(shù),所以變量作為函數(shù)名,是可控的。但這實(shí)際上等同于執(zhí)行任何函數(shù)。當(dāng)參數(shù)為,參數(shù)com為ping時(shí),結(jié)果如圖21所示。
圖21直接執(zhí)行ping命令
六、上傳繞過(guò)
熟悉的朋友一定知道,文件上傳是主要方式之一,是獲取Web權(quán)限的重要方式,而且往往是最后一級(jí),可見其重要性。下面我們來(lái)分析一下常見的文件上傳繞過(guò)。
1、Java 繞過(guò)
我們先來(lái)看一個(gè)示例代碼:
讓我們看看函數(shù)。
可以看到調(diào)用是一段Java代碼,我們回到函數(shù)。
此代碼在文件類型無(wú)效時(shí)調(diào)用,但無(wú)論調(diào)用失敗與否,都會(huì)執(zhí)行上傳代碼,所以只要禁用Java,就可以知道上傳文件的路徑。
這里直接替換包(因?yàn)镴ava是客戶端腳本語(yǔ)言,只限制瀏覽器),如圖22。
圖 22 改為更改包
2、文件頭驗(yàn)證繞過(guò)
問(wèn)題代碼如下。
以上代碼判斷文件類型,只允許/gif類型。但是人們?nèi)匀豢梢詡卧爝@樣的標(biāo)題進(jìn)行上傳。
3、邏輯問(wèn)題
示例代碼如下。
問(wèn)題出在后綴判斷和功能上。我們先來(lái)看看后綴判斷。
如果($[0] == ($[1]) && $[1] ==
"")
上傳XX.jpg.php時(shí):
$[0]=××
$[1]=jpg
$[2]=php
但是可以看到if語(yǔ)句沒有判斷$[2],所以成功繞過(guò)進(jìn)入函數(shù)。
($[''] . "/" . $[$]['name'], $
dat[''] 。 “/”。 $[0] 。 “?!?. ($[1]));
這里將之前上傳的××.jpg.php重命名為××.jpg。但是根據(jù)功能特點(diǎn)網(wǎng)站優(yōu)化,第二次上傳同名文件時(shí)php 代碼格式化工具,比如××.jpg.php,會(huì)進(jìn)入進(jìn)程嘗試重命名××.jpg,但是因?yàn)椤痢?.jpg 已經(jīng)存在,上傳成功。 ××.jpg.php.
七、文件包含
文件包含也是 PHP 中的一個(gè)常見漏洞,因此它通常是極其有害的。那么什么是文件包含?它經(jīng)常出現(xiàn)在 ()、()、()、() 以及這些加載文件的函數(shù)上。由于文件名沒有被過(guò)濾,攻擊者可以包含任意文件或特定文件,從而達(dá)到攻擊的目的。
1、漏洞
問(wèn)題代碼如下。
這段代碼的初衷應(yīng)該是調(diào)用一個(gè)文件的樣式和函數(shù)。但是因?yàn)檫@里的目錄是用戶可控的,所以可以調(diào)用任何文件。問(wèn)題就出在這,如果攻擊者上傳一張末尾帶有PHP惡意代碼的圖片,比如/××.jpg,然后訪問(wèn)?dir=/××.jpg,惡意代碼就會(huì)被引入到當(dāng)前文件中并執(zhí)行,從而達(dá)到攻擊的目的。
當(dāng)然,文件包含不限于包含上傳的文件,還可以包含一些配置文件。
?dir=.
?dir=../../../../../../web.
?dir=../../../../../../../../../var/log//.log
?dir=../../../../../../../../../proc/.gz(需要root權(quán)限)
?dir=../../../../../../../../../etc/(需要root權(quán)限)
2、繞過(guò)限制
在實(shí)際開發(fā)中,開發(fā)者為了避免受害,對(duì)包含路徑做了很多限制,比如下面的代碼。
從這里可以看出,開發(fā)者同時(shí)控制目錄和后綴。但是可以提交 ../ 以輕松繞過(guò)對(duì)目錄的限制,同時(shí)繞過(guò)對(duì)帶有截?cái)嗟暮缶Y的限制。如?dir=../../../../../../../etc/,從而包含惡意文件。
截?cái)嘈枰?off,只有在PHP版本小于5.3.4時(shí)才能實(shí)現(xiàn)。
當(dāng)然,對(duì)于上面的代碼,還有其他方法可以繞過(guò)它的限制,比如路徑長(zhǎng)度截?cái)啵≒HP版本小于5.2.8,文件名長(zhǎng)度大于4096字節(jié),長(zhǎng)度大于256字節(jié)),句點(diǎn)截?cái)啵≒HP版本小于5.2.8,僅適用于系統(tǒng),句點(diǎn)長(zhǎng)度必須大于256字節(jié)) 等。
讓我們看看另一段過(guò)濾目錄的代碼。
.php:
這個(gè)過(guò)濾代碼使用一個(gè)函數(shù)將../替換為./,這樣攻擊者就無(wú)法使用../跳出目錄。但是在提交.../的時(shí)候,因?yàn)?./被./替換了,又變成了../,從而跳出了目錄。所以當(dāng)人們提交 ?dir=.../.php 時(shí),文件就被成功包含進(jìn)來(lái)了。
測(cè)試結(jié)果如圖23所示。
圖 23 包含本地文件
3、讀取任何文件
是最常用的文件讀取函數(shù),用于將整個(gè)文件讀入一個(gè)字符串。語(yǔ)法:
(路徑, , , , )
也稱為任意文件讀取,它控制要讀取的文件的路徑,從而達(dá)到攻擊的目的,比如讀取一些數(shù)據(jù)庫(kù)配置文件。
我們先來(lái)看一段代碼:
提交 ?dir=/data/web.結(jié)果如圖 24 所示。
圖 24 讀取本地文件
八、寫在最后
隨著互聯(lián)網(wǎng)的普及,商業(yè)網(wǎng)站、政府網(wǎng)站、個(gè)人博客數(shù)不勝數(shù)。建站門檻越來(lái)越低,建站流程越來(lái)越標(biāo)準(zhǔn)化、智能化。很多不懂網(wǎng)站開發(fā)的人也可以使用騰云網(wǎng)絡(luò)搭建自己的網(wǎng)站。云網(wǎng)絡(luò)價(jià)格低廉,很多企業(yè)和政府也選擇了安全性高、口碑好的騰云網(wǎng)絡(luò)進(jìn)行網(wǎng)站建設(shè)。因此php 代碼格式化工具,騰云網(wǎng)絡(luò)的安全尤為重要。如今,隨著PHP的廣泛使用,PHP在開源市場(chǎng)中的地位越來(lái)越高。在這里,我以總結(jié)的形式談?wù)勯_源審計(jì)的經(jīng)驗(yàn)。
在審計(jì)開始時(shí),應(yīng)該先通讀全局文件,看看是否有一些全局過(guò)濾,大致了解程序的結(jié)構(gòu)。如果做全局過(guò)濾,可以嘗試對(duì)代碼進(jìn)行過(guò)濾,如果成功了,就徹底落下了。
在審計(jì)中,應(yīng)特別注意用戶可控制的參數(shù)。對(duì)于可控參數(shù)的搜索,可以檢索一些參數(shù)組小程序開發(fā),以提高審計(jì)效率。常用參數(shù)組見表1。
表1常用參數(shù)組
當(dāng)找到一個(gè)可控參數(shù)時(shí),可以分析它經(jīng)過(guò)了幾次,是否進(jìn)入了查詢語(yǔ)句,經(jīng)歷了幾次功能。說(shuō)到函數(shù),在PHP審計(jì)中,尋找高風(fēng)險(xiǎn)函數(shù)也是最有效的方法之一。常見的高危函數(shù)見表2。
表2常見的高風(fēng)險(xiǎn)函數(shù)
在開源程序中,它顯得更為次要。可想而知,如果需要帶走的物品很多,但一次拿的不多,可以分兩次拿走。第二次也是如此。將一次攻擊分成兩次,但可以達(dá)到同樣的目的,而且這種隱蔽性比較高,在大中型的騰云網(wǎng)絡(luò)中經(jīng)常出現(xiàn)。腦力,也是對(duì)審核員耐心和體力的考驗(yàn)。