Part1 前言
大家好,我是ABC_123。一年一度的“大型攻防比赛”已经过去2、3个月了,在此期间陆续收到了多名网友发来的内存马样本,ABC_123一直在抽时间进行分析解密工作。现在很多的内存马都进行了加密混淆,而且一个比一个复杂;不禁感叹攻防都是相对的,道高一尺魔高一丈。对于内存马的解密分析,主要目的除了证明其是内存马代码之外,还要找到其流量特征,以备在安全设备中找到含有相应特征的流量,然后进行溯源分析,也可能发现完整的0day攻击链条。本篇文章中的内存马套了多层加密,ABC_123将完整解密过程分享给大家。
Part2 技术研究过程
样本首先是一个jsp的webshell,初始内容如下:大体看了一下,发现是通过java反射编写的,将三段字符串合并然后base64解密,然后再进行加载,这样做会有一个很好的免杀效果。
将上图中的三段字符串合并,然后base64解密得到如下xml形式的代码。
将yv66vg开头的字符串进行base64解密,会得到一个class文件,然后反编译可以得到java代码。
将得到的java代码放到IDEA里格式化查看,发现代码多达几千行,并且进行了深度的加密混淆,同时还掺杂了大量的无意义冗余代码和无意义的注释代码。
首先将代码中所有无用的调试输出代码冗余代码统一替换为空,如下图所示:
然后使用正则表达式,将所有的注释内容替换为空。
经过处理,代码行数由几千行变为800多行。经过大体分析查看,在这段加密混淆的java代码中,m63IIIIII方法被大量引用,所以对于该方法的解密是重中之重。
于是编写java代码,通过import引用这个加密混淆的内存马代码,然后将内存马代码的private属性都改为public属性,这样我们可以直接调用其m63IIIIII方法。如下图所示,这段m63IIIIII代码代表的含义是parseBase64Binary。
然后我们提取出所有的m63IIIIII方法值,通过java反射调用的方式将所有m63IIIIII方法的加密值输出。这样做的目的是,可以直观看到这段java代码实现了哪些功能。
然后进一步编写正则表达式,将原有加密混淆后的内存马java代码中的m63IIIIII的方法替换为解密后的值。
最终还原出java代码如下:经过初步反混淆后,java内存马代码看起来清楚了不少。
仔细重新分析分析代码,发现里面又套了一层加密文本。
接下来我们对上述H4sI开头的加密字符串进行base64与Gzip的解密,得到class文件后,反编译之后的java代码如下:代码进行了深度的代码混淆,有大量的冗余代码掺杂其中,接下来需要手工对代码报错的地方进行修复。
修复完成之后,代码不报错了。然后按照前面介绍的方法,将java代码中所有的注释内容和冗余代码清除。
此外还掺杂了大量的没有调用的方法,一并删除掉。最终经过一系列处理,java内存马代码由4000多行精简到到了300多行。
分析java内存马代码发现,大量的代码大量调用了m68IIIIIIIIIIIIII()方法,按照前面的方法,直接调用并解密得到如下字符串:
经过分析,发现其构造方法传入了以下几个关键值。
通过分析解密混淆的java代码发现,当header请求头“User-Agent”包含“.1.2.2”后,会走内存马webshell流程,至此流量特征找到!接下来可以按照这个特征去流量监控设备,或者从全流量设备中去溯源分析攻击者的行为。
Part3 总结
1. 内存马反编译的主要目的,还是为了找到内存马通信的流量特征,以备在流量监控设备中找到相应攻击者的流量,进行溯源分析。但是这方面的技术,很考验蓝队人员的代码功底。
2. 后续ABC_123会继续给大家分享Java内存马反编译的文章,敬请期待。
公众号专注于网络安全技术分享,包括APT事件分析、红队攻防、蓝队分析、渗透测试、代码审计等,每周一篇,99%原创,敬请关注。
Contact me: 0day123abc#gmail.com
(replace # with @)