1. 程式人生 > 實用技巧 >程式碼審計原理之程式碼執行

程式碼審計原理之程式碼執行

0x01 程式碼執行

PHP程式碼執行漏洞可以將程式碼注入到應用中,最終到webserver去執行,該漏洞主要存在於eval()、assert()、preg_replace()、call_user_func()、array_map()以及動態函式中

  • eval();
  • assert();
  • preg_replace();

preg_replace():加上模式修飾符也會造成程式碼執行

關於模式修飾符:https://www.php.net/manual/zh/reference.pcre.pattern.modifiers.php

//preg_replace([正則表示式], [要替換的內容], [被查詢的字串]);
//preg_replace([1], [2], [3]);

[1]可控時:

$a=$_GET['a'];// /e
preg_replace("/<php>(.*?)<\/php>$a",'\\1', "<php>phpinfo();</php>");

使$a=/e,會造成程式碼執行(php版本為5.5以下)

模式修飾符/e:如果設定了這個被棄用的修飾符,preg_replace()在進行了對替換字串的 後向引用替換之後, 將替換後的字串作為php 程式碼評估執行(eval 函式方式),並使用執行結果 作為實際參與替換的字串。單引號、雙引號、反斜線(\)和 NULL 字元在 後向引用替換時會被用反斜線轉義.

[2]可控時:

$a=$_GET['a'];//phpinfo();
preg_replace("/php/e", $a, 'php');

使$a=phpinfo();,成功程式碼執行

[3]可控時:

$a=$_GET['a'];//{php}phpinfo(){/php}
preg_replace("/\s*\{php\}(.*?)\{\/php\}\s*/ies", '\\1', $a);

使$a={php}phpinfo(){/php},成功程式碼執行

模式修飾符/i:如果設定了這個修飾符,模式中的字母會進行大小寫不敏感匹配。

模式修飾符/s:如果設定了這個修飾符,模式中的點號元字元匹配所有字元,包含換行符。如果沒有這個 修飾符,點號不匹配換行符。這個修飾符等同於 perl 中的/s修飾符。 一個取反字元類比如 [^a] 總是匹配換行符,而不依賴於這個修飾符的設定。

0x02 修復

preg_replace()放棄使用/e修飾符

preg_replace_callback()使用該函式代替preg_replace()函式(preg_replace()函式使用/e修飾符的用法在PHP5.5之後被拋棄使用)

$a=$_GET['a'];//{php}phpinfo(){/php}
preg_replace_callback("/\s*\{php\}(.*?)\{\/php\}\s*/ies", '\\1', $a);