Burp Extender Apis 插件开发 (六)

admin 2022年6月27日09:35:22评论33 views字数 8651阅读28分50秒阅读模式

No.1

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测以及文章作者不为此承担任何责任。

雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

No.2

前言

这节课的来源是在写fastjson rce检测插件时所遇到的问题并解决后的笔记。
我们知道fastjson的数据是json格式的, 那么前面学的buildParameter就不适用该情况了,会导致使用buildParameter重构参数后报错。

这节课学习 buildHttpMessage 重构json数据,并结合前面课程实现fastjson rce检测插件

No.3

getContentType

此方法用于获取消息正文的内容类型,由IRequestInfo对象调用

官方api:https://portswigger.net/burp/extender/api/burp/IRequestInfo.html#getContentType()

Burp Extender Apis 插件开发 (六)

示例代码如下:

reqContentType = analyzedRequest.getContentType()

如果数据是json格式,那么analyzedRequest.getContentType()返回来的值是4。

那么就可以通过reqContentType是否等于4过滤掉不是json格式的数据包,从而使该插件只检测当数据类型是json时才触发。

接下来准备重构数据包。

No.4

stringToBytes()

byte[] stringToBytes(java.lang.String data)

此方法可用于将数据从字符串形式转换为字节数组。该转换不反映任何特定字符集,十六进制表示为0xWXYZ的字符将始终转换为表示形式为0xYZ的字节。它执行与方法相反的转换bytesToString(),并保证使用这两种方法将基于字节的数据转换为String并再次返回,以确保其完整性(反映给定字符集的转换可能不是这种情况)。

官方api:https://portswigger.net/burp/extender/api/burp/IExtensionHelpers.html#stringToBytes(java.lang.String)

Burp Extender Apis 插件开发 (六)

官方的解释有点拗口,其实很简单,就是把我们想要提交的字符串内容转换为burp能认识的数据类型。

示例代码如下:将字符串payload转换为burp认识的字节类型,这样newBody的数据类型就变成了byte,就能够在下一个api里使用了。

newBodyPayload = '{"age":25, "name":"Bob""}'
newBody = self._helpers.stringToBytes(newBodyPayload)       # 将字符串转换为字节

当构造好payload后,下面准备重构http消息

No.5

buildHttpMessage

byte[] buildHttpMessage(java.util.List<java.lang.String> headers, byte[] body)

此方法构建包含指定的标头和消息正文的HTTP消息。如果适用,将根据正文的长度添加或更新Content-Length标头。

官方api:https://portswigger.net/burp/extender/api/burp/IExtensionHelpers.html#buildHttpMessage(java.util.List,%20byte[])

Burp Extender Apis 插件开发 (六)

buildHttpMessage的第一个参数headers是IRequestInfo对象的getHeaders()方法返回值

示例代码如下:如果不知道analyzedIRequestInfo是什么变量,请回顾前几节课。

reqHeaders = analyzedIRequestInfo.getHeaders()

buildHttpMessage的第二个参数body是IExtensionHelpers.stringToBytes(字符串)的返回值

newBody = self._helpers.stringToBytes(newBodyPayload) # 将字符串转换为字节

准备好两个参数后,传递给buildHttpMessage即可重构http消息

newRequest = self._helpers.buildHttpMessage(reqHeaders, newBody) # 重构json格式的数据不能用buildParameter,要用buildHttpMessage替换整个body重构http消息。

然后接下来同样使用makeHttpRequest发送数据并响应即可。

newIHttpRequestResponse = self._callbacks.makeHttpRequest(httpService, newRequest) # 发送数据

fastjson rce检测插件demo

示例代码如下:

# -*-coding:utf-8 -*-
# 被动扫描fastjson rce检测
from burp import IBurpExtender, IScannerCheck, IScanIssue, IMessageEditorTabFactory, IContextMenuFactory
from burp import IScanIssue
import sys
import time
import os

