突破短信双因素认证:一次银行渗透测试的深度剖析
在对一家大型银行基础设施(4000台主机,4500名用户)进行授权的黑盒渗透测试期间,发现了一个关键漏洞:个人账户门户中基于短信的双重身份验证(2FA)可被完全绕过。攻击者只要掌握受害者手机号码,即可全自动执行针对4位数字验证码的暴力破解攻击,且无任何速率限制,从而获得护照信息、应用历史记录以及用于欺诈交易的全部权限。
此权限允许攻击者通过客户支持渠道提交贷款申请、审批项目融资并确认付款,无需额外验证。10,000种可能组合可在数秒内被破解。
API与认证逻辑分析
登录流程依赖两个接口:
- 短信请求:
POST返回"repeat":180,3分钟内禁止重试。 - 验证码验证:
POST /api/*****/login,请求体为"{code":"0548","phone":"+7(111)222-22-22"}。
输入错误验证码返回HTTP 400状态码,提示“手机号或验证码错误”。正确验证码则返回HTTP 200,并携带会话Cookie(JSESSIONID、PHPSESSID)。系统未设置尝试次数统计、CAPTCHA、IP或会话封锁机制。每次请求独立处理。
POST /api/*****/login HTTP/1.1
Host: ****
Content-Type: application/json
{"code":"0548","phone":"+7(111) 222-22-22"}
JavaScript中的漏洞利用实现
PoC利用浏览器会话上下文绕过CORS和SameSite限制。核心循环通过20个线程并行执行暴力破解:
await fetch('https://roga_and_copyta/*****/api/*****/login', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({code: codeStr, phone: phone})
});
for (let i = 0; i < 20; i++) {
turboThread(i, start, end); // 验证码范围
}
if (response.status === 200) {
foundCode = codeStr;
// 自动填充字段
}
成功判定依据为返回HTTP 200状态码。类似脚本在Python中同样有效。攻击耗时仅35秒完成10,000次请求。
漏洞分类与根本原因
该缺陷符合CWE-307(过度认证尝试缺乏适当限制)。CVSS 3.1评分:9.1(严重)——网络环境、低复杂度、无需权限、无需用户交互。
关键设计失误:
- 可用性优先于安全:为避免用户因输入错误而抱怨,未设速率限制。
- 自动化盲区:4位数字对人类难记,但对脚本毫无难度。
- 未进行暴力破解测试:安全假设从未经过真实验证。
修复建议
构建纵深防御体系,应采取以下措施:
- 尝试次数限制:每码最多3–5次尝试,失败后重新发送短信。
- 连续2–3次失败后启用CAPTCHA。
- 使用6位验证码(100万种组合,暴力破解需数小时)。
- 异常行为监控:检测请求频率、IP信誉等。
- 按手机号与会话实施速率限制。
// 后端速率限制示例(伪代码)
if (attempts[phone] > 5) {
invalidateCode(phone);
requireCaptcha();
}
核心启示
- 绕过2FA即意味着完全控制账户:包括护照信息、各类申请记录、银行数据及支付确认权限。
- 无限制的4位验证码 = 10,000种组合,35秒内即可破解。
- CWE-307(CVSS 9.1):缺乏对自动化暴力破解的有效防护。
- 建议:强制设置尝试上限 + 引入CAPTCHA + 使用6位码 + 实时监控。
- 该漏洞在实际攻击前已通过渗透测试发现,所有问题均已修复。
— Editorial Team
暂无评论。