概述
0x00前言
在使用Burp Suite(以下简称Burp)来开展渗透工作的途中可能需要验证一些脑洞大开的想法,但Burp自带的功能可能无法满足你的需求,于是你迫切需要一个高度定制化的插件来实现这个功能。经查阅你得知除了Java还可以通过配置扩展环境来运行由Python或者Ruby语言编写的Burp插件。不过关于语言的选择上,此前在也有详细的文章介绍过如何使用Java作为开发语言编写Burp插件。但各家各有所长并不是所有的同学都恰好掌握Java或者掌握多门编程语言,而现今正是Python盛行的天下所以我们决定再以Python语言做为开发基础在做一次分享。
( 注意多图警告!!!)
0x01环境准备
如果你已经安装上了Jython的话推荐你这么做,在Burp Suite中打开Extender -> Option -> Python Enviroment -> Select file 打开Jython的安装目录选择Jython.jar即可。未安装Jython的话按下文操作。
Jython下载地址: https://www.jython.org/download.html
在下载页面选择Jython Standalone 将jython的jar包下载下来备用,打开Burp Suite在Extender中选中Option,可以看到一个Python Environment的配置项,点击Select file 选中下载的jython-standalone-2.7.1.jar文件。
关于加载自定义插件的方式为 Extender -> Extensions -> Brup Extensions -> add (选中插件) -> Loaded 如果编写的插件有语法错误或者运行中发生错误可以在Errors标签中查看,输出内容可以在Output中查看 。
0x02接口介绍
本章节参考互联网公开资料,文章,以及官方接口文档等。给出实现Burp接口的Python代码Demo,由于时间及篇幅有限 不能对每个接口都进行长篇大论并给出相应实用的Demo,大部分Demo仅仅展示了该接口的某些属性以便读者在使用 时能够快速理解上手,避免接口不熟导致浪费大量时间。
●IBurpExtender
所有的插件都必须实现这个接口。实现接口的类名必须得是 BurpExtender,且需要实现以下方法:
/***
*此方法在Burp加载插件后由Burp调用,并传入一个IBurpExtenderCallbacks接口实例。
*/
void registerExtenderCallbacks(IBurpExtenderCallbacks callbaks)
● Demo:
from burp import IBurpExtender
class BurpExtender(IBurpExtender):
# burp在加载插件后该函数将有Burp自动调用,并传入一个IBurpExtenderCallbacks接口实例
def registerExtenderCallbacks(self, callbacks):
print("Hello Burp!")
Run Output:
● IBurpExtenderCallbacks
Burp使用这个接口将一组回调方法传递给插件,插件可以使用这些方法来执行Burp中的各种操作。加载插件时,Burp 调用registerExtenderCallbacks()方法并传递IBurpExtenderCallbacks接口实例。然后插件根据需求调用此接口的方法以 达到扩展Burp功能的需求。由于此接口提供的方法以及字段过多,请同学们移驾到 http://portswigger.net/burp/extende r/api/burp/IBurpExtenderCallbacks.html中查看。
from burp import *
class BurpExtender(IBurpExtender):
def registerExtenderCallbacks(self, callbacks):
#通过IBurpExtenderCallbacks实例可以设置当前插件的显示名称为Flying Pigs
callbacks.setExtensionName('Flying Pigs')
● Run Screenshot
● IContextMenuFactory
用户如果想在Context中添加自定义菜单的话可以通过调用注册方法,IBurpExtenderCallbacks.registerContextMenuFa ctory()之后在重写createMenuItems来达到添加自定义菜单的需求。
/***
*当用户在Burp内的任何地方调用Context菜单时,Burp将调用此方法。
*invocation-实现IContextMenuInvocation接口的实例,该实例可以获得Context调用的详细信息
*通过重写该方法你应该返回一个包含自定义菜单的list,如若不需要菜单应该返回null
*/
java.util.List<javax.swing.JMenuItem> createMenuItems(IContextMenuInvocation invocation)
Demo:
from burp import *
from javax.swing import JMenu
from javax.swing import JMenuItem
class BurpExtender(IBurpExtender, IContextMenuFactory):
def registerExtenderCallbacks(self, callbacks):
callbacks.setExtensionName('Flying Pigs')
#注册context
callbacks.registerContextMenuFactory(self)
def createMenuItems(self, invocation):
menus = []
#自定义菜单选项以及子菜单
mainMenu = JMenu("NewMenu")
subMenu = JMenuItem("subMenu")
mainMenu.add(subMenu)
menus.append(mainMenu)
return menus
●Run Screenshot
● IContextMenulnvocation
当Burp调用插件提供的带有Context菜单调用细节的IContextMenuFactory时,将使用此接口可以查询调用事件的详细信息,以便确定应该显示哪些菜单项。
//用于获取本地Java输入事件,并作为上下文菜单调用的触发器
java.awt.event.InputEvent getInputEvent()
//用于获取上下文中被调用的菜单
byte getInvocationContext()
//用于获取用户选中的Scanner问题的细节
IScanIssue[] getSelectedIssues()
//用于获取当前显示的或用户选中的HTTP请求/响应的细节
IHttpRequestResponse[] getSelectedMessages()
//用于获取用户所选的当前消息的界限(消息需可适用)
int[] getSelectionBounds()
//用于Burp工具的Flag标记
int getToolFlag()
●Demo:
from burp import *
from javax.swing import JMenu
from javax.swing import JMenuItem
class BurpExtender(IBurpExtender, IContextMenuFactory):
def registerExtenderCallbacks(self, callbacks):
callbacks.setExtensionName("IContextMenuInvocationDemo")
callbacks.registerContextMenuFactory(self)
def createMenuItems(self, invocation):
#通过getToolFlag()获取当前执行Context菜单的位置,如果是PROXY模块就显示自定义菜单
if(invocation.getToolFlag() == IBurpExtenderCallbacks.TOOL_PROXY):
Menu = JMenu("PROXY_TOOL")
return [Menu]
●Run Screenshot:
●ICookie
此接口用于获取HTTP cookie的内容
//获取 Cookie的域
java.lang.String getDomain()
//获取 Cookie的过期时间
java.util.Date getExpiration()
//获取 Cookie名称
java.lang.String getName()
//获取 Cookie的路径
java.lang.String getPath()
//获取 Cookie的值
java.lang.String getValue()
● Demo:
from burp import *
class BurpExtender(IBurpExtender, ICookie):
def registerExtenderCallbacks(self, callback):
#获取回话内容
cookies = callback.getCookieJarContents()
self.cookieInformation(cookies)
#获取会话cookie
def cookieInformation(self, c):
domain = c[0].getDomain() + ": "
for i in c:
domain += "{}={};".format(i.getName(), i.getValue())
print(domain)
●Run Output
● IExtensionHelpers
这个接口包含许多辅助方法,插件可以通过调用IBurpExtenderCallbacks.getHelpers获取该接口实例。由于该实例方法过多。本章只做简单举例,其余方法还请各位同学到官方文档中查看。
//base64编码
java.lang.String base64Encode(java.lang.String data)
●Demo:
from burp import *
class BurpExtender(IBurpExtender):
def registerExtenderCallbacks(self, callbacks):
#通过IBurpExtenderCallbacks实例获取IExtensionHelp实例
Helpers = callbacks.getHelpers()
e = Helpers.base64Encode('hello word')
print(e)
●Run Output:
●IExtensionStateListener
插件通过调用IBurpExtenderCallbacks.registerExtensionStateListener()注册一个插件状态监听器。当插件的状态发生改变时,监视器会接到通知。(注:任何启动后台线程或打开系统资源等操作如文件读写,数据库连接等。插件都应该注册一个监听器,并在在插件卸载后做善后处理工作)。
//此接口仅提供一个方法,是在插件卸载后调用此方法
void extensionUnloaded()
●Demo
from burp import *
class BurpExtender(IBurpExtender, IExtensionStateListener):
def registerExtenderCallbacks(self, callbacks):
#注册插件状态监听器
callbacks.registerExtensionStateListener(self)
#当监听器监听到插件被卸载后调用此方法,通过重写此方法在插件卸载后做善后处理工作
def extensionUnloaded(self):
print("Plugins Uninstall")
● IHttpListener
插件通过IBurpExtenderCallbacks.registerHttpListener()注册一个HTTP监听器。监听Burp内工具发起的HTTP请求或收到HTTP响应。插件提议通过该接口修改或者分析HTTP数据。
void processHttpMessage(int toolFlag,
boolean messageIsRequest,
IHttpRequestResponse messageInfo)
/***
* 参数说明
*
*toolFlag 发出请求的Burp工具标志.具体相关定义请看官方文档中IBurpExtenderCallbacks接口中的Field
*messageIsRequest 指示该值为请求消息(True)或响应消息(FALSE)
*messageInfo 要处理的请求/响应的详细信息,是一个IHttpRequestResponse实例
*/
●Demo:
from burp import *
class BurpExtender(IBurpExtender, IHttpListener):
def registerExtenderCallbacks(self, callbacks):
#注册Http监听器
callbacks.registerHttpListener(self)
def processHttpMessage(self, toolFlag, messageIsRequest, IHttpRequestResponse):
#得到Burp内工具标志位
print(toolFlag)
#如果消息是请求消息那么将得到 1,如果是响应消息那么将得到 0
print(messageIsRequest)
#一个IHttpRequestResponse实例
print(IHttpRequestResponse)
●Run Output:
● IHTTPRequestResponse
此接口用于检索和更新关于HTTP消息的详细信息。注意:setter方法通常只能在消息处理之前使用,而不能在只读上下文中使用。与响应细节相关的getter方法只能在发出请求后使用。
//获取请求信息(演示方法其余方法请到接口文档中查询)
byte[] getRequest()
● Demo:
from burp import *
class BurpExtender(IBurpExtender, IHttpListener):
def registerExtenderCallbacks(self, callbacks):
#注册一个Http监听器
callbacks.registerHttpListener(self)
def processHttpMessage(self, toolFlag, messageIsRequest, IHttpRequestResponse):
#获取HTTP请求 ,由于返回的是一个ascii码数组需要进行转码
req = IHttpRequestResponse.getRequest()
req = ''.join([chr(i) for i in req])
print(req)
●Run Output:
IHttpRequestResponsePersisted (该接口以过时)
IHttpRequestResponseWithMarkers
此接口是IHttpRequestResponse接口的一个子接口,用于那些被标记的 IHttpRequestResponse 对象,插件可以使用 IBurpExtenderCallbacks.applyMarkers() 创建一个IHttpRequestResponseWithMarkers实例。标记可用于各种情况,如指定Intruder 工具的 payload 位置,Scanner 工具的插入点或将 Scanner 工具的Issue设置高亮。
/*
* 以下两个方法均返回一个整型数组,这个数组包含了已定义标识的起始和结束的偏移量。
* 如果未定义标志将返回null
*/
//获取带有标记的请求的详细信息
java.util.List<int[]> getRequestMarkers()
//获取带有标记的响应的详细信息
java.util.List<int[]> getResponseMarkers()
●Demo:
from burp import *
from array import array
class BurpExtender(IBurpExtender, IHttpListener):
def registerExtenderCallbacks(self, callbacks):
self._callbacks = callbacks
callbacks.registerHttpListener(self)
def processHttpMessage(self, toolFlag, messageIsRequest, IHttpRequestResponse):
#通过IBurpExtenderCallbacks.applyMarkers()创建一个IHttpRequestResponseWithMarkers实例
#并设置requestMarkers [5,9] responseMarkers [0,3]
markers = self._callbacks.applyMarkers(IHttpRequestResponse, [array('i', [5,9])], [array('i', [0,3])])
print('RequestMarkers--->',markers.getRequestMarkers()[0])
print('ResponseMarkers--->',markers.getResponseMarkers()[0])
●Run Output:
以下Demo配合IScanner设置关键字高亮。
from burp import *
from array import array
class BurpExtender(IBurpExtender, IScannerCheck, IScannerInsertionPoint):
def registerExtenderCallbacks(self, callbacks):
self._helpers = callbacks.getHelpers()
self._callbacks = callbacks
callbacks.registerScannerCheck(self)
def doPassiveScan(self, baseRequestResponse):
array = list()
match = self.getMatche(baseRequestResponse.getResponse(), 'Flag')
array.append(ScanIssue(
[self._callbacks.applyMarkers(baseRequestResponse, None, match)],
baseRequestResponse.getHttpService(),
self._helpers.analyzeRequest(baseRequestResponse).getUrl()
)
)
return array
def doActiveScan(self, baseRequestResponse, insertionPoint):
pass
def getMatche(self, baseReqRes, rule):
length = len(baseReqRes)
matche = [array('i')]
start = self._helpers.indexOf(baseReqRes, rule, True, 0, length)
if (start > 0):
matche[0].append(start)
matche[0].append(start+len(rule))
return matche
class ScanIssue(IScanIssue):
def __init__(self, httpMessages, httpService, url):
self._httpMessages = httpMessages
self._httpService = httpService
self._url = url
def getConfidence(self):
return 'Certain'
def getHttpMessages(self):
return self._httpMessages
def getHttpService(self):
return self._httpService
def getIssueBackground(self):
return None
def getIssueDetail(self):
return None
def getIssueName(self):
return 'test'
def getIssueType(self):
return 0
def getRemediationBackground(self):
return None
def getRemediationDetail(self):
return None
def getSeverity(self):
return 'Information'
def getUrl(self):
return self._url
def getHost(self):
return 'localhost'
def getPort(self):
return int(80)
Run Screenshot :添加了一个Issues并将Response中关键词设为高亮。
● IHttpService
此接口用于提供关于HTTP服务的详细信息,可以将HTTP请求发送到该服务。此接口提供了以下方法。
//返回HTTP服务信息的主机名或IP地址
java.lang.String getHost()
//返回 HTTP服务器信息的端口
int getPort()
//返回 HTTP服务信息的协议
java.lang.String getProtocol()
●Demo:
from burp import *
class BurpExtender(IBurpExtender, IHttpListener):
def registerExtenderCallbacks(self, callbacks):
callbacks.registerHttpListener(self)
def processHttpMessage(self, toolFlage, messageIsResponse, messageInfo):
#通过HttpService方法获取Http服务详细信息
IHttpService = messageInfo.getHttpService()
print("Host------>", IHttpService.getHost())
print("Port------>", IHttpService.getPort())
print("Protocol-->", IHttpService.getProtocol())
●Run Output:
●IProxyListener
插件通过注册一个ProxyListener() 监听器,Proxy将在处理请求或者响应时通知该监听器,插件可以对这些信息执行自定义分析或修改。此接口提供了以下方法:
// Proxy模块处理HTTP消息时调用
void processProxyMessage(boolean messageIsRequest, IInterceptedProxyMessage message)
●IInterceptedProxyMessage
通过此接口,插件可以注册一个IProxyListenner来接收Proxy的详细信息 此接口包括以下方法:
//返回被截获的http消息所请求的客户端IP地址
java.net.InetAddress getClientIpAddress()
//返回拦截操作的类型,具体类型可在官方文档关于此接口的属性描述中查看
int getInterceptAction()
//返回当前截获该HTTP消息监听器的名称
java.lang.String getListenerInterface()
//返回被截获消息的详细信息
IHttpRequestResponse getMessageInfo()
//返回请求/响应消息的唯一引用号
int getMessageReference()
//设置更新拦截操作
void setInterceptAction(int interceptAction)
●Demo:
from burp import *
class BurpExtender(IBurpExtender, IProxyListener):
def registerExtenderCallbacks(self, callbacks):
callbacks.registerProxyListener(self)
def processProxyMessage(self, messageIsRequest, message):
#只对request操作
if(messageIsRequest):
print("IP ---> ", message.getClientIpAddress())
print("Type ---> ", message.getInterceptAction())
print("Listener ---> ", message.getListenerInterface())
#将所有的http信息都做drop操作
message.setInterceptAction(IInterceptedProxyMessage.ACTION_DROP)
●Run Output:
●IIntruderPayloadGeneratorFactory
插件可以实现此接口,并且调用IBurpExtenderCallbacks.registerIntruderPayloadGeneratorFactory() 注册IntruderPayloadGenerator工厂,然后通过重写该接口的createNewInstance方法来实现自定义Payload生成器 该接口提供一下方法:
//返回一个IintruderPayloadGenerator Payload生成器对象
IIntruderPayloadGenerator createNewInstance(IIntruderAttack attack)
//设置PayloadGenerator名称
java.lang.String getGeneratorName()
●IIntruderAttack
此接口用于操作Intruder Attack 模块, 并提供以下方法:
//获取HTTP服务器信息
IHttpService getHttpService()
//获取
byte[] getRequestTemplate()
●Run Output:
●IIntruderPayloadGenerator
此接口用于自定义Intruder 的Payload生成器,当发起一个Intruder工具时,插件通过注IIntruderPayloadGeneratorFactory 返回次接口实例。次接口提供入下方法:
//该方法用于获取下一个Payload的值
byte[] getNextPayload(byte[] baseValue)
//此方法由Burp调用,由Paylaod生成器告知Burp是否继续提供Payload继续为True,停止为False
boolean hasMorePayloads()
//重置Payload生成器的状态,这将导致下一次调用getNextPayload方法时会返回第一条payload
void reset()
● Demo :
from burp import *
class BurpExtender(IBurpExtender, IIntruderPayloadGeneratorFactory):
def registerExtenderCallbacks(self, callbacks):
self._helpers = callbacks.getHelpers()
callbacks.registerIntruderPayloadGeneratorFactory(self)
#自定义payload生成器名称
def getGeneratorName(self):
return 'Payload Generator Test'
#返回一个IintruderPayloadGenerator Payload生成器对象
#Burp调用它的时候传入一个IIntruderAttack对象
def createNewInstance(self, attack):
#获取Attack的Http服务器信息
s = attack.getHttpService()
#获取Attack请求模板
t = attack.getRequestTemplate()
print("Http Service Infomatcion ==> ", s)
print("Rquest Template ==> ", self._helpers.bytesToString(t))
return IntruderPayloadGenerator()
class IntruderPayloadGenerator(IIntruderPayloadGenerator):
"""
自定义的Payload生成器,通过读取本地存储的字典文件到self.dict
然后Burp每次调用getNextPayload函数读Payload当Payload读取完之后通过
设置self.flag = False告诉Burp已经无法继续提供更多的Paylaod请停止Intruder Attack
"""
def __init__(self):
dict = open('E:BurpPlug-inExploitdict_test.txt', 'r').readlines()
self.flag = True
self.Index = -1
self.dict = [i.strip() for i in dict]
def hasMorePayloads(self):
return self.flag
#baseValue为Positions中标记的基准值
def getNextPayload(self, baseValue):
print(self.flag, self.Index)
if self.Index == len(self.dict)-1:
self.flag = False
else:
self.Index += 1
return self.dict[self.Index]
def reset(self):
pass
Run :
●IIntruderPayloadProcessor
插件可以实现该接口,并且通过IBurpExtenderCallbacks.registerIntruderPayloadProcessor()注册一个自定义的Intruder工具的Paylaod处理器。该接口提供以下方法:
//此方法有Burp调用,返回Payload处理器的名字
java.lang.String getProcessorName()
//此方法有Burp调用,在每次需要对Paylaod进行处理的时候调用
//currentPaylaod要处理的Payload
//originalPayload在应用了任何Processor处理器之前最原始的Payload值
//baseValue为Positions中标记的基准值
//返回值为被处理的Payload的值,如果返回null意味着当前的Payload将被跳过,并且此次攻击将直接移动到下一个Paylaod
byte[] processPayload(byte[] currentPayload, byte[] originalPayload, byte[] baseValue)
● Demo:
from burp import *
class BurpExtender(IBurpExtender, IIntruderPayloadProcessor):
def registerExtenderCallbacks(self, callbacks):
self._helpers = callbacks.getHelpers()
callbacks.registerIntruderPayloadProcessor(self)
#设置处理器名称
def getProcessorName(self):
return "ProcessorName Test"
#对Payload进行处理
def processPayload(self, currentPayload, originalPayload, baseValue):
currentPayload = self._helpers.bytesToString(currentPayload)
originalPayload = self._helpers.bytesToString(originalPayload)
baseValue = self._helpers.bytesToString(baseValue)
print("currentPayload ==> " + currentPayload)
print("originalPayload ==> " + originalPayload)
print("baseValue ==> " + baseValue)
disposeValue = currentPayload + "MMD_"
return disposeValuei
IMenuItemHandler (此接口以过时,请使用IContextMenuFactory代替)
最后
以上就是傲娇鸡为你收集整理的BurpSuite武器库打造之环境搭建和API介绍(上)的全部内容,希望文章能够帮你解决BurpSuite武器库打造之环境搭建和API介绍(上)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复