class BurpExtender(IBurpExtender, IMessageEditorTabFactory, IContextMenuFactory, IScannerCheck):
   def registerExtenderCallbacks(self, callbacks):

       # Required for easier debugging:
       sys.stdout = callbacks.getStdout()

       # 用于设置当前扩展的显示名称,该名称将显示在Extender工具的用户界面中。参数:name - 扩展名。。
       self._callbacks = callbacks

       # 用于获取IExtensionHelpers对象,扩展可以使用该对象执行许多有用的任务。返回:包含许多帮助器方法的对象,用于构建和分析HTTP请求等任务。
       self._helpers = callbacks.getHelpers()

       # 用于设置当前扩展的显示名称,该名称将显示在Extender工具的用户界面中。参数:name - 扩展名。
       self._callbacks.setExtensionName("Passive Fastjson Check")

       # 注册扫描
       callbacks.registerScannerCheck(self)

   # 获取请求的url
   def get_request_url(self, protocol, reqHeaders):
       link = reqHeaders[0].split(' ')[1]
       host = reqHeaders[1].split(' ')[1]
       return protocol + '://' + host + link

   # 获取请求的一些信息:请求头,请求内容,请求方法,请求参数
   def get_request_info(self, request):
       analyzedIRequestInfo = self._helpers.analyzeRequest(request)  # analyzeRequest用于分析HTTP请求,并获取有关它的各种关键详细信息。生成的IRequestInfo对象
       reqHeaders = analyzedIRequestInfo.getHeaders()  # 用于获取请求中包含的HTTP头。返回:请求中包含的HTTP标头。
       reqBodys = request[analyzedIRequestInfo.getBodyOffset():].tostring()  # 获取消息正文开始的请求中的偏移量。返回:消息正文开始的请求中的偏移量。
       reqMethod = analyzedIRequestInfo.getMethod()  # 获取请求方法
       reqParameters = analyzedIRequestInfo.getParameters()
       return analyzedIRequestInfo, reqHeaders, reqBodys, reqMethod, reqParameters

   # 获取响应的一些信息:响应头,响应内容,响应状态码
   def get_response_info(self, response):
       analyzedIResponseInfo = self._helpers.analyzeRequest(response)  # analyzeResponse方法可用于分析HTTP响应,并获取有关它的各种关键详细信息。返回:IResponseInfo可以查询的对象以获取有关响应的详细信息。
       resHeaders = analyzedIResponseInfo.getHeaders()  # getHeaders方法用于获取响应中包含的HTTP标头。返回:响应中包含的HTTP标头。
       resBodys = response[analyzedIResponseInfo.getBodyOffset():].tostring()  # getBodyOffset方法用于获取消息正文开始的响应中的偏移量。返回:消息正文开始的响应中的偏移量。response[analyzedResponse.getBodyOffset():]获取正文内容
       # resStatusCode = analyzedIResponseInfo.getStatusCode()  # getStatusCode获取响应中包含的HTTP状态代码。返回:响应中包含的HTTP状态代码。
       return resHeaders, resBodys

   # 获取服务端的信息,主机地址,端口,协议
   def get_server_info(self, httpService):
       host = httpService.getHost()
       port = httpService.getPort()
       protocol = httpService.getProtocol()
       ishttps = False
       if protocol == 'https':
           ishttps = True
       return host, port, protocol, ishttps

   # 获取请求的参数名、参数值、参数类型(get、post、cookie->用来构造参数时使用)
   def get_parameter_Name_Value_Type(self, parameter):
       parameterName = parameter.getName()
       parameterValue = parameter.getValue()
       parameterType = parameter.getType()
       return parameterName, parameterValue, parameterType

   # 开始检测
   def start_run(self, baseRequestResponse):
       self.baseRequestResponse = baseRequestResponse

       # 获取请求包的数据
       request = self.baseRequestResponse.getRequest()
       analyzedRequest, reqHeaders, reqBodys, reqMethod, reqParameters = self.get_request_info(request)
       reqContentType = analyzedRequest.getContentType()       # 获取请求格式,例如json

       if reqContentType == 4:         # json格式数据

           # 获取服务信息
           httpService = self.baseRequestResponse.getHttpService()

           newBodyPayload = '{"age":25, "name":"Bob""}'
           newBody = self._helpers.stringToBytes(newBodyPayload)       # 将字符串转换为字节 https://portswigger.net/burp/extender/api/burp/IExtensionHelpers.html#stringToBytes(java.lang.String)
           newRequest = self._helpers.buildHttpMessage(reqHeaders, newBody)    # 重构json格式的数据不能用buildParameter,要用buildHttpMessage替换整个body重构http消息。https://portswigger.net/burp/extender/api/burp/IExtensionHelpers.html#buildHttpMessage(java.util.List,%20byte[])
           newIHttpRequestResponse = self._callbacks.makeHttpRequest(httpService, newRequest)  # 发送数据
           response = newIHttpRequestResponse.getResponse()  # 获取响应包
           analyzedIResponseInfo = self._helpers.analyzeRequest(response)  # analyzeResponse方法可用于分析HTTP响应,并获取有关它的各种关键详细信息。返回:IResponseInfo可以查询的对象以获取有关响应的详细信息。
           resBodys = response[analyzedIResponseInfo.getBodyOffset():].tostring()
           newUrl = self._helpers.analyzeRequest(newIHttpRequestResponse).getUrl()

           print resBodys

           if 'fastjson' in resBodys:
               print '[+] {}'.format(newUrl)
               self.save(newUrl)
               self.issues.append(CustomScanIssue(
                               newIHttpRequestResponse.getHttpService(),
                               newUrl,
                               [newIHttpRequestResponse],
                               "FastJson RCE",
                               "fastjson",
                               "High"))
           else:
               print '[-] {}'.format(newUrl)

   def doPassiveScan(self, baseRequestResponse):
       '''
       :param baseRequestResponse: IHttpRequestResponse
       :return:
       '''
       self.issues = []
       self.start_run(baseRequestResponse)
       return self.issues

   def consolidateDuplicateIssues(self, existingIssue, newIssue):
       '''
       相同的数据包,只报告一份报告
       :param existingIssue:
       :param newIssue:
       :return:
       '''


       if existingIssue.getIssueDetail() == newIssue.getIssueDetail():
           return -1

       return 0

