您好,登錄后才能下訂單哦!
本篇文章為大家展示了PHP中preg_replace的作用是什么,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
這個(gè)案例實(shí)際上很簡(jiǎn)單,就是 preg_replace 使用了 /e 模式,導(dǎo)致可以代碼執(zhí)行,而且該函數(shù)的第一個(gè)和第三個(gè)參數(shù)都是我們可以控制的。我們都知道, preg_replace 函數(shù)在匹配到符號(hào)正則的字符串時(shí),會(huì)將替換字符串(也就是上圖 preg_replace 函數(shù)的第二個(gè)參數(shù))當(dāng)做代碼來(lái)執(zhí)行,然而這里的第二個(gè)參數(shù)卻固定為 'strtolower("\\1")' 字符串,那這樣要如何執(zhí)行代碼呢?
爬坑1
上面的命令執(zhí)行,相當(dāng)于 eval('strtolower("\\1");')
結(jié)果,當(dāng)中的 \\1 實(shí)際上就是 \1 ,而 \1 在正則表達(dá)式中有自己的含義。我們來(lái)看看 W3Cschool 中對(duì)其的描述:
反向引用
對(duì)一個(gè)正則表達(dá)式模式或部分模式 兩邊添加圓括號(hào) 將導(dǎo)致相關(guān) 匹配存儲(chǔ)到一個(gè)臨時(shí)緩沖區(qū) 中,所捕獲的每個(gè)子匹配都按照在正則表達(dá)式模式中從左到右出現(xiàn)的順序存儲(chǔ)。緩沖區(qū)編號(hào)從 1 開(kāi)始,最多可存儲(chǔ) 99 個(gè)捕獲的子表達(dá)式。每個(gè)緩沖區(qū)都可以使用 '\n' 訪問(wèn),其中 n 為一個(gè)標(biāo)識(shí)特定緩沖區(qū)的一位或兩位十進(jìn)制數(shù)。
所以這里的 \1 實(shí)際上指定的是第一個(gè)子匹配項(xiàng),我們拿 ripstech 官方給的 payload 進(jìn)行分析,方便大家理解。官方 payload 為: /?.*={${phpinfo()}}
,即 GET 方式傳入的參數(shù)名為 /?.* ,值為 {${phpinfo()}}
。
原先的語(yǔ)句: preg_replace('/(' . $regex . ')/ei', 'strtolower("\\1")', $value);
變成了語(yǔ)句: preg_replace('/(.*)/ei', 'strtolower("\\1")', {${phpinfo()}});
爬坑2
上面的 preg_replace 語(yǔ)句如果直接寫(xiě)在程序里面,當(dāng)然可以成功執(zhí)行 phpinfo() ,然而我們的 .* 是通過(guò) GET 方式傳入,你會(huì)發(fā)現(xiàn)無(wú)法執(zhí)行 phpinfo 函數(shù),如下圖:
我們 var_dump 一下 $_GET 數(shù)組,會(huì)發(fā)現(xiàn)我們傳上去的 .* 變成了 _* ,如下圖所示:
這是由于在PHP中,對(duì)于傳入的非法的 $_GET 數(shù)組參數(shù)名,會(huì)將其轉(zhuǎn)換成下劃線,這就導(dǎo)致我們正則匹配失效。我們可以 fuzz 一下PHP會(huì)將哪些符號(hào)替換成下劃線,發(fā)現(xiàn)有:(這是非法字符不為首字母的情況)
當(dāng)非法字符為首字母時(shí),只有點(diǎn)號(hào)會(huì)被替換成下劃線:
所以我們要做的就是換一個(gè)正則表達(dá)式,讓其匹配到 {${phpinfo()}}
即可執(zhí)行 phpinfo 函數(shù)。這里我提供一個(gè) payload : \S*=${phpinfo()}
執(zhí)行結(jié)果如下:
爬坑3
下面再說(shuō)說(shuō)我們?yōu)槭裁匆ヅ涞?{${phpinfo()}}
或者 ${phpinfo()}
,才能執(zhí)行 phpinfo 函數(shù),這是一個(gè)小坑。這實(shí)際上是PHP可變變量 的原因。在PHP中雙引號(hào)包裹的字符串中可以解析變量,而單引號(hào)則不行。 ${phpinfo()}
中的 phpinfo() 會(huì)被當(dāng)做變量先執(zhí)行,執(zhí)行后,即變成 ${1} (phpinfo()
成功執(zhí)行返回true)。如果這個(gè)理解了,你就能明白下面這個(gè)問(wèn)題:
var_dump(phpinfo()); // 結(jié)果:布爾 true var_dump(strtolower(phpinfo()));// 結(jié)果:字符串 '1' var_dump(preg_replace('/(.*)/ie','1','{${phpinfo()}}'));// 結(jié)果:字符串'11' var_dump(preg_replace('/(.*)/ie','strtolower("\\1")','{${phpinfo()}}'));// 結(jié)果:空字符串'' var_dump(preg_replace('/(.*)/ie','strtolower("{${phpinfo()}}")','{${phpinfo()}}'));// 結(jié)果:空字符串'' 這里的'strtolower("{${phpinfo()}}")'執(zhí)行后相當(dāng)于 strtolower("{${1}}") 又相當(dāng)于 strtolower("{null}") 又相當(dāng)于 '' 空字符串
上述內(nèi)容就是PHP中preg_replace的作用是什么,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。