平时使用burp进行简单的测试,遇到各种各样的问题,使用各种各样的方法,我们可以抓包、改包、重放、爆破,同时有很多BApp Store有很多开源的扩展工具,今天我想要分享的是巧用一个名为“Extractor”的扩展插件和Burpsuite Marco的结合用法,获取他在你解决某些场景下的anti-token的问题时候可以有所帮助。
A Burp extension for generic extraction and reuse of data within HTTP requests and responses.
用于在HTTP请求和响应中进行提取和重用数据的Burp扩展。
Extractor的功能用上面的一句话完全概括了,请求响应数据的提取和请求中数据的替换重放使用,那么这个工具的功能到底有多强大,多复杂呢?
可以看到,扩展界面大致分为三大部分:
- 1:选择要插入替换数据的请求;
- 2:选择要提取数据的响应;
- 3:开启Debug;
- 4:Go!!!
Extractor使用方法就是从一个请求的相应中提取数据,再另一个http请求中重用,诸如:CSRF token、 timestamps(时间戳)、Auth Bearer token等某些场景中,通过使用正则提取数据,并且在burp发送指定请求时将提取出的值替换掉请求中的正则匹配到的值。
burpsuite自带的功能,宏这个功能应该都不陌生,之前已经有相关文章介绍Marco,如:“Burpsuite中宏的使用”一文。文章中详细的介绍了一般宏的录制以及使用,本文的宏只是涉及到最基础的用法,重点是在实际使用中的思路。
之前在测试某个接口的时候,发现有这样一个请求:
POST /WechatApp/public/zzbcd/P8009.do HTTP/1.1
Host:www.xxx.com
{"No":"123456"}
请求的返回中包含了如下信息:
{"STATUS":"1","No":"123456","tranDate","2018-8-9","ID":"411103199206121819","":"Name":"王刚","Phone":"13333333333","idType":"100000"}
这里传入的参数是一个规律递增的ID值,通过重放的方式,可以批量获取大量个人敏感的身份信息。问题不算太大,但绝不是可以忽略掉的问题。
修复方案是建议是防止重放攻击,并且模糊处理返回的敏感信息。几日后,收到复测的安排,遂进行复测。
修复后的接口请求如下,其添加了一个Token_Id值,用来防止重放攻击?
POST /WechatApp/public/zzbcd/P8009.do HTTP/1.1
Host:www.xxx.com
{"No":"123456","Token_Id":"N5EVWFXBEDFL51GMUQECPZF4A5X096HD20180809123129"}
重放之后提示“系统异常请稍后重试”,通过修改cookie参数中的值、refrer参数等方法,均无法绕过token_Id的检验。
重新查看proxy中的请求记录,发现在每次请求之前,会先发送一个请求,该请求返回包中,只有一个参数,即tokenId。如下所示:
到此,脑子里首先想到的就是刚刚提到的“Burpsuite中宏的使用”,于是仔细阅读了该篇文章的用法,并仔细的对本地复测的情况录制了宏,遗憾的是最终并未能够成功,可能原因有二三:
- 自己配置/使用不正确(自认为概率很小,因为请教了不同的大佬,并进行了多次尝试);
- 文章中示例使用DVWA搭建,具体到请求和场景和真实情况有所出入;
- 自己写了等效的脚本,一个函数请求并获取tokenId,另一个替换tokenId后发送请求获取信息,均已失败告终
看来,此处的问题真的是修复了吧……
当看到Extractor插件的时候,我决定重新在生产上复测这个当时存疑的接口。
首先,分别将两个接口发送到Extractor扩展。
可以在Extractor看到两个请求,上工作区选择“使用tokenId”的请求,下工作区选择“获取tokenId”的响应包,点击Go,Extractor就准备好了。
上图的中标注了四个点,解释一下:
- 1:开启Extractor;
- 2:最新正则匹配到的tokenId显示区域
- 3:设置host,可以直接使用burp scope中的host,也可以自定义host
- 4:左右两边,分别设置需要正则匹配的内容(此处左侧正则匹配要带如请求的tokenId,右侧表示正则匹配获取到的tokenId)
当 “Turn Extractor on”被开启后,Extractor即开始起作用。此时去Repeater进行重放,看是否Extractor已经生效,每次请求替换最新获取匹配的tokenId值,但是你会发现,可能会失败了。问题出在这里。
“Value to insert”值不为空才可以正常使用,需要先触发“获取tokenId”请求,之后Extractor才可以从相应中正则匹配到tokenId值,Extractor项目中的gif动画因为是简单的演示了功能,可能忽略掉他在使用时先触发了GET请求去get token。
所以此处我们如果想要进行爆破或者枚举的操作,必须每次请求前先请求一次“获取tokenId”,这样才可以达到枚举爆破的效果,So,是时候用Marco了。
这里的思路倒也简单,可以帮助理解burp在使用Marco(宏)的时候是怎样的一个逻辑,录制一个宏,什么条件都不需要附加,只需要保证在请求之前先把宏中设置的“获取tokenId”请求就可以。
注(这里的几点说明):
- Add添加一个规则Rule;
- 规则内容为“在请求之前,先运行一个Marco(宏)”;
- “Session Handling Rules”和“Marco”配合来用,前者配置一个规则,调用后者的内容;
- 通过在“Scope“中配置在哪个特殊请求或者全部请求需要触发宏,并且选择在哪些功能区触发之后,可以进行验证了。
下面是我在Repeater中连续点击多次之后的返回,如下所示:
之后可以Intruder可以进行爆破咯~,结果就是问题真的修复了,虽然解决了tokenId的问题,但是修复再其他位置也做了校验,所以突破了tokenId的限制,但是无法重放攻击做信息搜集之类的敏感操作。OK,到一段落。
PS: 一时手边没有真实有效的例子,之后再做补充真实过程。
整个过程中的逻辑流程,帮助理解整个绕过token校验的流程:
某微信公众号的注册接口
填写资料后提交请求,会发送短信通知返回结果。
POST /mina/saveCustomerInfo?applyId=2018080916437317 HTTP/1.1
Host: www.xxx.com
UserData(包含手机号码)
尝试直接重放请求,并且修改其他可能参数,均提示报错。
看起来是某个值做了校验或者cookie做了校验。重新查看proxy记录,整个过程包括两个请求,即分两个步骤完成,第一个请求获取名为"applyId"的值,第二个请求使用该参数进行提交用户填写的数据,成功提交。
POST /mina/apply HTTP/1.1
Host: www.xxx.com
UserData(包含手机号码)
POST /mina/saveCustomerInfo?applyId=2018080916437317 HTTP/1.1
Host: www.xxx.com
UserData(包含手机号码)
绕过的思路和操作已经很清晰,遵循上一个实例的套路:
这里需要注意勾选你要覆盖到的功能区域,否则Marco可能会发现没有生效。