异或绕过及其原理

异或的原理

总的来说,异或就是两个字符的二进制进行异或

比如:

a=01010101; //假设其为二进制
b=10101010;
c=a^b;        //进行异或
c=11111111;
总的来说就是两个字符二进制一个为0,另一个为1时,异或结果为1
只要不同就为1,相同就为0。

为什么上面的异或和在CTF题中看到的不一样

相信有很多人和我最开始一样,对异或还是有有点疑惑,我们平时异或出的为字母,而不是二进制,这到底该怎么判断呢?

我们知道大部分字符都可以用ascii码表示,而异或通过ascii码就可以输出所有字符,并且利用16进制将其变为不可见字符,就可以实现大部分字符的绕过操作。

例如:
1^2 //输出1
0x1^0x2//输出1

而我们大部分都利用%ff进行异或,他在16进制中表示255。

其中我们经常使用的_GET的ASCII码为

_GET
95 71 69 84

然后将其转化为hex(16进制编码),再进行异或。

hex(95)
'0x4f'
hex(0x4f^0xff)
'0xa0'
hex(71)
'0x47'
hex(0x47^0xff)
'0xb8'
.....

得到'0xa0 b8 ba ab'
'0xa0b8baab'将其与'0xffffffff'异或变成了_GET
所以我们urlencode后就为(%a0%b8%ba%ab)^(%ff%ff%ff%ff)

所以,我们可以这样进行绕过。

最后,附上异或脚本

<?php
$l='';
$r='';
$argv= str_split("_GET");//更改里面的值,改为需要的字符
for($i=0;$i<count($argv);$i++)
{
    for($j=0;$j<255;$j++)
    {
        $k=chr($j)^chr(255);
        if($k==$argv[$i])
        {
            if($j<16)
            {
                $l.="%ff";
                $r.="%0".dechex($j);
                continue;
            }
            $l.="%ff";
            $r.="%".dechex($j);
        }
    }
}
echo "\{$l^$r\}";
posted @ 2024-03-26 22:21  follycat  阅读(20)  评论(0编辑  收藏  举报