目的:
${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
//${_GET}{%ff}();&%ff=phpinfo
这个是大家常见的异或的bypass的payload。我看网上很多都是说“这里有个payload”,…然后就没有什么了,我这个payload也用了一段时间,
也是 知其然不知其所以然,用也这么用了,然后后面碰到题,,一变化就不会了,所以今天弄弄,看看能弄明白不,
关于这个%ff 以及异或的事情,咱们好好唠唠
这个这个,异或,只能够是数字和数字之间异或,原理是转为二进制进行异或,这个不用关了,只需要知道是数字与数字之间异或就可了,
然后多个字符,一个长传之间进行异或,会对应位进行异或,然后然后将异或之后的结果拼接成为一个新的大长串。
${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
//${_GET}{%ff}();&%ff=phpinfo
按两块异或会出 _GET
这个东西。
能够接收,毕竟异或就是用不可见字符相异或表示出我们想要的字符串么,
然后为了传输,就进行一下url编码,便于传输和识别,
${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
//${_GET}{%ff}();&%ff=phpinfo
这里找到了一个对上述的解释:
这里用到的关键符号就是^
,用到的方法是利用不可见字符的异或来构造_GET
对函数进行调用,首先是获取_GET
的ascii码值
然后使用0xff
分别对这几个字符进行异或操作
.。疑问??为什么 费用 这个东西进行异或操作啊,
得到了字符串0xa0b8baab
(均为不可见字符),将其与0xffffffff
进行异或操作,就变成了_GET
了,所以payload为:
?_=${%ffffffff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
迷迷瞪瞪地
到这里我明白一些了,,,
url编码也是16进制的,所以0xff 进行urlencode之后,%ff,就是了
10进制异或可以,16进制异或也行,所以我们看到都是16进制进行异或的时候,都是用0xff
,这个东西就是10进制的255
,我也不知道为什么非用这个,
code=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
code=${_GET}{phpinfo}(); -> code=$_GET{phpinfo}()
因为url也是16进制编码的,而且
a^b^b = a
所以下面的这个%a0%b8%ba%ab
就是0xa0xb80xba0xab
,连在一起就是0xa0b8baab
。16进制的a0 b8 ba ab
对应的就是10进制的95 71 69 84
和0xff
相^
出来的,, 然后,,95 71 69 84
对应的也就是_ G E T
也就是_GET
每个字母都和0xff
或者叫%ff
或者叫255
相异或,变成0xa0xb80xba0xab
。进行bypass。然后,再次与%ff
进行异或,就变成了_GET
。就达成目的了,
那么至于为何1-255,非选择 0xff
,,,癖好吧可能,,
取反~
的话,跟异或没半毛钱关系,只是恰巧都是url编码,很像罢了,
上面这句话错了,,异或和取反有联系的,看下面,
最后,我已经可以手写异或了,,,
1. 单个字符 手写异或
求.
的异或bypass:
思路: 将.
转为10进制,然后与0xff
进行异或,得到的就是中间值,然后将中间值再与0xff
进行异或就得到了.
了。(16进制和10进制没区别,只是16进制便于再url中传输而已,)
2. 字符串手写异或:
比如_GET
就参考上面的就行了,
**思路:**单个字符手写异或,然后拼起来就好了,拼接的时候用url编码进行拼接,一个是一个,连在一起就行了
异或和取反的练习
取反就是 变成二进制,然后每一位取反,0变1,1变0 . 。
异或:1^1=0 , 1^0=1
。
字符串取反就相当于 每一个 char 每一个字符取反,然后拼起来,
然后字符取反,就相当于 它的ascii码与0xff
相异或,就是95^11111111
。8位二进制数,因为 一个字符用二进制表示就是8位二进制数么,
所以说一个字符串取反,等于 这个字符串每个字符和0xff
相异或然后拼起来是一样的。