返回顶部

基于 burpsuite的web逻辑漏洞插件开发(来自JSRC安全小课堂,柏山师傅)

 

基于 burpsuite的web逻辑漏洞插件开发

     BurpSuite 提供了插件开发接口,支持Java、Python、Ruby语言的扩展。虽然 BApp Store 上面已经提供了很多插件,其中也不乏优秀好用的插件。

推荐几个个人感觉好的插件CO2,Logger++,Autorize,XSS Validator

      但是通用化的工具无法完全符合web安全测试人员的特定需求。
本节我和大家探讨,如何根据实际需求自己开发出提高安全测试效率的插件。
      本次课程主要是从以下四个方面展开

 

 

 1.为什么要独立开发插件

      随着厂商安全意识增强,传输过程中,大多数线上业务通过https传输,传输流量加密。无法做中间人攻击了就服务端,数据库中的敏感数据加密存储,访问控制受限,即使拿到数据库也无法拿到明文数据。但是数据在客户端最终要展示给用户,必然明文展现。

    传统的安全防御设备和措施对逻辑漏洞收效甚微,现在攻击者更倾向于在客户端利用此类漏洞。而逻辑漏洞种类很多,通用化的工具无法完全符合web安全测试人员的特定需求。一个业务的逻辑漏洞抽象出来的模型,难以在其他业务层进行批量处理,通用的解决方案往往效果不佳。(但是一个业务层抽象出来的模型,在其自身站点往往具有通用性。)

    例如,某URL存在越权,可能该站点其他URL也可能存在类似的问题。我们基于该URL特征,开发burpsuite插件,批量扫描该站点,就能更全面的发现同类问题。

2. 开发环境配置

Burp支持Java、Python、Ruby语言的扩展,本次讲座以python环境为 例进行说明。Burpsuite 是运行在java环境,所有的库是java所写。Python作为开发语言,调用Java库就要用到Jython。

 Burpsuite Jython环境的配置

Extender -> options -> python Environment -> select file,导入下载好的jython jar包。

 

 

 3.插件开发关键接口的使用实例

    API接口查阅可以从以下拿到:
API接口文档可以在burpsuite 的Extender -> APIs 
也可以通过https://portswigger.net/burp/extender/api/index.html进行查阅。

     IBurpExtender
IBurpExtender是Burpsuite插件的入口,所有插件的开发都必须要实现。当插件被建立以后,registerExtenderCallbacks也需要实现。

代码如下:class BurpExtender(IBurpExtender):
def registerExtenderCallbacks(self, callbacks):

参数callbacks可获取核心基础库,例如日志,请求,返回值修改等。IBurpExtenderCallbacks: 这个接口几乎是必备的。在插件编写的过程中会经常用到。

    IExtensionHelpers: 
提供了编写扩展中常用的一些通用函数,比如编解码、构造请求、获取请求参数,获取请求头等。如:IRequestInfo analyzeRequest(byte[] request)
通过analyzeRequest函数,可以拿到请求的细节。

通过如下几个接口方法可以拿到

 

 

 IHttpRequestResponse: 这个接口包含了每个请求和响应的细节。在Brupsuite中的每个请求或者响应都是IHttpRequestResponse实例。通过getRequest(), getResponse()方法可以获取请求和响应的细节信息。

以registerHttpListener为例进行代码说明:

    如图所示,在user 和 webserver之间建立监听,调用HttpListener接口。获取请求,响应的日志。

 

 

 实现这个功能,最重要的是这个方法:
# register ourselves as an HTTP listener
callbacks.registerHttpListener(self)

def registerExtenderCallbacks(self, callbacks):

        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        ## 设置插件名
        self._callbacks.setExtensionName("getTheRequest")

# //如果没有注册,下面的processHttpMessage方法是不会生效的。处理请求和响应包的插件,这个应该是必要的

        callbacks.registerHttpListener(self)

### processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo),
### 在messageInfo这个参数中,我们可以获取到request和response日志。

 def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
        if toolFlag == 4:
            if not messageIsRequest:
                request = messageInfo.getRequest()
                analyzedRequest = self._helpers.analyzeResponse(request)
                request_header = analyzedRequest.getHeaders()

                try:
                    method, path = res_path.findall(request_header[0])[0]
                    host = res_host.findall(request_header[1])[0]
                    url = method + " " + host + path
                except:
                    url = ""

                if method == "GET":
                    print “[+++++]The URL is ", url
                    print "[+++++]The host is ",host
                    print "[++++] The URI is following"
                    print path
                    for iterm in path.split("/"):
                        print iterm
                    print 

