PHP中乙個有趣的preg replace函式詳解

2022-10-06 06:09:12 字數 1508 閱讀 7200

0x01 起因

事情的起因是下午遇到了 preg_replace 函式,我們都知道 preg_replace 函式可能會導致命令執行。現在我們來一些情況。

0x02 經過

踩坑1:

測試**大概是這樣的:

foreach ($_get as $regex => $value)

測試過程中發現通過瀏覽器的方式傳入資料的時候,會將 . + 等特殊字元轉換為 _ 。

這裡涉及到了php的乙個特性

php自身在解析請求的時候,如果引數名字中包含空格、.、[等字元,會將他們轉換成_。

<?php $a = $_get;

var_dump($a);

?>

經過我的fuzz,結果如程式設計客棧下圖:

踩坑2:

那我們知道 preg_replace 的 /e 修正符會將 replacement 引數當作 php **,並且以 eval 函式的方式執行,前提是 subject 中有 pattern 的匹配。既然是這樣我們看一張圖。

圖中實際上通過 eval 執行的是 strtolower 函式。分別實際執行的是:

strtolower("just test");

strtolower("phpinfo()xhhzibge");

strtolowe"}");

第三個之所以可以執行**,是因為我們通過複雜(花括號)語法的方式來讓其**執行。

踩坑3:

回到源**中,我們再理解一下:

foreach ($_get as $regex => $value)

這裡的 replacement 是 strtolower(「\\1」) ,著重理解一下 \\1 。

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

假設乙個正規表示式是這樣的:

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

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

$1 $2 $3 $4

'/(.*)(\?|&)' . $key . '=[^&]+?(&)(.*)/i'

0x03 解決

好了上面都已經鋪墊完坑了,這裡要開始解決了。

foreach ($_get as $regex => $value)

我們想要讓這部分**達到**執行的效果需要達到幾個條件:

我們知道這裡是通過 get 方式獲取到 \$regex 和 \$value 的,要想在 replacement 部分通過 \1 擷取到 pattern 正則匹配命中 \$value 中的資料,並且攜帶 \$ 、 }

0x04 後記

其實還有點小問題,我這邊沒有寫,不過大家可以看看這個深入研究preg_replace與**執行。

總結本文標題: php中乙個有趣的preg_replace函式詳解

本文位址:

彙編中乙個有趣的問題

int main 問題是下面哪個關係成立 a b c還是 a b c?我們知道區域性變數是存放在棧中的,a先push,然後是b,最後是c。而棧指標sp是從高位址 低位址方向移動的,所以 a b c。如果void f int a int b,int c 這裡就是 a b c,因為引數是逆序進棧的。網上...

C中乙個有趣的列印

在lresult sendmessage hwnd hwnd,handle of destination window uint msg,message to send wparam wparam,first message parameter lparam lparam second messag...

彙編中乙個有趣的問題

intmain 問題是下面哪個關係成立 a b c還是 a b c?我們知道區域性變數是存放在棧中的,a先push,然後是b,最後是c。而棧指標sp是從高位址 低位址方向移動的,所以 a b c。如果void f int a int b,int c 這裡就是 a b c,因為引數是逆序進棧的。網上有...