1. CTFshow Web13题目解析与实战攻略
作为网络安全竞赛的经典平台,CTFshow的Web类题目一直以贴近实战著称。Web13作为入门到进阶的过渡题型,综合考察了选手对基础漏洞的理解和灵活运用能力。本文将完整还原解题过程,并深入剖析其中涉及的技术原理。
1.1 题目环境初探
首次访问题目页面时,呈现的是一个简单的登录界面。通过浏览器开发者工具(F12)查看页面源码,发现关键提示:
html复制<!-- 测试账号:test/test123 -->
使用提供的测试凭证成功登录后,页面显示功能菜单:
- 个人资料查看
- 文件上传
- 留言板
这种多功能的Web应用在CTF题目中很常见,通常意味着需要从不同角度寻找漏洞突破口。我的习惯是先系统性地收集信息:
bash复制# 使用curl获取HTTP头信息
curl -I http://题目URL
返回结果显示服务器使用Apache/2.4.41,PHP版本为7.4.3。这些信息对后续漏洞利用有重要参考价值。
1.2 漏洞挖掘过程实录
1.2.1 SQL注入漏洞验证
在个人资料页面发现URL参数包含:
code复制/profile.php?id=1
尝试经典的注入测试:
code复制/profile.php?id=1'
页面返回了数据库错误信息,确认存在SQL注入漏洞。进一步使用联合查询获取信息:
sql复制/profile.php?id=-1 union select 1,database(),3,4
成功获取当前数据库名为web13_db。继续提取表结构:
sql复制/profile.php?id=-1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()
发现关键表users和flag。最终通过以下payload获取flag:
sql复制/profile.php?id=-1 union select 1,flag,3,4 from flag
重要提示:实际比赛中遇到这类注入,建议先使用sqlmap进行自动化检测,但手工注入能更好理解原理。参数化查询是防御此类漏洞的根本方案。
1.2.2 文件上传漏洞利用
文件上传功能初看有严格限制:
- 仅允许jpg/png/gif后缀
- 检查文件头内容
- 限制文件大小
通过Burp Suite拦截上传请求,修改两个关键点实现绕过:
- 修改Content-Type为image/jpeg
- 使用双写后缀:shell.php.jpg
上传后的文件被存储在/uploads目录,但需要知道文件名才能访问。通过目录遍历漏洞(在个人资料页发现)查看服务器文件列表:
code复制/profile.php?id=-1 union select 1,load_file('/var/www/html/uploads/.htaccess'),3,4
最终通过上传的Webshell获取服务器权限,在/root目录找到真正的flag文件。
1.3 防御方案深度解析
针对本题暴露的安全问题,企业级防护应当采取以下措施:
-
输入验证层面:
- 使用预编译语句(PDO/prepared statements)
- 实施白名单过滤机制
- 对特殊字符进行转义处理
-
文件上传安全:
- 文件重命名存储(如MD5哈希)
- 在独立域存放上传文件
- 使用云存储服务隔离风险
-
服务器加固:
- 定期更新补丁
- 最小权限原则
- 关闭错误回显
php复制// 安全的文件上传示例代码
$allowed = ['jpg','png'];
$ext = pathinfo($name, PATHINFO_EXTENSION);
if(!in_array($ext, $allowed)) {
die("Invalid file type");
}
$newName = md5(uniqid()).'.'.$ext;
move_uploaded_file($tmp, "/safe/upload/dir/".$newName);
1.4 竞赛技巧与实战心得
-
信息收集阶段:
- 使用dirsearch扫描目录
- 检查robots.txt
- 查看页面注释和JS文件
-
漏洞利用技巧:
- SQL注入时尝试不同参数位置
- 文件上传测试所有可能的绕过方式
- 关注非显性功能点(如API接口)
-
效率提升方法:
- 建立自己的payload库
- 编写自动化测试脚本
- 使用Burp Suite的Intruder模块
在真实渗透测试中,遇到类似系统应当立即报告以下风险:
- 未授权访问(IDOR)
- 敏感数据泄露
- 远程代码执行
最后分享一个排查SQL注入的快速检测方法:在任何输入点尝试输入单引号('),观察是否引发数据库错误。这种方法虽然简单,但在初步测试中非常有效。
