黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第六章 扩展Burp代理(2)Burp中使用Bing

黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第六章 扩展Burp代理(1)配置&Burp模糊测试



写在前面

单个web服务器提供多个web应用程序服务并不罕见,只是其中一些应用程序我们可能不知道。如果我们正在渗透web服务器,应该尽最大努力发现这上面其它的hostname,因为这些hostname可能会为我们提供一种更简单的获取shell的方法。在同一台目标服务器上找到不安全的web应用程序以及开发资源并不罕见。Microsoft的Bing搜索引擎具备的搜索功能允许我们使用“IP”关键字查询Bing在单个IP地址上找到的所有网站。如果我们使用“domain”搜索关键字,Bing还会告诉我们该域名下的所有子域。
现在,我们可以编写一个scraper将这些查询提交给Bing,然后在结果中获取HTML,但这是不礼貌的(也违反了大多数搜索引擎的使用条款)。为了避免麻烦,我们将改用Bing API以编程方式提交这些查询并自己解析结果。除了上下文菜单,我们不会用这个扩展实现任何花哨的Burp GUI;每次运行查询时,我们只需将结果输出到Burp中,任何检测到的指向Burp目标范围的URL都会自动添加。

编写bhp_bing.py脚本

定义Burp扩展类BurpExtender

因为我们已经介绍了如何阅读Burp API文档并将其转换为Python,所以让我们直接写代码。创建并打开bhp_bing.py文件,并敲入以下内容:

from burp import IBurpExtender
from burp import IContextMenuFactory

from java.net import URL
from java.util import ArrayList
from javax.swing import JMenuItem
from thread import start_new_thread

import json
import socket
import urllib

API_KEY = 'YOURKEY'
API_HOST = 'api.cognitive.microsoft.com'

class BurpExtender(IBurpExtender, IContextMenuFactory):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        self.context = None

        # we set up our extension
        callbacks.setExtensionName('BHP Bing')
        callbacks.registerContextMenuFactory(self)

        return
    
    def createMenuItems(self, context_menu):
        self.context = context_menu
        menu_list = ArrayList()
        menu_list.add(JMenuItem(
            "Send to Bing", actionPerformed=self.bing_menu))
        return menu_list

这是我们Bing扩展的第一部分代码,需要说明的是我们需要确保将Bing API密钥设置到位。Bing API允许每月进行1000次免费搜索。先定义一个BurpExtender类,该类实现标准IBurpExtender接口和IContextMenuFactory,它允许我们在用户右键单击Burp中的请求时提供上下文菜单,本示例中的菜单将显示“Send to Bing”选项。我们注册了一个菜单处理程序,该处理程序确定用户点击了哪个网站,以使得我们可构建Bing查询。接下来,程序设置了一个createMenuItem方法,该方法将接收一个IContextMenuInvocation对象,并使用这个对象来确定用户选择了哪个HTTP请求。最后一步是呈现菜单项并使用bing_menu方法处理单击事件。

创建Bing查询执行函数

现在,让我们执行Bing查询,输出结果,并将任何发现的虚拟主机添加到Burp的目标范围:

    def bing_menu(self, event):
        # grab the details of what the user clicked
        http_traffic = self.context.getSelectedMessages()

        print("%d requests highlighted" % len(http_traffic))

        for traffic in http_traffic:
            http_service = traffic.getHttpService()
            host = http_service.getHost()

            print("User selected host: %s" % host)
            self.bing_serch(host)

        return
    
    def bing_search(self, host):
        # check if we have an IP or hostname
        try:
            is_ip = bool(socket.inet_aton(host))
        except socket.error:
            is_ip = False
        
        if is_ip:
            ip_address = host
            domain = False
        else:
            ip_address = socket.gethostbyname(host)
            domain = True
        
        start_new_thread(self.bing_query, ("ip:%s" % ip_address,))
        if domain:
            start_new_thread(self.bing_query, ("domain:%s" % host,))

当用户单击我们定义的上下文菜单项时,bing_menu方法被触发。我们检索突出显示的HTTP请求,并检索每个请求的host部分,然后将其发送到bing_search方法进行进一步处理。bing_search方法首先确定获取到的host部分是IP地址还是主机名,然后查询Bing中与host具有相同IP地址的所有虚拟主机。如果扩展收到的是一个domain,则会对Bing可能索引的任何子目录进行二次搜索。

定义Bing API的请求与解析函数bing_query

现在,我们将安装所需的管道,以便将请求发送到Bing并使用Burp的HTTP API解析返回结果。在BurpExtender类中添加以下代码:

    def bing_query(self, bing_query_string):
        print('Performing Bing search: %s' % bing_query_string)
        http_request = 'Get https://%s/bing/v7.0/search?' % API_HOST
        # encode our query
        http_request += 'q=%s HTTP/1.1\r\n' % urllib.quote(bing_query_string)
        http_request += 'HOST: %s\r\n' % API_HOST
        http_request += 'Connection:close\r\n'
        http_request += 'Ocp-Apim-Subscription-Key: %s\r\n' % API_KEY
        http_request += 'User-Agent: Black Hat Python\r\n\r\n'

        json_body = self._callbacks.makeHttpRequest(
            API_HOST, 443, True, http_request).tostring()
        json_body = json_body.split('\r\n\r\n', 1)[1]
        
        try:
            response = json.loads(json_body)
        except (TypeError, ValueError) as err:
            print('No results from Bing: %s' % err)
        else:
            sites = list()
            if response.get('webPages'):
                sites = response['webPages']['value']
            if len(sites):
                for site in sites:
                    print('*'*100)
                    print('Name: %s         ' % site['name'])
                    print('URL: %s          ' % site['url'])
                    print('Description: %r  ' % site['snippet'])
                    print('*'*100)

                    java_url = URL(site['url'])
                    if not self._callbacks.isInScope(java_url):
                        print('Adding %s to Burp scope' % site['url'])
                        self._callbacks.includeInScope(java_url)
            else:
                print('Empty response from Bing.: %s' % bing_query_string)
        return

