主頁(yè) > 知識(shí)庫(kù) > PHP中一個(gè)有趣的preg_replace函數(shù)詳解

PHP中一個(gè)有趣的preg_replace函數(shù)詳解

熱門(mén)標(biāo)簽:萍鄉(xiāng)商鋪地圖標(biāo)注 電信外呼系統(tǒng)多少錢(qián)一個(gè)月 神龍斗士電話機(jī)器人 太原400電話申請(qǐng)流程 代理打電話機(jī)器人 合肥企業(yè)外呼系統(tǒng)線路 企業(yè)400電話辦理多少費(fèi)用 桂陽(yáng)公司如何做地圖標(biāo)注 宿州正規(guī)外呼系統(tǒng)軟件

0x01 起因

事情的起因是下午遇到了 preg_replace 函數(shù),我們都知道 preg_replace 函數(shù)可能會(huì)導(dǎo)致命令執(zhí)行。現(xiàn)在我們來(lái)一些情況。

0x02 經(jīng)過(guò)

踩坑1:

測(cè)試代碼大概是這樣的:

foreach ($_GET as $regex => $value) {
 preg_replace('/(' . $regex . ')/ei','strtolower("\\1")',$value);
}

測(cè)試過(guò)程中發(fā)現(xiàn)通過(guò)瀏覽器的方式傳入數(shù)據(jù)的時(shí)候,會(huì)將 . + 等特殊字符轉(zhuǎn)換為 _ 。

這里涉及到了php的一個(gè)特性

php自身在解析請(qǐng)求的時(shí)候,如果參數(shù)名字中包含空格、.、[等字符,會(huì)將他們轉(zhuǎn)換成_。

?php
$a = $_GET;
var_dump($a);
?>

經(jīng)過(guò)我的fuzz,結(jié)果如下圖:

踩坑2:

那我們知道 preg_replace 的 /e 修正符會(huì)將 replacement 參數(shù)當(dāng)作 php 代碼,并且以 eval 函數(shù)的方式執(zhí)行,前提是 subject 中有 pattern 的匹配。既然是這樣我們看一張圖。

圖中實(shí)際上通過(guò) eval 執(zhí)行的是 strtolower 函數(shù)。分別實(shí)際執(zhí)行的是:

strtolower("JUST TEST");
strtolower("PHPINFO()");
strtolower("{${PHPINFO()}}");

第三個(gè)之所以可以執(zhí)行代碼,是因?yàn)槲覀兺ㄟ^(guò)復(fù)雜(花括號(hào))語(yǔ)法的方式來(lái)讓其代碼執(zhí)行。

踩坑3:

回到源代碼中,我們?cè)倮斫庖幌拢?/p>

foreach ($_GET as $regex => $value) {
 preg_replace('/(' . $regex . ')/ei','strtolower("\\1")',$value);
}

這里的 replacement 是 strtolower(“\\1”) ,著重理解一下 \\1 。

每個(gè)這樣的引用將被匹配到的第n個(gè)捕獲子組捕獲到的文本替換。 n可以是0-99,\0和\$0代表完整的模式匹配文本。

假設(shè)一個(gè)正則表達(dá)式是這樣的:

preg_replace('/(.*)(\&;|)' . $key . '=[^]+?()(.*)/i', '$1$2$4', $url . '');

這里的 \$1\$2\$4 等同于上面的 \1\2\4 的作用,因此我們看一下是怎么選擇匹配的。

 $1 $2   $3 $4
'/(.*)(\&;|)' . $key . '=[^]+?()(.*)/i'

0x03 解決

好了上面都已經(jīng)鋪墊完坑了,這里要開(kāi)始解決了。

foreach ($_GET as $regex => $value) {
 preg_replace('/(' . $regex . ')/ei','strtolower("\\1")',$value);
}

我們想要讓這部分代碼達(dá)到代碼執(zhí)行的效果需要達(dá)到幾個(gè)條件:

  • pattern 部分的表達(dá)式需要命中 \$value 中的數(shù)據(jù)
  • \1 中取出的數(shù)據(jù)復(fù)雜(花括號(hào))語(yǔ)法的特征,來(lái)保證在雙引號(hào)的包含下達(dá)到代碼執(zhí)行的效果
  • 由于php的特性u(píng)rl會(huì)將 . 、 [ 、 + 等特殊字符轉(zhuǎn)換為 _ 。

我們知道這里是通過(guò) get 方式獲取到 \$regex 和 \$value 的,要想在 replacement 部分通過(guò) \1 截取到 pattern 正則匹配命中 \$value 中的數(shù)據(jù),并且攜帶 \$ 、 { 、 ( 這里就涉及到正則表達(dá)式的使用了。

這里我選擇了 \S ,也就是匹配任意的非空白字符,那么最后的payload長(zhǎng)這樣

\S*()={${phpinfo()}}

0x04 后記

其實(shí)還有點(diǎn)小問(wèn)題,我這邊沒(méi)有寫(xiě),不過(guò)大家可以看看這個(gè)深入研究preg_replace與代碼執(zhí)行。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

您可能感興趣的文章:
  • PHP 字符串正則替換函數(shù)preg_replace使用說(shuō)明
  • PHP正則替換函數(shù)preg_replace和preg_replace_callback使用總結(jié)
  • php正則之函數(shù) preg_replace()參數(shù)說(shuō)明
  • PHP 正則表達(dá)式之正則處理函數(shù)小結(jié)(preg_match,preg_match_all,preg_replace,preg_split)
  • php中preg_replace_callback函數(shù)簡(jiǎn)單用法示例
  • php中使用preg_replace函數(shù)匹配圖片并加上鏈接的方法
  • php正則preg_replace_callback函數(shù)用法實(shí)例
  • PHP正則替換函數(shù)preg_replace()報(bào)錯(cuò):Notice Use of undefined constant的解決方法分析
  • PHP5.2下preg_replace函數(shù)的問(wèn)題

標(biāo)簽:衡陽(yáng) 白銀 綏化 鄂州 廊坊 崇左 辛集 太原

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《PHP中一個(gè)有趣的preg_replace函數(shù)詳解》,本文關(guān)鍵詞  PHP,中,一個(gè),有趣,的,preg,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《PHP中一個(gè)有趣的preg_replace函數(shù)詳解》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于PHP中一個(gè)有趣的preg_replace函數(shù)詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章