作者:ADLab
CIA泄漏仍在持续发酵中,维基解密正在持续放出越来越多的资料来展示CIA武器库的威力。最近维基解密公布了CIA的代码混淆框架Marble,该框架通过选择的算法对代码中的字符串进行重新编码,用以增加代码的分析难度。这套代码不仅仅可以混淆英文字符串,还可以混淆包括中文、俄文、韩语、阿拉伯语等多种语言。
Marble由4部分组成:Mibster、Mender、Validator、Marbles,其中Marbles是加密算法池,程序会从其中众多算法中选择一种算法来对字符串进行加密。
Marble概述
Marble框架如下图,当一个项目想要用Marble进行混淆时,可以在编译该项目时对项目的预先生成事件和后期生成事件进行设置,在编译之前预先生成事件启动,会调用mibster从算法池中选择一种算法对项目中的字符串进行加工,并生成一个recepit供Validator程序进行验证,在项目编译好之后,后期生成事件启动,该事件会调用Mender来还原混淆的代码。当这一切做完之后可以使用Validator程序对生成的Binary进行验证。
Mibster的实现
首先我们来看整个框架最主要的程序Mibster,其主要流程为:
Mibster逻辑实现流程如下:
1选择算法
Mibster首先会通过函数“ChooseMarble”来从算法池中选择一种算法,在文件“Marble.h”中保存着算法的集合。文件“Marble.h”如下图共支持100多种算法:
函数“ChooseMarble”分为两种情况来选择算法。
函数“ChooseMarble”中算法选择逻辑如下:
在函数“ChooseMarble”中会判断局部变量“pChosenNode”是否被赋值,来判断有无自定义混淆算法。
在选择好混淆算法后通过调用函数“SetScrambler”来初始化算法类。在函数“SetScrambler”中通过字符串比较寻找要初始化的对象。如下图:
2生成混淆文件
算法初始化完成后调用函数“GenerateModifiedFiles”来生成混淆的文件。函数函数“GenerateModifiedFiles”首先会递归遍历目标文件夹(需要混淆的工程),然后寻找.c、.cpp和.h扩展名的文件。找到源码文件后调用函数“ProcessFile”对文件做混淆运算。具体流程如下:
如果在遍历过程中遇到了文件夹,则递归调用此函数。
如果是文件的话,观察其后缀名,程序的混淆对象是c和c++的工程,如果属于这种工程的代码,则进行混淆,并排除所有匹配“Marble.*”文件。
在找到符合规则的文件后调用函数“ProcessFile”对文件进行混淆。这个函数会搜索文件中所有包含“ARBLE”的关键字,来寻找要混淆的字符串。
关键字“ARBLE”其实是CIA自定义的一种数据类型的后缀。这个类型的声明在文件“Marble.h”中。
函数“ProcessFile”中寻找到关键字“ARBLE”后会判断关键字前面一个字符来判断是否是自定义的数据类型。只有自定义的“WARBLE”和“CARBLE”数据类型中的值才会被混淆,而“BARBLE”则未处理。
函数“ProcessFile”使用 “EDG”的库函数“MISCMemorySearch_NSS::FindIndexOfSequenceInMemory”来寻找关键字。
当在被混淆程序的代码中找到一个需要被混淆的字符串定义后,就将这个字符串加入到一个待混淆字符串列表中,并继续寻找下一个待混淆字符串。
同时,我们还会对被混淆的源文件生成一个后缀名为.Marble的副本用于后续处理。
之后,对待混淆字符串列表做循环。
While循环中首先定位每个待混淆字符串的内容并赋值给pNode。
接着程序会根据开始选择的算法对字符串进行加密处理,并将其保存到一块临时内存中。
当没有需要加密的字符串时,再将这块临时内存写回文件。
这就是整个混淆文件生成过程。加密前后数据对比。混淆前:
混淆后:
混淆后的文件中写入了反混淆算法和密钥,使用这个字符串时会通过解密算法还原出字符串的内容然后再使用。
3生成报告
当所有的混淆工作都完成后会使用函数“GenerateReceipt”生成xml格式的混淆报告。这个文件保存在设置的输出目录中,文件名为“MarbleReceipt.xml”。
在这个文件中记录了混淆的算法、被混淆的文件和被混淆的字符串等信息。
Mender和Validator
Mender程序是专门用于将混淆后的源代码还原用的程序,该程序在还原过程中使用到了mibster生成的*.Marble文件,其做法是遍历被混淆的目标工程文件夹,当遇到*.Marble文件时,就将其中的全部内容拷贝给相应的被混淆的文件。
Validator是Marble框架中用来检测混淆是否被正确使用的程序,该程序用mibster产生的receipt来验证混淆的字符串是否正确的被生成到Binary中。其过程也并不复杂,首先通过msxml16库来读取receipt中的信息(主要是OriginalHex,即被混淆的字符串的hex信息),并将其处理后赋值给描述字符串的节点中并链入链表。
接着读取生成的文件,并循环遍历字符串链表,看链表中的每一条字符串是否都出现在了生成文件中。
总结
CIA的“Marble”只是静态的对指定字符串做了简单的混淆,在研究人员做静态分析的时候会加大分析人员的工作量。在动态分析的时候由于会调用解密函数所以作用不是很大。虽然算法池中算法很多,但是加密强度不高,调用解密函数可以较容易还原出原文。