Part1 前言
大家好,我是ABC_123。在前几周的攻防演习比赛过程中,收到了几个网友发来的Webshell文件或者内存马class文件,让我帮忙分析一下,这两天正好抽时间研究一下。在最近几年,很多红队人员早已对内存马部分代码进行层层加密及深度的加密混淆,推测是为了绕过RASP的防护。
注:为了防止泄露敏感信息,ABC_123将以下截图中的关键类名、关键字、特征都进行了重命名或者模糊化处理。
Part2 技术研究过程
从流量中抓取并还原出java攻击代码大致如下:通过Base64Utils可知,那一长串字符推测为base64加密,然后AESUtils是第2层解密算法。其中,AESUtils的具体实现代码我们不知道,但由于该方法只传了一个key值,可以大致推测出解密算法的具体实现。
如下图所示,手工编写一个AES解密方法,将上述代码中的base64密文经过AES算法解密,成功得到一个正常的序列化文件a666.ser,说明我们的解密方法写的是正确的。
接下来将a666.ser文件直接以文本格式打开,先大致看一下具体内容,其中一长串字符串很容易联想到是base64加密。
将上述加密字符串复制出来,使用base64解密之后发现是一堆乱码,一时间不知道错在哪里。
后续以16进制重新打开a666.ser这个序列化文件仔细查看,发现在v66vg前面其实还有一个可见字符y,16进制的79对应的就是小写字母y。
将字母y添加到刚才我们复制出来的加密字符的前面,以yv66vg开头,然后重新base64解码生成如下结果,推测应该是一个class文件。
接下来对class文件进行反编译,发现这个class文件进行了深度的加密混淆,首先看一下static静态初始代码块,结果发现全部代码都是加密混淆的,基本上是无法辨认的。
不着急,我们继续看这个加密混淆class文件其它方法的实现,看一下doFilter部分,大致可以看出来是一个filter型内存马。
接下来看 b(byte[] var1) 这个方法,大体看了一下,推测其可能是一个解密函数,于是重点对这个方法进行反混淆。手工通过IDE依据自己对代码的理解,挨个对类名、方法名、变量名进行重命名。
经过一系列重命名,上述加密混淆的代码改成了如下形式:很明显,如果想看到具体的代码实现,对于类似于 a(14933, -7719) 方法的解密是重中之重。
接下来需要我们自己编写java代码实现解密功能,将原有的static静态代码块改造为一个 static111 方法,放到java代码的最前面执行(这里因为经过测试,static方法里面对c和d这两个变量进行了一系列赋值,所以是必须的添加的),然后把a方法的代码也复制进去,最终输出a方法结果,发现结果是“java.util.Base64”。
然后将原有java代码的a方法的所有值进行替换,最终将decrypt(原有的方法名叫b)这个方法的代码,完全解混淆成功,如下图示:
使用同样的方法对doFilter内存马部分的代码进行反混淆,变成如下形式。
解混淆之后,发现hashMap对象传递了session、request、response三个对象,很明显是冰鞋内存马的特征,也可以推测该内存马是经过改造加密流量的冰蝎内存马。此外,当User-Agent设置为Mozilla/5.0 (Macintosh; Intel Windows NT************时,会走冰蝎Filter型内存马,因此这个user-agent就是流量的特征。通过流量设备筛选含有该特征的流量,即可得知攻击者具体做了哪些操作。至此,对于该内存马的分析工作就完成了。
Part3 总结
1. 很多红队制作内存马已经开始进行java代码混淆,而且越来越复杂,推测是为了绕过RASP。
2. 下一篇我会继续介绍一个更加复杂的内存马解密。
公众号专注于网络安全技术,包括安全咨询、APT事件分析、红队攻防、蓝队分析、渗透测试、代码审计等,99%原创,敬请关注。
Contact me: 0day123abc#gmail.com
(replace # with @)