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