您的位置:首页 > 产品设计 > UI/UE

Burpsuite插件开发之RSA加解密

2016-01-06 17:52 423 查看




burpsuite是一款非常好用的抓包工具,我自己也是重度用户,所以就上手了burpsuite的插件接口开发,本文主要记录了一个解密请求包,插入payload,再加密的插件开发过程,插件应用场景主要是用于通过分析apk的实现。这里做探讨的目的只是方便安全测试人员的个人学习,或大家渗透测试使用。

详细的代码见github代码,在文档中数据首先是以rsa方式加密des的key得到encryptKey,然后使用des的key加密数据包得到data,再组装成一个JSON格式串,这是加密过程,当然解密过程就是逆向的。插件应用场景主要是用于通过分析apk的实现,或者泄露的密钥,获取其加解密算法,在解密后的数据包中插入payload,发现注入问题等。

如下则是加密后的数据包:

c={

"data":"21BhviedgtbwK6rdlK7vzltqxOLxUmU2g5qaO5LWPYTha5fXslmL6jrMkFnJBwpZPZMNl5foxTUHw2Mae++zkWwtzWkKXI9WJ/CJqxO9uORT5I6iUmIG7bBcgnHpmlSNKfFwBvnr9vj3v5ByvW2s2/pL9rSaeD+/8XsX01NA96mC4g5pVBeU5IY9F4tdxH9yobXfN6GzEVhLeiEd30xzMA\u003d\u003d",

"encryptKey":"bjWZgigAW/ZaAA55v7Yi9AGt2qsP7BfZZISu70qc/xVUVfh5L/Mw/mMbzxkcZ6uXb1vvgXvF7hHYwjsVzvEkRK0rIfIwkcYzn160fvQ/8+F8YBMDLzTEhf8r0KjOLlJV+HgOsS4QG/G9lOU5mnupfrVA9sf54b3OvXHU0TQVG7U\u003d"

}


从数据库包能看到大的数据是一个json格式,里面有data,和encryptKey值,encryptKey就是使用RSA加密des 的key得到的,RSA的工作方式和pem文件可通过界面设置,再接着用这个key采用des方式解密data中的内容。操作界面如下:




burp_rsa

2,InsertPoint 接口

InsertPoint顾名思义就是注入点,就是payload插入的地方,比如request中的cookie,参数等位置。为了对一些burpsuite不支持的参数格式进行支持就必须实现该接口,可以用在Active Scanner和Intruder中.

2.1 基础开发知识

最好的方式就是在原有插件的基础上修改,这样能省很多精力,当然如果要一步一步来的话,步骤如下:

(1)包含burp的接口文件

(2)创建一个包名为burp,在里面创建BurpExtender类,实现IBurpExtender接口,这个BurpExtender类是所有接口的心脏,注意这里涉及到名字都不能改动,burp插件就这么规定的。

(3)实现唯一的接口函数

public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) {

this. callbacks = callbacks ;

}


通过callbacks获取核心基础库能力,像日志,请求,返回值修改等。

(4)日志接口

PrintWriter stdout = new PrintWriter(callbacks.getStdout(), true);

PrintWriter stderr = new PrintWriter(callbacks.getStderr(), true);

//输出到插件的output

stdout.println("Hello output");

// 输出到alerts tab

callbacks.issueAlert("Hello alerts");

//打印调用栈

e.printStackTrace(stderr)


有了这些日志接口就能比较好的调试代码了,如果要很好的跟踪请求的,可以在BApp Store中添加”Custom Logger”这个插件,能够记录所有的请求和返回信息。

2.2 getInsertionPoints

下面我们就来讲讲如何实现一个
InsertionPoints
接口。第一步继承
IScannerInsertionPointProvider
接口,实现getInsertionPoints()方法,同时通过
callbacks.registerScannerInsertionPointProvider(this)
方法注册成为insertion point provider。下面我们就来看看
getInsertionPoints()
的实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

@Override

