利用递归Grep测试每请求CSRF令牌保护的页面
David Fletcher // 红队成员,Web应用安全专家
跨站请求伪造(CSRF/XSRF)是一种攻击技术,攻击者利用受害用户身份在存在漏洞的Web应用上执行非授权操作。要实施CSRF攻击,攻击者必须能预先确定并提交执行目标操作所需的所有参数值。若条件满足,攻击者会通过社会工程学手段制作恶意URL,或在允许未过滤HTML输入的第三方网站上植入恶意表单。当目标用户执行攻击者提供的内容时,目标Web应用便会执行该操作。
为防御CSRF攻击,Web应用通常在敏感表单中使用反CSRF令牌。该令牌是在加载目标表单时生成的随机值,并在表单提交时进行验证。由于攻击者无法提前获知该值且必须提供有效值才能成功提交表单,因此正确实施此技术可有效阻止CSRF攻击。
部分反CSRF实现会在每次表单提交时更改令牌值。这种行为的副作用是,若不考虑令牌值,自动化测试几乎无法进行。本文将演示如何利用Burp Intruder的递归Grep有效载荷解决该问题。一旦理解递归Grep有效载荷的机制,它几乎可解决所有对先前服务器响应的依赖问题。
近期遇到的一个WebSphere门户便呈现上述行为。当任何表单提交至服务器时,后续响应中多个值会发生变化,导致Burp Repeater和Burp Intruder等自动化工具无法正常工作。服务器仅会重新加载包含新令牌值的空白表单作为响应。
为演示该问题,我创建了一个包含两个字段的ASP.NET Web表单。为简化流程,当前令牌值会显示在表单上。若提交的表单未包含正确令牌值,页面将显示“无效令牌值”;反之,提交的值将成功显示在页面上。
基础表单显示令牌值
令牌验证错误
成功提交表单
若未对令牌值进行补偿处理,使用Burp Intruder尝试篡改表单字段时将得到以下结果。这是因为令牌随每个请求变化并在表单提交时进行验证。由于值不匹配,所有请求均失败。
因无效令牌值导致的Intruder攻击失败
为适应响应中的令牌值,可使用Burp Intruder的递归Grep有效载荷。该有效载荷会根据先前的服务器响应构造参数并插入请求中。派生参数可来自响应中任意位置,且可根据需要添加多个递归Grep有效载荷。测试上述WebSphere门户时,存在三个随服务器响应变化的独立值。
使用递归Grep有效载荷需对标准Intruder攻击设置进行调整。上例中,我仅选择了txtFName参数,指定使用简单列表有效载荷的狙击攻击类型,并选择了默认Burp用户名列表。
使用递归Grep需选择Pitchfork或Cluster Bomb攻击类型。由于仅篡改一个参数,Pitchfork攻击更为合适。该攻击会在最短列表耗尽时停止。对于多个重要参数,此攻击将每个列表中的值视为元组处理。相反,Cluster Bomb攻击会测试每个列表生成的所有可能排列组合。具体设置如下图所示:目标字段(txtFName)和令牌(checkToken)被标识为有效载荷位置,攻击类型为Pitchfork。
带参数和令牌有效载荷位置的Intruder攻击设置
由于目标字段在请求中首先出现,我们选择简单列表作为有效载荷类型,并指定如前所述的Burp用户名列表。
简单列表有效载荷配置
第二个字段为checkToken值。此处我们需要递归Grep有效载荷,但首先需设置Grep位置。为此需导航至选项标签页并滚动至表单中的“Grep提取”位置。
Burp Intruder Grep提取
点击添加按钮以添加提取位置。在后续表单中,滚动HTTP响应主体并高亮CSRF令牌值。这标识了Burp将用于递归Grep有效载荷的先前响应中的位置。
Grep提取位置选择
为确保递归Grep正常工作,需在选项标签页进行最后调整。由于先前响应与当前请求存在直接关联,必须将线程数设置为1。
Burp Intruder攻击请求引擎选项
在代理上启用拦截后提交表单以捕获当前令牌值。这是填充递归Grep有效载荷所必需的,并将用于启动Intruder攻击。
拦截到的包含当前令牌值的POST请求
返回Burp Intruder攻击并选择有效载荷标签页。选择相应的有效载荷索引并选择递归Grep有效载荷类型。应能看到之前创建的Grep提取条目。选择该值并将当前令牌值粘贴至“初始有效载荷用于首请求”字段。
递归Grep有效载荷选项
所有选项设置完成后,最终可执行Intruder攻击。由于“checkToken”参数被选为篡改值,我们可在攻击中看到提交的值。此外,因需要Grep提取支持攻击,我们能看到先前表单提交返回的值。检查输出可见响应显示成功,“无效”一词不再出现于输出中,且令牌值按预期从响应传递至请求。
成功的Intruder攻击结果
若遇到类似行为,希望本文能提供价值。尽管递归Grep有效载荷对部分反CSRF行为有效,但它并非万能解决方案。
在同一WebSphere门户中,存在该功能无法处理的多步表单提交。这些表单涉及对同一位置的多重提交。每次提交都会生成需按顺序提交的新令牌值。一组令牌用于激活表单,下一组则用于提交。若缺少前者,页面仅会重新加载而不激活表单。
目前正在研究该问题的解决方案,并已启动Burp扩展程序开发。敬请关注后续文章中的相关功能……