周杰伦 4/10/2023, 9:17:41 PM
文章分类 游戏基址 二进制漏洞 密码应用 智能设备 阅读数 : 616 阅读时长 : 5分钟
原理与思考请参见 ,本文为详细的样本分析,且较为偏向初学者,会一步步详细的说明,如有错误请轻喷。样本HASH:cbef6bd78137deab082d39983cdb198f370330da410c5d29f65af2386b8c1b2d由于涉及APT等原因不能直接提供样本,请自行寻找下载。
拿到样本后个人比较喜欢先上DIE查壳并确定语言类型,: 看到这个结果还是比较奇怪的,虽然使用GCC的不少,但常见的还是VS这种编译器,我们上IDA看看他的虚实。上了IDA,根据你的IDA版本可能会停在不同的地方,我测试的IDA7.7会自动识别到main函数(虽然被混淆了),但我们这里假设你停留在了Main Entry中,即下图这个函数里: 按照一般我们的经验来说,main函数一般在401170,我们点进这个函数,通过对参数的判别大致推测main函数在这里: 看到这就发现这个程序大概率是被混淆过的,我们点进去看看,然后就发现在代码最下部分有这样的特征: 根据经验这个样本是GO语言的样本,如果你不能确定这个是GO语言的话可以shift+f12看看字符串部分带有cgo的库:
知道了样本是带着混淆的go后我们就需要先做去混淆的操作,由于对go研究不多,使用IDAGolangHelper无果后只能想想其他的法子。正好看到了,想着用一下试试。于是写了个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去混淆有没有更好的方案?请大神指教下,谢谢
更多【从GO到Luajit——特殊GO语言APT样本引发的思考(二)】相关视频教程:www.yxfzedu.com