1.简介

本篇主要是做一下笔记以遍日后使用,本篇目的是想在proxy窗口后面加一个小窗口显示解密后的数据。

注:本篇代码和图片不相关。

2.写代码

先看效果图,如下,多了一个小窗口显示解密后的数据:

丝丝.png
图片1.png

先贴代码吧,代码如下,

关键的几点的说一下吧:
1.要多一个窗口必须要写一个类继承 IMessageEditorTab ,并实现其中接口方法,

isEnabled() 方法返回true 才会显示出旁边的小窗口

setMessage() 我瞎说的,待求证:当选项卡可编辑时(例如,Repeater),可使用SetMessage更新请求

from burp import IBurpExtender
from burp import IMessageEditorTabFactory
from burp import IMessageEditorTab
from burp import IParameter
from burp import IHttpListener



class BurpExtender(IBurpExtender, IMessageEditorTabFactory, IHttpListener):

    #
    # implement IBurpExtender
    #

    def registerExtenderCallbacks(self, callbacks):
        # keep a reference to our callbacks object
        self._callbacks = callbacks

        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()

        # set our extension name
        callbacks.setExtensionName("Serialized input editor")

        # register ourselves as a message editor tab factory
        callbacks.registerMessageEditorTabFactory(self)
        callbacks.registerHttpListener(self)

    #
    # implement IMessageEditorTabFactory
    #

    def createNewInstance(self, controller, editable):
        # create a new instance of our custom editor tab
        return DeCryptTab(self, controller, editable)

    def processHttpMessage(self, toolFlag, messageIsRequest, currentRequest):
        if not messageIsRequest:
            return
        requestInfo = self._helpers.analyzeRequest(currentRequest.getRequest())
        headers = requestInfo.getHeaders()
        newHeaders = list(headers)
        print(newHeaders)
#
# class implementing IMessageEditorTab
#


class DeCryptTab(IMessageEditorTab):
    def __init__(self, extender, controller, editable):
        self._extender = extender
        self._editable = editable
        self.content = ''
        self._key = ''

        # create an instance of Burp's text editor, to display our deserialized data
        self._txtInput = extender._callbacks.createTextEditor()
        self._txtInput.setEditable(editable)

    #
    # implement IMessageEditorTab
    #

    def getTabCaption(self):
        return "Serialized input"

    def getUiComponent(self):
        return self._txtInput.getComponent()

    def isEnabled(self, content, isRequest):
        # enable this tab for requests containing a data parameter
        # return isRequest and not self._extender._helpers.getRequestParameter(content, "data") is None
        if isRequest == True:
            requestResponseInfo = self._extender._helpers.analyzeRequest(
                content)
        else:
            requestResponseInfo = self._extender._helpers.analyzeResponse(
                content)
        # variable "content" is <array.array> object
        body = content[requestResponseInfo.getBodyOffset():].tostring()
        self._txtInput.setText(body)
        return True

    # 设置显示在窗口中的消息
    def setMessage(self, content, isRequest):
        self._currentMessage = '123123123123123'

    def getMessage(self):

        self._currentMessage = '------------'

    def isModified(self):
        # return self._txtInput.isTextModified()
        return False

    def getSelectedData(self):
        # return self._txtInput.getSelectedText()
        return False


3.问题

3.1 插件里调用 Cryto会报错,因为运行的不是本地环境,需要使用java的方法
ImportError: No module named Crypto

如下代码所示,可以使用java的方法实现加解密(不过好麻烦啊)

import java.lang.String as javaString
from javax.crypto import *
from java.security import *
from javax.crypto.spec import *
from sun.misc import BASE64Encoder
from sun.misc import BASE64Decoder
#from com.sun.crypto import *
# replaces standard crypto provider by IBM's code
from com.ibm.crypto.provider import *
#decrypt
myencpwd = 'xxxxxxxxxx' # this is the encrypted input
pwd = "mypassword"
salt = "ABC123"
count = 32
Security.addProvider(Class.forName("com.ibm.crypto.provider.IBMJCE").newInstance())
pbeParamSpec = PBEParameterSpec(salt, count)
pbeKeySpec = PBEKeySpec(pwd)
keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
pbeKey = keyFac.generateSecret(pbeKeySpec);
dcipher = Cipher.getInstance("PBEWithMD5AndDES")
dcipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec)
dec = BASE64Decoder().decodeBuffer(myencpwd)
utf8 = dcipher.doFinal(dec)
decrypted = javaString(utf8, "UTF8")
printstr = decrypted.toString()
print printstr

3.2 数据的转换 (下面代码复制粘贴过来的,好像有点乱,不过这不重要)

def processHttpMessage(self, toolFlag, messageIsRequest, currentRequest):
    # only process requests
    if not messageIsRequest:
        return
    **requestInfo = self._helpers.analyzeRequest(currentRequest.getRequest())**  
    timestamp = datetime.now()
    print "Intercepting message at:", timestamp.isoformat()

    **headers = requestInfo.getHeaders()**
    newHeaders = list(headers)
    newHeaders.append("Timestamp: " + timestamp.isoformat())
    
    parameters = requestInfo.getParameters()
    for parameter in parameters:
        print "parameter:"
        print parameter.getName()
        if 'HEADER' in parameter.getName():
            newHeaders.append("via: " + parameter.getValue())
            testmario = self._helpers.removeParameter(currentRequest.getRequest(), parameter)
            currentRequest.setRequest(testmario)
            bodyBytes = currentRequest.getRequest()[requestInfo.getBodyOffset():]

            bodyStr = self._helpers.bytesToString(bodyBytes)
            newMsgBody = bodyStr + timestamp.isoformat()
            newMessage = self._helpers.buildHttpMessage(newHeaders, newMsgBody)

    print "Sending modified message:"
    print self._helpers.bytesToString(newMessage)
    currentRequest.setRequest(newMessage)
    return

另一个例子

def isEnabled(self, content, isRequest):
        # enable this tab for requests containing a data parameter
        # return isRequest and not self._extender._helpers.getRequestParameter(content, "data") is None
        if isRequest == True:
            requestResponseInfo = self._extender._helpers.analyzeRequest(
                content)
        else:
            requestResponseInfo = self._extender._helpers.analyzeResponse(
                content)
        # variable "content" is <array.array> object
        body = content[requestResponseInfo.getBodyOffset():].tostring()
        # self._txtInput.setText(d)
        return True

4.参考

官方的一些例子
https://github.com/PortSwigger
https://github.com/PortSwigger/burp-beautifier/blob/master/beautifier.py

官方的接口文档
https://portswigger.net/burp/extender/api/burp/package-summary.html

其它博主的的笔记
http://wp.blkstone.me/2018/10/write-burp-suite-extension-with-python-for-beginner/