代码如上所示,就可以打印出URL,HOST,URI日志信息

 

 

    如果做扫描类插件:
class BurpExtender(IBurpExtender,IScannerCheck)
callbacks.registerScannerCheck(this);


    实现IScannerCheck后需要重写被动扫描的函数。
doPassiveScan(IHttpRequestResponse baseRequestResponse) {}

doPassiveScan这个接口,在baseRequestResponse获取请求和响应数据,并利用这些数据进行基于扫描规则进行扫描。

 

   逻辑漏洞检测插件开发探讨

这个插件实现的基本功能是:确定哪些cookie有效cookie,可以基于这些URL,生成字典,进行目录爆破

首先,我们需要拿到requests 的 cookie

request = messageInfo.getRequest()
            analyzedRequest = self._helpers.analyzeResponse(request)
            requestHeaders = analyzedRequest.getHeaders()

            newHeaders = dict()
            cookies = dict()

            for header in requestHeaders:
                header = header.encode('utf-8')
                if "HTTP/" not in header and "Host" not in header and "Cookie" not in header:

                    header_item = header.split(": ")
                    newHeaders[header_item[0]] = ": ".join(header_item[1:])

                if header.lower().startswith("cookie"):

                    rawCookie =  header.strip("Cookie: ")

                    for item_cookie in rawCookie.split("; "):
                        key = item_cookie.split("=")[0]
                        value = "=".join(item_cookie.split("=")[1:])
                        cookies[key] = value
                lengthList = {}
                for key,value in cookies.items():
                    tempcookie = {}
                    tempcookie[key] = value
                    response = requests.get(url,headers=newHeaders,cookies=tempcookie,verify=False)
                    lengthList[key] = len(response.content)
                if lengthList.keys():
                    print url
                    print lengthList
根据响应长度的不同确定哪些cookie是有效cookie

 

 

 针对DES,AES加密参数的逻辑漏洞挖掘:

AES,DES属于对称加密,所以客户端和服务器端都会有秘钥存在,也就是说密钥在客户端肯定能找到。网页,微信小程序中,往往在js代码中就能找到,找到密钥即可进行逻辑漏洞测试。

在一次对微信小程序渗透测试中,抓包发现订单ID参数以密文形式进行传输。因此,我们需要获取加密方法。通过反编译微信小程序包,发现了密钥,加密方法是DES加密。
这是在一次渗透测试过程中获取DES秘钥的截图;

昨天分享了一下,今题讲一些插件的tips

 

 

 ## 代码编写获取订单ID密文。

 

 

 在burpsuite测试过程:
由于是对订单ID加密,我们先遍历明文ID,再对明文Id进行加密,生成字典。再利用burp 的爆破插件,进行爆破即可。

tips:遇到参数加密的情况并不可怕,既然是对称加密,秘钥一定能在客户端拿到。对js代码进行分析,往往就可以获取到秘钥。

# 对消息体进行解析
analyzeRequest= helpers.analyzeRequest(messageInfo); 
# 获取请求头
headers= analyzeRequest.getHeaders()
# 获取参数列表
paraList= analyzeRequest.getParameters();#获取参数列表,参数分为三种类型,URL中的参数,cookie中的参数,body中的参数。

for para in paraList:
# 这里可以考虑对加密参数进行筛选
key= para.getName() # 获取参数名
value= para.getValue() # 获取参数
aesValue = aes.encrypt(value); 
aesValue = URLEncoder.encode(aesvalue); 

遍历参数,可以对参数名进行过滤,处理需要加密的参数

newPara= helpers.buildParameter(key, aesValue, para.getType()); #构造新的参数                          
updateRequest = helpers.updateParameter(new_Request, newPara); #构造新的请求包
messageInfo.setRequest(updateRequest);//设置最终新的请求包

//如果作为插件开发的话,只需要更改AES秘钥即可。

posted @ 2020-02-07 16:35  cat47  阅读(1173)  评论(0编辑  收藏  举报