class CustomScanIssue(IScanIssue):
   def __init__(self, httpService, url, httpMessages, name, detail, severity):
       '''

       :param httpService: HTTP服务
       :param url: 漏洞url
       :param httpMessages: HTTP消息
       :param name: 漏洞名
       :param detail: 漏洞细节
       :param severity: 漏洞等级
       '''
       self._httpService = httpService
       self._url = url
       self._httpMessages = httpMessages
       self._name = name
       self._detail = detail
       self._severity = severity

   def getUrl(self):
       return self._url

   def getIssueName(self):
       return self._name

   def getIssueType(self):
       return 0

   def getSeverity(self):
       return self._severity

   def getConfidence(self):
       return "Certain"

   def getIssueBackground(self):
       pass

   def getRemediationBackground(self):
       pass

   def getIssueDetail(self):
       return self._detail

   def getRemediationDetail(self):
       pass

   def getHttpMessages(self):
       return self._httpMessages

   def getHttpService(self):
       return self._httpService

效果如下:

当正常发送数据包时,响应包没报错

Burp Extender Apis 插件开发 (六)

再来看看插件的情况,可以看到响应包里出现了fastjon字符串,说明payload检测出了该漏洞

Burp Extender Apis 插件开发 (六)

这里demo用的是写死的payload,自己写的时候根据自己的需求将payload请求的地址改为dnslog的地址。

No.6

安服福建大区招聘

安全服务部福建大区致力于福建全省的安全检测和咨询规划业务支撑。团队拥有非常完善的渗透测试、代码审计、应急响应、网络安保的服务体系和技术能力。同时,致力于打造一个规范、安全、高效、诚信、专业的安全服务团队。

安全服务工程师(实习)

————————

工作地点:福州

【岗位职责】

1.负责对客户系统进行渗透测试,包括各类应用系统、移动APP等,全面发现被测系统存在的安全问题并提供修复建议;

2.客户系统出现安全事件时进行应急处置,协助客户修复安全漏洞;

3.负责日常网络安全产品运维、漏洞扫描、网络安全基线配置核查等;

4.负责日常网络安全日志和事件监测、分析、预警、处置、总结;

5.负责敏感时期、重大节假日期间的网络安全保障;

6.协助用户处理日常安全工作,提供安全建议和咨询。


【任职要求】

1.对网络安全攻防感兴趣,熟练掌握渗透测试技巧、熟练运用各类安全软件、安全测试工具;

2.熟悉渗透测试步骤、方法、流程,熟练使用渗透测试工具;

3.熟悉常见web安全漏洞的原理、测试方法、加固方法;

4.具有较好的工作习惯及较强的文档、报告、方案编写能力;

5.具备优秀的沟通协调能力、学习能力、抗压能力;

6.在t00ls、freebuf、Seebug等平台发布过技术文章者优先;

7.有web开发经验或熟悉PHP/C#/Java/Python任意一种语言者优先;

8.有CTF、攻防比赛获得奖项者优先;

9.有知名SRC、漏洞平台、CVE、CNVD、CNNVD漏洞提交证明者优先。


简历投递至:[email protected]

Burp Extender Apis 插件开发 (六)

专注渗透测试技术

全球最新网络攻击技术

END

Burp Extender Apis 插件开发 (六)

原文始发于微信公众号(白帽子):Burp Extender Apis 插件开发 (六)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年6月27日09:35:22
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Burp Extender Apis 插件开发 (六)https://cn-sec.com/archives/868395.html

发表评论

匿名网友 填写信息