多因素认证(MFA)长期被视为账户安全的重要屏障,但攻击者已经发展出一整套绕过手段,使验证码不再是可靠终点。传统MFA面临的困境在于,它仍然依赖用户可以输入的凭证,而这些凭证在传输过程中可能被截获,或者通过疲劳攻击让用户主动批准。理解这些路径后,防御的关键不再是堆叠更多一次性密码,而是引入无法被在线转发的证明机制,并配合持续风险判断。

一、梳理主要MFA绕过攻击路径
MFA绕过最常见的形式是实时中间人代理。攻击者部署类似Evilginx的反向代理,向用户展示伪造登录页面,用户输入的账号密码和TOTP验证码会被代理原样转发给真实站点。攻击者并不需要破解验证码算法,只需要在用户与真实站点之间充当透明转发器。认证成功后,反向代理窃取真实站点返回的会话Cookie,完成账号接管。因为攻击全程使用真实站点的证书和接口,普通用户难以察觉域名差异,基于TOTP的一次性密码在这种场景下完全失效。
另一种高成功率方式是MFA疲劳攻击,也称推送轰炸。当账户启用推送通知验证时,攻击者在已知密码的情况下反复向目标手机发送批准请求。部分用户为停止通知轰炸而误点批准,或因操作习惯不加确认。攻击者还可能伪装成IT支持人员,要求用户在通话中完成批准。推送通知本身缺乏上下文判断,如果用户只看到简单的“批准登录”按钮,很容易被诱导。防御此类攻击需要改变验证方式,让批准动作附带身份设备的验证,并限制连续失败请求。
此外,会话令牌劫持同样能够绕过MFA。攻击者通过恶意软件、浏览器扩展或网络中间人获取已认证的会话Cookie、Bearer Token或刷新令牌。由于这些令牌代表已经完成的认证状态,后续请求不再触发MFA。如果服务端没有绑定浏览器指纹、网络位置或设备标识,攻击者可以长时间静默操作。更有隐蔽做法是用OAuth授权令牌接管应用权限,表面上无需重新登录。因此,MFA防御必须延伸到认证之后的会话生命周期。
二、从可转发凭证转向防钓鱼凭据
TOTP和SMS验证码的共同缺陷是没有验证交易上下文。一个六位数字既可以被用户输入真实页面,也可以被输入攻击者的伪造页面,然后由代理转发。即便引入推送通知,如果没有展示登录来源和设备信息,用户仍可能误判。真正具备防钓鱼能力的是FIDO2/WebAuthn体系,其中浏览器会校验凭据对应的relying party origin,私钥只能在硬件安全密钥或平台TPM中签名挑战。攻击者即使搭建了反向代理,也无法让浏览器为伪造站点产生有效签名。
在WebAuthn注册过程中,服务端生成一个随机挑战,浏览器调用本地验证器创建非对称密钥对。公钥返回服务端保存,私钥永远不会离开验证器。认证时,服务端再生成挑战,验证器对包含挑战和relying party ID的数据进行签名。由于签名绑定origin,攻击者的代理站点无法获得正确的relying party ID,也就无法让验证器为其签名。下方代码给出浏览器端创建凭证的基本结构。
const credential = await navigator.credentials.create({
publicKey: {
challenge: new Uint8Array(serverChallenge),
rp: { name: 'Example Corp', id: 'ipipp.com' },
user: { id: new Uint8Array(userId), name: 'user@ipipp.com', displayName: 'User' },
pubKeyCredParams: [{ alg: -7, type: 'public-key' }],
authenticatorSelection: { authenticatorAttachment: 'cross-platform' }
}
});
企业如果尚未全面部署硬件密钥,可以采用阶梯策略:高风险用户或管理员强制使用硬件安全密钥,普通用户使用Passkey或TOTP。服务端必须限制TOTP验证码的有效期,例如30秒窗口只允许一次尝试,并绑定注册时的设备指纹。对于推送通知,批准页面应显示登录请求的IP地址、地理位置、设备类型和应用名称,甚至要求用户输入一次性数字,避免无意识批准。与此同时,使用证书绑定可以进一步压缩代理攻击空间。服务端可以监测TLS指纹、HTTP头顺序和本地时钟偏移,识别经过反向代理转发的流量。
三、用风险评分与自动化响应建立纵深防线
MFA绕过不一定是纯技术对抗,更多时候是攻击者利用策略空白。防御体系应把每次登录视为风险事件,而不是简单的通过或拒绝。风险评分引擎可以从设备健康、网络位置、登录频率和历史行为等维度打分。例如设备不在历史记录中增加风险分,最近三次MFA被拒绝增加风险分,登录地址与时区与用户日常活动不匹配增加风险分。当总分超过阈值时,系统应触发二次验证或直接阻断,并自动撤销该用户已有会话,防止攻击者通过已有令牌继续活动。
def calculate_risk(ip, device_id, location, recent_mfa_failures):
risk = 0
if ip not in known_ips:
risk += 30
if device_id not in known_devices:
risk += 40
if location != usual_location:
risk += 25
if recent_mfa_failures >= 3:
risk += 50
return risk
if calculate_risk(...) >= 60:
block_login()
revoke_active_sessions()
notify_security_team()
针对MFA疲劳攻击,限制连续推送请求是关键。服务端可以设置同一用户五分钟内最多发送三次推送,拒绝超过两次后锁定账号并通知管理员。同时采用阶梯验证,当用户连续拒绝推送后,下一次登录必须改用硬件密钥或管理员审批。检测响应方面,安全团队应关注以下异常模式:同一会话令牌从两个不同国家短时间访问;大量推送拒绝后突然出现成功批准;同一设备短时间内尝试登录多个账户;TOTP验证码在同一IP上被重放。这些信号应集成到SIEM或身份日志平台,自动触发会话吊销和账户冻结。
纵深防御还需要降低令牌被劫持后的可利用时间。访问令牌和刷新令牌应尽量缩短有效期,并支持主动撤销。对于浏览器会话,绑定Secure、HttpOnly、SameSite属性,并记录User-Agent与IP范围变化。若检测到会话从陌生网络发起,应要求重新认证或通过硬件密钥完成step-up验证。多因素认证不是一次性身份证明,而应成为一个持续判断过程,结合设备状态、网络风险和行为变化动态调整信任等级。
总体来看,防御MFA绕过的核心在于减少可转发凭证的依赖,引入防钓鱼协议,并用风险驱动策略堵住会话阶段的漏洞。企业可以将硬件安全密钥用于关键入口,对普通登录启用条件访问,同时在身份基础设施中集中采集风险信号。只有把认证、会话管理和监控响应连成闭环,才能让MFA从被绕过的单点验证升级为难以突破的综合防线。