自己使用burp进行测试的过程中遇到好些接口是有sign的,如果修改了请求参数都需要重新计算sign值,所以有用python实现过一个简单的插件,来自动计算sign值,以达到和普通接口测试一样方便的效果。
后来,好基友在做一个APP的测试的时候,发现有类似的问题,接口的所有参数都有使用AES加密,返回也是一样。他通过逆向获得了加密的算法,我们就通过如下的插件实现了自动加解密的过程。在整个过程中有一点点收获,现分享出来。
具体bug请移步:
Zealer_android客户端安全检测(从脱壳到burp自动加解密插件案例/SQL注入/逻辑漏洞/附AES加解密脚本POC)
代码
闲话少说,上代码,BurpExtender主类代码如下,进行了较为详细的注释。AES算法类的参考链接:
http://www.wenhq.com/Article/view_716.html
package burp;
import java.util.ArrayList;
import java.util.List;
import java.io.PrintWriter;
import java.net.URLEncoder;
import burp.AESOperator; //AES加解密算法的实现类
import burp.Util; //unicode解码的实现类
public classBurpExtender implements IBurpExtender, IHttpListener
{
privateIBurpExtenderCallbacks callbacks;
privateIExtensionHelpers helpers;
privatePrintWriter stdout;//用于输出,主要用于代码调试
// implement IBurpExtender
@Override
publicvoidregisterExtenderCallbacks(IBurpExtenderCallbacks callbacks)
{
stdout = new PrintWriter(callbacks.getStdout(), true);
//PrintWriter stdout = new PrintWriter(callbacks.getStdout(),true); 这种写法是定义变量和实例化一并进行,会覆盖之前的同名变量。
//stdout.println("testxx");
//System.out.println("test"); 不会输出到burp的
this.callbacks = callbacks;
helpers = callbacks.getHelpers();
callbacks.setExtensionName("AES encrypt Java edition");//插件名称
callbacks.registerHttpListener(this); //如果没有注册,下面的processHttpMessage方法是不会生效的。处理请求和响应包的插件,这是必要的。
}
@Override
publicvoidprocessHttpMessage(int toolFlag,boolean messageIsRequest,IHttpRequestResponsemessageInfo)
{
try{
List paraWhiteList = newArrayList(); //参数白名单,白名单中的参数值不进行加密计算
paraWhiteList.add("android");
if (toolFlag == 64 || toolFlag == 16 || toolFlag == 32 || toolFlag == 4){ //不同的toolflag代表了不同的burp组件。参考链接https://portswigger.net/burp/extender/api/constant-values.html#burp.IBurpExtenderCallbacks
if (messageIsRequest){ //对请求包进行处理
IRequestInfoanalyzeRequest= helpers.analyzeRequest(messageInfo); //对消息体进行解析
Listheaders= analyzeRequest.getHeaders();//获取http请求头的信息,返回可以看作是一个python中的列表,java中是叫泛型。
boolean isFileUploadRequest=false;
for (String header : headers){
//stdout.println(header);
if (header.toLowerCase().indexOf("content-type")!=-1&& header.toLowerCase().indexOf("boundary")!=-1){//通过http头中的内容判断这个请求是否是文件上传的请求。
isFileUploadRequest= true;
}
}
if (isFileUploadRequest== false){//对文件上传的请求,对其中的参数不做加密处理
int bodyOffset = analyzedResponse.getBodyOffset();