publicList<IScannerInsertionPoint>getInsertionPoints
(IHttpRequestResponse
baseRequestResponse){
// 生成insertPoints数组  
List<IScannerInsertionPoint>insertionPoints
= newArrayList<IScannerInsertionPoint>();//
获取请求参数

IRequestInfo requestInfo=
helpers.analyzeRequest(baseRequestResponse.getRequest());  
List<IParameter>requestParams
= requestInfo.getParameters();

 
    for(IParameter
parameter:
requestParams){

        Stringvalue
=parameter.getValue();
        value=
helpers.urlDecode(value).trim();

        EncryptBean encryptBean=
newEncryptBean();
        if(parameter.getName().trim().equals("c")){//参数中含有c参数表示要加密的内容

            encryptBean=
JSON.parseObject(value,EncryptBean.class);
            stdout.println("private
key: " +key.privateKey+
" public key "+
key.publicKey);

            try{
                value=
decryptRSAAndDES(key,encryptBean);

                stdout.println("after decrypted:Will scan  data at parameter "+
parameter+
" with value decrypted "+
value);
            }catch
(Exceptione){

                e.printStackTrace(stderr);
            }

            if(value.isEmpty())continue;
 

            try{
                Stringbasename
=parameter.getName();

                //insertionPoints.add(new InsertionPoint(this, baseRequestResponse.getRequest(), basename, value));
                JSONObjectjsonObj
=JSON.parseObject(value);

                Stringbasevalue
="";
                for(Map.Entry<String,Object>entry:jsonObj.entrySet()){

                    basename=
entry.getKey();
                    basevalue=
entry.getValue().toString();                    

                    //在这里传入总的value值以便在InsertionPoint进行分解,构造加密后的request请求,构造InsertionPoint时传入的value为总的value值
                    insertionPoints.add(0,newInsertionPoint(this,baseRequestResponse.getRequest(),basename,value));

                    stdout.println("in for:Will scan AES encrypted data at parameter
" +basename
+" with value "
+ value);
                }

            }catch(Exceptione){
            }

        }
    }

    returninsertionPoints;
}

 

这一段代码的大体意思就是通过helper.analyzeRequest方法获取所有请求信息,遍历其中的参数信息,当发现参数名等于”c”时就会调用解密过程,这块的代码需要根据参数格式自定义解析参数过程。调用解密的过程大体就是先解析JSON格式,然后解密,得到解密数据的内容后调用

1
2

`newInsertionPoint(this,baseRequestResponse.getRequest(),basename,value)`

 

实例化一个注入点。一般情况下basename和value是一一对应的,如param1=phoneNum,但是这里我们basename传入param1,value值则是解密后的值如

1
2

`{"userid":"51ba27cb-514d-3d86-0000-2f7515a40613","task_id":"1450147269","param1":"000000000000000","m":"https"}`,

 

这么传递是为了方便实例化插入点。接着我们看下InsertionPoint的参数构造。

2.3 InsertionPoint

1
2
3
4
5
6
7

InsertionPoint(BurpExtendernewParent,byte[]baseRequest,String
basename,

                Stringbasevalue){

    this.parent=
newParent;this.baseRequest=
baseRequest;this.baseName=
basename;  

    //this.baseValue = basevalue;
    this.value=
basevalue;this.baseValue=
JSON.parseObject(basevalue).getString(basename);

}
 

在InsertionPoint的代码中有一个很重要的接口就是buildRequest,这个函数就是用来添加payload。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

@Override

public byte[]buildRequest(byte[]payload)
{

    StringpayloadPlain
=parent.helpers.bytesToString(payload);
    StringpayloadEncrypted
= "";

    StringtmpAESKey
="0123456789abcdef";
    parent.stdout.println("payloadPlain:"+
payloadPlain);

    parent.callbacks.issueAlert("payloadPlain:"+
payloadPlain);
    try{

        Map<String,String>map
=JSON.parseObject(this.value,new
TypeReference<Map<String,String>>(){}.getType());
        map.put(this.baseName,getBaseValue()+
payloadPlain);

        StringallPayloadPlain
= JSON.toJSONString(map);
        payloadEncrypted=
parent.encryptRSAAndDES(allPayloadPlain,tmpAESKey,parent.key);

    }catch(Exceptione){
        parent.callbacks.issueAlert(e.toString());

    }
    parent.stdout.println("Inserting
" +payloadPlain
+" ["
+payloadEncrypted
+ "] in parameter "+
baseName);

    // TODO: Only URL parameters, must change to support POST parameters, cookies, etc.
    //"c" 解密数据格式包一致

    returnparent.helpers.updateParameter(baseRequest,parent.helpers.buildParameter("c",payloadEncrypted,IParameter.PARAM_BODY));
}

 

这段代码就是获取payload,然后嵌入到解密后的请求包,然后将请求加密,最后调用updateParameter更新参数信息。在这里要注意
parent.helpers.buildParameter("c", payloadEncrypted, IParameter.PARAM_BODY)
c是body中的请求参数,和我们的数据格式对应,
IParameter.PARAM_BODY
这个参数则表明是Body中的请求参数,如果是URl中的则是
PARAM_URL


2.4 接口关系

知道了上述接口的作用,感觉还糊里糊涂的。那就是这些接口是怎么串起来的,数据包是如何流动的,下面我们来看下active scanning的流程。




burp-active-scan

ActiveScanner引擎从InsertionPoints Provider获取Insertion Points,然后调用BuildRequest发送Request,Requst再经过HttpListener的处理到达webServer。

参考文献:
http://drops.wooyun.org/papers/3962 http://2015.zeronights.ru/assets/files/42-Elkin-Bulatenko.pdf
https://github.com/lgrangeia/aesburp
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  解密 加密 插件 安全