Pikachu靶场通关笔记(4) — Token防爆破? (Burp递归提取实战)

21次阅读
没有评论

1. 疑问与原理解析

疑问:代码中使用了 set_token(),每次登录失败都会刷新 Token,并且验证逻辑是在后端进行的 (if($token == $_SESSION['token']))。既然 Token 是动态随机的,且每次只能用一次,为什么还能爆破?

原理 :确实,这种机制有效地防止了 多线程并发爆破 (因为 Token 是一次性的,线程 A 用了,线程 B 的就废了)。但是,它 无法防止单线程的递归爆破

因为服务器为了让正常用户能继续尝试登录,必须在 响应包(Response)的 HTML 表单中返回一个新的 Token:

<input type="hidden" name="token" value="s8798df7s98d7f98s7df..." />

攻击工具(如 Burp Suite)可以模拟浏览器的行为:“看一眼上次回包里的新 Token,把它填进这次的请求包里”

2. 渗透测试过程 (Burp 高级操作)

这一关不能用普通的 Intruder 模式,必须配置 递归提取 (Recursive Grep)

第一步:抓包与模式选择

  1. 随便输入账号 test、密码 test,抓包。
  2. 发送到 Intruder
  3. Attack Type (攻击模式):必须选择 Pitchfork (草叉模式)。
    • 为什么?因为需要同时控制两个变量:password(字典)和 token(上一包的返回值),且它们是一一对应的关系。
Pikachu 靶场通关笔记(4) — Token 防爆破? (Burp 递归提取实战)

第二步:设置变量位置

我们需要标记两个位置:

  • password 的值。
  • token 的值。

示例:password=§test§&token=§38649789...§

第三步:配置 Payload (重头戏)

Payload Set 1 (对应 password)

  • Type: Simple list
  • Load: 载入密码字典。
Pikachu 靶场通关笔记(4) — Token 防爆破? (Burp 递归提取实战)

Payload Set 2 (对应 token)

  • Type: 选择 Recursive Grep (递归 grep)。
  • 配置
    • 下面会让你选从哪里提取,现在先不管,去设置 Payload Setting。
    • 注意 :在 Payloads 界面下方,有一个 Initial payload for first request(第一次请求的初始 Payload), 这里必须手动填入你刚才抓包时那个原始 Token没有初始 Token,第 1 个包就会因为空 Token 报错,导致整个链条断裂。
Pikachu 靶场通关笔记(4) — Token 防爆破? (Burp 递归提取实战)

第四步:设置提取规则 (Settings 选项卡)

切到 Settings 选项卡,找到 Grep – Extract (Grep 提取) 区域。

  1. 勾选 Extract the following items from responses
  2. 点击 Add
  3. Burp 会弹出一个框,点击 Refetch response,去 Response 响应包里选。找到那行 <input type="hidden" name="token" value="..." />
  4. 选中 value 引号里面的那串 Token 字符串。
  5. Burp 会自动生成正则表达式。点击 OK。
  6. 回到 Payloads 选项卡,确认 Payload Set 2 已经自动关联了这个提取规则。
Pikachu 靶场通关笔记(4) — Token 防爆破? (Burp 递归提取实战)
Pikachu 靶场通关笔记(4) — Token 防爆破? (Burp 递归提取实战)

第五步:设置单线程 (至关重要!)

因为 Token 是一次一换的,第 2 个请求必须等第 1 个请求拿到 Token 才能发。

  1. Resource Pool (资源池) 选项卡中。
  2. 创建一个新的资源池。
  3. Maximum concurrent requests (最大并发请求数):设置为 1
    • 如果不设为 1,多线程会导致旧 Token 被抢占,爆破直接失败。
Pikachu 靶场通关笔记(4) — Token 防爆破? (Burp 递归提取实战)

第六步:开始攻击

点击 Start Attack。会发现攻击速度比以前慢(因为是单线程),但 Token 每次都在变,且每次都能成功绕过 Token 校验,看好对应关系,会发现下个包中的 token 值,就是上个包中的 token 返回值,直到爆破出正确密码。

Pikachu 靶场通关笔记(4) — Token 防爆破? (Burp 递归提取实战)

3. 代码审计

查看源码 bf_token.php

// 后端验证
if($token == $_SESSION['token']){// ... 验证账号密码 ...} else {$html.= '<p> csrf token error</p>';}

// 漏洞点:在验证结束后,生成了新的 Token,并且在后续的 HTML 中输出了。set_token(); 
// ...
<input type="hidden" name="token" value="<?php echo $_SESSION['token'];?>" />

结论
Token 机制本身主要用于防御 CSRF(跨站请求伪造),它的设计初衷并不是为了防御 暴力破解
虽然它客观上增加了爆破的难度(强制单线程,降低速度),但并没有从根本上解决暴力破解的问题。

4. 修复方案 (防爆破的正确姿势)

既然 Token 防不住,那怎么防爆破?

  1. 验证码:加一个图形验证码(Token 是机器看不见的,但验证码需要图像识别)。
  2. 账号锁定:连续失败 5 次,锁定账号 30 分钟。
  3. IP 风控:同一 IP 请求频率过高,直接封禁。
  4. 延时响应:每次失败后,sleep(2) 两秒再返回结果,拖慢爆破速度。
正文完
 0
评论(没有评论)