preg-match 绕过
PHP preg_match () 函数
作用
preg_match 函数用于执行一个正则表达式匹配。
语法
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
搜索 subject 与 pattern 给定的正则表达式的一个匹配。
参数说明:
$pattern: 要搜索的模式,字符串形式。
$subject: 输入字符串。
$matches: 如果提供了参数 matches,它将被填充为搜索结果。 $matches [0] 将包含完整模式匹配到的文本, $matches [1] 将包含第一个捕获子组匹配到的文本,以此类推。
$flags:flags 可以被设置为以下标记值:
PREG_OFFSET_CAPTURE: 如果传递了这个标记,对于每一个出现的匹配返回时会附加字符串偏移量 (相对于目标字符串的)。 注意:这会改变填充到 matches 参数的数组,使其每个元素成为一个由 第 0 个元素是匹配到的字符串,第 1 个元素是该匹配字符串 在目标字符串 subject 中的偏移量。
offset: 通常,搜索从目标字符串的开始位置开始。可选参数 offset 用于 指定从目标字符串的某个未知开始搜索 (单位是字节)。
返回值
返回 pattern 的匹配次数。 它的值将是 0 次(不匹配)或 1 次,因为 preg_match () 在第一次匹配后 将会停止搜索。preg_match_all () 不同于此,它会一直搜索 subject 直到到达结尾。 如果发生错误 preg_match () 返回 FALSE。
绕过方法
1、数组绕过
preg_match 只能处理字符串,当传入的 subject 是数组时会返回 false
2、PCRE 回溯次数限制
payload:
1 | import requests |
pcre.backtrack_limit
给 pcre 设定了一个回溯次数上限,默认为 1000000,如果回溯次数超过这个数字,preg_match 会返回 false
3、换行符.
不会匹配换行符,例如
1 | if (preg_match('/^.*(flag).*$/', $json)) { |
需要$json="\nflag"
而在非多行模式下,$
似乎会忽略在句尾的 %0a
1 | if (preg_match('/^flag$/', $_GET['a']) && $_GET['a'] !== 'flag') { |
传入?a=flag%0a