前言
一道涉及恶意宏的逆向题目,不算难。
知识点
关于OLE文件
office文档(如.doc、.ppt、.xls等)其实都是复合文档(OLE),该文件格式全称为OLE复合文档格式,它允许多个数据流和存储在单个文件中,这些数据流和存储可以包含文本、图形、表格、音频、视频、嵌入对象等。包括宏代码信息也是存储在OLE中的。
doc、docx、docm都是word文档的文件格式,doc是普通的OLE文档,而docx和docm是OLE文件格式的同时,本质上都是一个zip压缩包。其中docx和docm的区别在于docx没有嵌入宏功能,这使得 .docx 文件更为安全,避免了宏病毒的威胁。而.docm 文件支持嵌入宏,允许在文档中包含 VBA(Visual Basic for Applications)脚本,用于自动化任务和增强文档功能。这就导致docm文件可能包含潜在的安全风险。此次的题目附件是正是一个docm文件。
恶意宏是使用宏语言编写的恶意程序,存在于字处理文档、电子数据表格、数据库、演示文档等数据文件中,可以在office系列办公软件中运行,利用宏的功能将自己复制到其他数据文件中。宏病毒感染的是数据文件。宏病毒与传统的病毒有很大的不同,它不感染可执行文件,而是潜伏在Microsoft Office文档中,一旦用户打开含有宏的文档,其中的宏就会被执行。宏是使用VBA编写的。
这里我们已经知道最基本的了,docm文件可能嵌入了恶意宏,那如何去分析它呢。
oledump工具
oledump 是一款用于分析 OLE 文件的工具,主要用于提取和分析 Microsoft Office 文档中的OLE结构。oledump 可以列出所有的宏数据流,并允许你查看、提取和分析这些宏代码。可以从GitHub上下载。
常用的一些命令:
- 列出 OLE 文件中的数据流:
oledump.py example.doc
这将列出 OLE 文件 example.doc 中的所有数据流,每个数据流都有一个编号和名称。 - 查看特定数据流的内容:
oledump.py example.doc -s 8
这里的 -s 8 是指定查看编号为 8 的数据流的内容。通常,宏代码会在类似 Macro 或 VBA 命名的数据流中。 - 提取并保存数据流:
oledump.py example.doc -s 8 -v > macro_code.vba
这将提取编号为 8 的数据流,并将其内容保存到 macro_code.vba 文件中。
在使用oledump列出数据流时,如下:
在编号后会有大写的M即表示该数据流包含宏代码或与宏相关的内容。小写m同理,大小写的区别在于大写的是没有经过压缩的宏代码,小写则是经过压缩的,oledump在提取时会自动进行解压。
Microsoft Word也提供了对宏进行编辑的功能,但是就如同本题,你只能在文档内运行,而无法直接进行修改(会被要求输入密码)。
程序分析
文档打开:
弹窗和文字内容表明了该文档具有恶意宏。弹窗要求输入flag,错误接着尝试。
cmd中python oledump.py protected_secret.docm
继续 python oledump.py -s A3 -v protected_secret.docm >> sA3
直接将A3数据流的内容提取出来,用vscode打开(vscode代码好看点)
AutoOpen
函数,当文档打开时执行。分析代码,弹出消息框要求用户输入flag,之后将flag异或7,得到一个新的字符串result。
中间是一大堆数据。
到函数底部,这里创建了一个临时文件temp1,并将该文件属性设为隐藏,之后将xpkdb的内容写进该文件,应该就是上面的数据。
接着CreateTextFile
创建一个批处理文件 temp.bat。批处理文件就是用了Windows 自带的 certutil 工具来解码文件,生成了一个temp.exe文件并执行,传递的参数是flag异或7得到的字符串result。
之后执行批处理文件捕获输出,输出为good,即成功。
只要可以dump出temp.exe就算解出来了。因为原项目需要密码才能编辑宏,这里选择将AutoOpen
函数的内容全部复制出来,随便打开一个word文档。创建一个宏。
视图->宏->查看宏
输入一个宏名,创建。将代码复制进去。
下一个断点(右键->切换)
有一点,需要删除一行代码batFile.WriteLine "del temp.exe"
,这里意思是执行完批处理文件最后会删除temp.exe。将其删掉就能在C:\Users\Sciurdae\AppData\Roaming\Microsoft\Templates
中找到temp.exe了。
加密很简单,全部向右移六位。
解密脚本:
v9 = [
4288, 4480, 5376, 4352, 5312, 4160, 7936, 5184, 6464, 6528, 5632, 3456, 7424, 5632, 6336, 6528, 6720, 6144, 6272, 7488, 6656, 7296, 7424, 2432, 2432, 2432, 5632, 4416,3456, 7168, 6528, 7488, 6272, 5632, 3520, 6208, 5632, 4736, 6528, 6400, 7488, 3520, 5632, 5184, 3456, 7488, 7296, 3200, 6272, 7424, 2432, 2432, 2432, 7808
]
flag = []
for i in v9:
flag.append(chr((i>>6)^7))
print(''.join(flag))
在调试时,如果已经运行过,但再次调试却报错:
是因为目录下已经有一个同名文件了。解决方法只需要删除它,或者更改一下名称。