[原创]从GO到Luajit——特殊GO语言APT样本引发的思考(二)
2022-7-28 20:39:0 Author: bbs.pediy.com(查看原文) 阅读量:9 收藏

[原创]从GO到Luajit——特殊GO语言APT样本引发的思考(二)

2022-7-28 20:39 7462

[原创]从GO到Luajit——特殊GO语言APT样本引发的思考(二)

原理与思考请参见 第一章,本文为详细的样本分析,且较为偏向初学者,会一步步详细的说明,如有错误请轻喷。
样本HASH:cbef6bd78137deab082d39983cdb198f370330da410c5d29f65af2386b8c1b2d
由于涉及APT等原因不能直接提供样本,请自行寻找下载。

拿到样本后个人比较喜欢先上DIE查壳并确定语言类型,DIE下载链接
图片描述
看到这个结果还是比较奇怪的,虽然使用GCC的不少,但常见的还是VS这种编译器,我们上IDA看看他的虚实。
上了IDA,根据你的IDA版本可能会停在不同的地方,我测试的IDA7.7会自动识别到main函数(虽然被混淆了),但我们这里假设你停留在了Main Entry中,即下图这个函数里:

按照一般我们的经验来说,main函数一般在401170,我们点进这个函数,通过对参数的判别大致推测main函数在这里:

看到这就发现这个程序大概率是被混淆过的,我们点进去看看,然后就发现在代码最下部分有这样的特征:

根据经验这个样本是GO语言的样本,如果你不能确定这个是GO语言的话可以shift+f12看看字符串部分带有cgo的库:

知道了样本是带着混淆的go后我们就需要先做去混淆的操作,由于对go研究不多,使用IDAGolangHelper无果后只能想想其他的法子。正好看到了rizzo插件,想着用一下试试。于是写了个go语言的基本库调用,由于go要对所有导入的库实例化并调用,所以写完的代码基本长这样:

然后编译之后制作rizzo特征文件,导入特征文件到要分析的文件后就得到了去混淆后的程序,main函数代码如下:

根据本系列文章中第一部分提到的搜索go语言实际main函数的方法即可找到main位于下图位置:

4902a0与490050处功能注释是因为在两个函数里面都直接调用的go库,并不用详细分析,程序不长所以只打了个注释没有重命名。rc4库代码调用图:

不确定的话可以对程序进行调试,跑到490050函数运行完观察其输出即可。基本确定490050调用完成后实际只做了个rc4解密。调试并dump解密后的数据,基本如下图所示:

如果你对luajit的bytecode不是很熟悉的话,也可以通过整个程序的字符串或者导出表发现这个程序与luajit相关:

使用本系列一中提到的方法进行反编译,得到实际payload与本系列一中payload部分基本一致。其中的shellcode实际加载了一个pe文件,该PE文件会先释放一个PDF迷惑用户,然后开始执行cs马。cs马的识别与分析已有其他详细报告,在此不再分析。
释放pdf代码如下:

由于涉及APT后续CS马的通信部分就不再放出,有兴趣的可自行进行分析。rizzo具体的使用可参考其github中的介绍,体感上来说比起bindiff,我更喜欢使用rizzo,rizzo的模糊匹配相比bindiff更加能忽略掉编译器所导致的小区别,特别是这个区别位于函数的入口部分时更加明显。
本样本难度不高,但对于多种语言的熟练掌握有所要求,而且遇到luajit字节码这种不常见的东西更是要知道如何百度找答案,不然就会在cgo与luajit的调用中迷失。
同时也问下这种go去混淆有没有更好的方案?请大神指教下,谢谢

看雪2022 KCTF 秋季赛 防守篇规则,征题截止日期11月12日!(iPhone 14等你拿!)


文章来源: https://bbs.pediy.com/thread-273846.htm
如有侵权请联系:admin#unsafe.sh