异或运算符简介
^ | xor |
---|
位异或 运算 | 逻辑 运算 | 如 1^1=0 、 0^0=0 、 0^1=1 、1^1^1=0 、1^1^0=0 、 1^2=3 、 1^2=3 | 数字n xor 0 会输出n ;其他情况输出其他所有数据 |
- 异或运算规则:如果两个相应bit位相同,则结果为0,否则为1。
- 注释方法:
‘ xxxx # 、’ xxxx--+ - 异或运算:可以取每个字符的ASCII,转成二进制再做运算,为了方便,copy一个脚本,通过查ASCII表的符合和字符的异或,打印出所有可能的组合,这里的脚本过滤了一些不可打印字符。
异或运算符利用
-
用于加密 第一步,明文(text)与密钥(key)进行异或运算,可以得到密文(cipherText)。 text ^ key = cipherText 第二步,密文与密钥再次进行异或运算,就可以还原成明文。 cipherText ^ key = text -
用于数据备份 文件 x 和文件 y 进行异或运算,产生一个备份文件 z。 x ^ y = z 无论是文件 x 或文件 y 损坏,只要不是两个原始文件同时损坏,就能根据另一个文件和备份文件,进行还原。 -
用于判断过滤 eg:/?id=1'^(length('union')=5)%23 ;当union被过滤时1^0 输出id=1;当union没被过滤时 1 ^ 1 输出 id=0,回显 error -
以制作免杀马为例: 在制作免杀马的过程,根据php的语言特性对字符进行!运算会将字符类型转为bool类型,而bool类型遇到运算符号时,true会自动转为数字1,false会自动转为数字0,如果将bool类型进行计算,并使用chr()函数转为字符,使用".“进行连接,便可以绕过preg_match匹配。 详情了解php不同于其他语言部分 但是很多的preg_match会过滤掉”.",所以需要使用异或运算进行绕过,很多的免杀马都是这样制作的。php对字符进行异或运算是先将字符转换成ASCII码然后进行异或运算,并且php能直接对一串字符串进行异或运算,例如"123"^"abc"是"1"与"a"进行异或然后"2"与"b"进行异或,以此类推,在异或结束后就获得了想要的字符串。 注意点:进行异或运算时要将数字转换成字符形式,如果数字(int)和字符异或的话,结果只会是数字,例如1"a"=1,"a"2=2,将数字转换成字符串可以使用trim()函数。 拓展: php特性use of undefined constant,会将没有引号的字符都自动视为字符串,ASCII码大于0x7F的都会被当作字符串,由此可知可以简化异或过程,任何字符与0xff异或都会取相反,这样就能减少运算量了。 -
以GET或POST传入字符绕preg_match为例: php的eval()函数在执行时如果内部有类似"abc"^"def"的计算式,那么就先进行计算再执行,我们可以利用再创参数来实现更方便的操作,例如传入?a=KaTeX parse error: Expected 'EOF', got '&' at position 96: …?a={_GET}{b}();&?b=phpinfo,也就是?a…{%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo,在传入后实际上为
?
?
?
?
?
?
?
?
?
(
)
;
但
是
到
了
e
v
a
l
(
)
函
数
内
部
就
会
变
成
{????^????}{?}();但是到了eval()函数内部就会变成
?????????();但是到了eval()函数内部就会变成{_GET}{?}();成功执行。 注意2:测试中发现,传值时对于要计算的部分不能用括号括起来,因为括号也将被识别为传入的字符串,可以使用{}代替,原因是php的use of undefined constant特性,例如
G
E
T
a
这
样
的
语
句
p
h
p
是
不
会
判
为
错
误
的
,
因
为
使
用
来
界
定
变
量
的
,
这
句
话
就
是
会
将
G
E
T
自
动
看
为
字
符
串
,
也
就
是
{_GET}{a}这样的语句php是不会判为错误的,因为{}使用来界定变量的,这句话就是会将_GET自动看为字符串,也就是
G?ETa这样的语句php是不会判为错误的,因为使用来界定变量的,这句话就是会将G?ET自动看为字符串,也就是_GET[‘a’]
参考链接:https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html 参考链接:https://blog.csdn.net/weixin_46330722/article/details/112898103
|