小结

Burp的HTTP API要求在发送之前将整个HTTP请求构建为字符串,另外我们还需要添加Bing API Key来进行API调用。然后我们将HTTP请求发送到Microsoft的服务器。当响应返回时,我们分离http头,然后将http头传递给JSON解析器。对于每组结果,我们都将输出一些关于我们发现的站点的信息。如果发现的站点不在Burp的目标搜索范围内,我们会自动添加之。
为此,我们在Burp扩展中混合了Jython API和纯Python,这将有助于我们在攻击特定目标时进行额外的侦察工作。接下来我们试一下。

小试牛刀

要使我们的Bing搜索extension能够正常工作,我们需要使用与前一章节的模糊测试extension相同的过程。加载扩展之后,浏览至http://testphp.vulnweb.com/,然后右键单击刚才发出的GET请求。如果扩展加载正确,我们应该会看到显示菜单项“Send to Bing”,下图所示。
在这里插入图片描述
当我们选择Send to Bing菜单时,我们应该会看到来自Bing的结果,我们得到的结果类型取决于我们加载扩展时选择的输出。但是我在执行的时候,得到的结果跟预期不一致,还有错误,如下图所示。
在这里插入图片描述
根据以往经验,可能应该还是敲错了代码,先根据错误提示检查一下吧。果真如此,在bing_menu函数中调用bing_search函数的时候,写成了bing_serch,可惜导入extension的时候burp还是木有检查出来,看来以后不能太相信burp协助检查错误了。重新运行,结果正常,不过现在这个站点不会再搜出内容,如下图。
在这里插入图片描述
如果单击Burp中的Target选项卡并选择Scope,我们应该会看到新项目自动添加到目标范围,如下图所示。目标范围的作用是仅将攻击、爬行和扫描等活动限制到定义的主机。
在这里插入图片描述
说明:不知道是不是因为我在前一步中bing搜索出来为空,我这里的目标范围始终是空的,等有了可测试的站点我再补充。

可执行代码

附上完整的代码。

from burp import IBurpExtender
from burp import IContextMenuFactory

from java.net import URL
from java.util import ArrayList
from javax.swing import JMenuItem
from thread import start_new_thread

import json
import socket
import urllib

API_KEY = '02b3f79965ee4e269ffff43bb03ccb2a'
API_HOST = 'api.cognitive.microsoft.com'

class BurpExtender(IBurpExtender, IContextMenuFactory):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        self.context = None

        # we set up our extension
        callbacks.setExtensionName('BHP Bing')
        callbacks.registerContextMenuFactory(self)

        return
    
    def createMenuItems(self, context_menu):
        self.context = context_menu
        menu_list = ArrayList()
        menu_list.add(JMenuItem(
            "Send to Bing", actionPerformed=self.bing_menu))
        return menu_list
    
    def bing_menu(self, event):
        # grab the details of what the user clicked
        http_traffic = self.context.getSelectedMessages()

        print("%d requests highlighted" % len(http_traffic))

        for traffic in http_traffic:
            http_service = traffic.getHttpService()
            host = http_service.getHost()

            print("User selected host: %s" % host)
            self.bing_search(host)

        return
    
    def bing_search(self, host):
        # check if we have an IP or hostname
        try:
            is_ip = bool(socket.inet_aton(host))
        except socket.error:
            is_ip = False
        
        if is_ip:
            ip_address = host
            domain = False
        else:
            ip_address = socket.gethostbyname(host)
            domain = True
        
        start_new_thread(self.bing_query, ("ip:%s" % ip_address,))
        if domain:
            start_new_thread(self.bing_query, ("domain:%s" % host,))
    
    def bing_query(self, bing_query_string):
        print('Performing Bing search: %s' % bing_query_string)
        http_request = 'GET https://%s/bing/v7.0/search?' % API_HOST
        # encode our query
        http_request += 'q=%s HTTP/1.1\r\n' % urllib.quote(bing_query_string)
        http_request += 'Host: %s' % API_HOST
        http_request += 'Connection:close\r\n'
        http_request += 'Ocp-Apim-Subscription-Key: %s\r\n' % API_KEY
        http_request += 'User-Agent: Black Hat Python\r\n\r\n'

        json_body = self._callbacks.makeHttpRequest(
            API_HOST, 443, True, http_request).tostring()
        json_body = json_body.split('\r\n\r\n', 1)[1]
        
        try:
            response = json.loads(json_body)
        except (TypeError, ValueError) as err:
            print('No results from Bing: %s' % err)
        else:
            sites = list()
            if response.get('webPages'):
                sites = response['webPages']['value']
            if len(sites):
                for site in sites:
                    print('*'*100)
                    print('Name: %s         ' % site['name'])
                    print('URL: %s          ' % site['url'])
                    print('Description: %r  ' % site['snippet'])
                    print('*'*100)

                    java_url = URL(site['url'])
                    if not self._callbacks.isInScope(java_url):
                        print('Adding %s to Burp scope' % site['url'])
                        self._callbacks.includeInScope(java_url)
            else:
                print('Empty response from Bing.: %s' % bing_query_string)
        return
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值