🐏羊城杯2024 | Reverse_docCrack 题目链接:Reverse-docCrack 
一道很意外的逆向题目,打开一瞬间懵了一下。细细思考,之前有简单了解过宏病毒之类的。感觉是一道很有意思的题目,所以打算好好记录一下这道题。
记得之前LilRan师傅发过该篇的题解 ,qq空间往下滑一滑,发现之前有提到过类似的出题方法(VBA)(看来做的题实在是太少了——),果然光看师傅们的空间就能学到好多东西。
以下是学习笔记——
知识点: 参考文章——[VBA脚本文件重定向](VBA脚本文件重定向 (qq.com) )、[VBA隐藏技术stomping](VBA隐藏技术stomping (qq.com) ) 、[VBA脚本终章编译器崩溃](VBA脚本终章编译器崩溃 (qq.com) )
VBA宏代码 将Office文档中嵌入以VBA(Visual Basic for Applications)编写的宏代码脚本,当运行Office文档时,便可以执行各种命令。
VBA脚本文件重定向 为防止分析人员直接打开宏编辑器查看宏的源码,分析脚本功能,微软提供的工程加密工具仍能被替换脚本中的加密模块进行验证绕过,所以VBA脚本文件重定向对脚本默认文件vbaProject.bin进行替换,在打开文本时加载其他文件,增加分析者的分析复杂程度。
此处的脚本文件重定向,是将vbaProject.bin进行伪装,比如styIes.xmI(用大写i替换小写L),之后修改相关的三个文件以保证程序正常进行——
根目录的[Content_Types].xml: 
添加一个标签
1 <Default Extension="xmI" ContentType="application/vnd.ms-office.vbaProject"/> 
\word_rels文件夹的 
修改vbaProject.bin.rles文件的名字为styIes.xmI.rels
将document.xml.rels文件中Target指向改为styIes.xmI (都是大写i)
VBA隐藏技术stomping 脚本重定向技术无法绕过Microsoft OLE分析工具的检测。
stomping 可以破坏 Microsoft Office 文档中的 VBA 源代码,对Microsoft OLE分析工具进行欺骗,干扰其分析结果。
OLE分析工具 是通过搜索”Attribut”这个特征来定位宏的位置。
VBA二进制脚本文件中即包含了源码字符,又包含了P-Code,VBA中的P-Code,其本质是对源码字符的编译压缩,因此实现的功能是相同的,即VBA二进制脚本中存在两份功能一致的代码,只是存在的形式不同,而oletools不会去解析P-Code。
如果满足脚本编译环境和执行环境的VBA版本一致,可以修改源码部分,这样oletools解析的结果就是我们修改后的代码,而解释器依旧会执行旧代码
VBA编译器崩溃 当脚本编译环境和执行环境的VBA版本不一致,编译器无法打开。 或者在vbaProject.bin文件中,修改Module=后的值删除,(保留换行符0x0D,0x0A),后面信息信息需要前移,也可以使编译器崩溃
修复崩溃 根据上文提到的方法反推,可以试着修复VBA文件,查看崩溃原因是否是由Module信息的缺失引起的,如果是该原因,修复该处缺失的信息。
常规OFFICE文档文件中,在word目录下的vbaData.xml文件中含有模块信息。
在[b773fa65bb375e6fe6d387f301f6bf33219189ea1d4a06762e965a9eba7de4e8]中,vbaData.xml文件被重定位到iuM.dsn,因此我们打开iuM.dsn。
我们可以看到wne:name=”Project.Module1.AutoOpen”,其中Project代表Project流,Module1是Module的名字,等于同我们自己生成文件的NewMacros,后门AutoOpen是函数名。
打开EbDYTPZ[.]vEypm文件,通过特征”/&H00000000“特征定位Module,可以发现该处并没有Module模块,确定攻击者将该字段抹除。
因此修复该文件需要Module的信息重新编辑进去,其余信息后移。
修复完脚本文件后,重新将文档文件打包,修改后缀,然后打开word,点击的编译器编辑按钮,发现VBA脚本编译器可以正常打开。
总结 VBA编译器崩溃技术与stomping和重定向技术没有冲突,三者可以相互组合使用,互补每个技术中存在的缺陷,
回到这个题目 (启用宏——)
拆开包发现没有重定向、运行宏文件也没有报错,直接用 oletools 反编译 P-code——
1 2 pip install -U oletools[full] olevba -c protected_secret.docm > code.vbs 
代码出来了
看看主要代码——
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 Result = ""          For  i = 1  To  Len (inflag)             res = Chr (Asc (Mid (inflag, i, 1 )) Xor  7 )             Result = Result & res         Next  i  xpkdb = dWPtWzWvKrZRFrsAWZMGNjZQbCrgAImKXVUkOykXWeRltpUU + AMaKeZzlhAtdNANKAKwMNbKEKUWuQVZQbbCJIUog + BvEKpalonhsRIgbPkYPYbsbQGzIzvPitapncgtGKIo + yBILPYnXCUApVHExOtpKlnfTkVfexwgrFQOFIveA + pqdgalQAZJKIDySPundFqdITahrgAYveJXfZCOUHWnUDKXZwZU + pErQJcjFIvYQeIehtTPMaOgEwFvvjnaTkabtJDvpHbWG + QmLHKhwBebnYaryyPsFeBassnVEjIoURcqNseXyjyMdcDfFnag tempPath = ThisDocument.Path & "\temp1"          Set  tempfile = fso.CreateTextFile(tempPath, True )         fso.GetFile(tempPath).Attributes = 2          tempfile.WriteLine xpkdb         tempfile.Close                  batPath = ThisDocument.Path & "\temp.bat"          Set  batFile = fso.CreateTextFile(batPath, True )         fso.GetFile(batPath).Attributes = 2          batFile.WriteLine "@echo off"          batFile.WriteLine "cd /d "  & ThisDocument.Path         batFile.WriteLine "certutil -decode temp1 temp|certutil -decode temp temp.exe"          batFile.WriteLine "del temp"          batFile.WriteLine "temp.exe "  & """"  & Result & """"          batFile.WriteLine "del temp.exe"          batFile.Close         Set  objExec = objShell.Exec(batPath)         Set  objStdOut = objExec.StdOut         Do  While  Not  objStdOut.AtEndOfStream             output = Trim (objStdOut.ReadLine)         Loop          output = Left (output, Len (output))         StartTime = Timer         Do  While  Timer < StartTime + 1              DoEvents         Loop          fso.DeleteFile batPath         fso.DeleteFile tempPath              If  output = "good"  Then              temp = MsgBox ("good!!!" , , "congratulations!!!" )             Exit  Do          Else              temp = MsgBox ("Sorry, U are wrong!!!" , , "Hacked_by_??????" )             isContinue = MsgBox ("Continue?" , vbYesNo + vbQuestion, "Warning" )         End  If      Loop  While  isContinue = 6  
flag每位异或7
temp1为两次base64加密后的文件,temp.bat为验证后保存结果的文件
断点下了,但是跑不起来,直接抠出来——
1 2 3 4 5 6 7 xpkdb = dWPtWzWvKrZRFrsAWZMGNjZQbCrgAImKXVUkOykXWeRltpUU + AMaKeZzlhAtdNANKAKwMNbKEKUWuQVZQbbCJIUog + BvEKpalonhsRIgbPkYPYbsbQGzIzvPitapncgtGKIo + yBILPYnXCUApVHExOtpKlnfTkVfexwgrFQOFIveA + pqdgalQAZJKIDySPundFqdITahrgAYveJXfZCOUHWnUDKXZwZU + pErQJcjFIvYQeIehtTPMaOgEwFvvjnaTkabtJDvpHbWG + QmLHKhwBebnYaryyPsFeBassnVEjIoURcqNseXyjyMdcDfFnag exe = "123.txt"  with  open (exe, "w" ) as  file:    file.write(xpkdb) 
解码——
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 v7 = [0 ]*54  v7[0 ] = 4288  v7[1 ] = 4480  v7[2 ] = 5376  v7[3 ] = 4352  v7[4 ] = 5312  v7[5 ] = 4160  v7[6 ] = 7936  v7[7 ] = 5184  v7[8 ] = 6464  v7[9 ] = 6528  v7[10 ] = 5632  v7[11 ] = 3456  v7[12 ] = 7424  v7[13 ] = 5632  v7[14 ] = 6336  v7[15 ] = 6528  v7[16 ] = 6720  v7[17 ] = 6144  v7[18 ] = 6272  v7[19 ] = 7488  v7[20 ] = 6656  v7[21 ] = 7296  v7[22 ] = 7424  v7[23 ] = 2432  v7[24 ] = 2432  v7[25 ] = 2432  v7[26 ] = 5632  v7[27 ] = 4416  v7[28 ] = 3456  v7[29 ] = 7168  v7[30 ] = 6528  v7[31 ] = 7488  v7[32 ] = 6272  v7[33 ] = 5632  v7[34 ] = 3520  v7[35 ] = 6208  v7[36 ] = 5632  v7[37 ] = 4736  v7[38 ] = 6528  v7[39 ] = 6400  v7[40 ] = 7488  v7[41 ] = 3520  v7[42 ] = 5632  v7[43 ] = 5184  v7[44 ] = 3456  v7[45 ] = 7488  v7[46 ] = 7296  v7[47 ] = 3200  v7[48 ] = 6272  v7[49 ] = 7424  v7[50 ] = 2432  v7[51 ] = 2432  v7[52 ] = 2432  v7[53 ] = 7808  flag = ''  for  i in  range (54 ):    flag += chr (v7[i] >> 6  ^ 7 ) print (flag)
后记 一瞬觉得做的题太少了,怎么这个时候才发现这么好玩的题目
另一瞬觉得,现在了解到知道学到了,也是一件很幸福的事情——