Burp Suite Scannerの拡張機能を作ってみた（リクエストヘッダーをScan対象に設定）

## 概要

Log4Shell が話題になったときに、リクエストヘッダーを自動診断できないか模索して
ほとんどのリクエストヘッダーを Scan 対象とする拡張機能を作りました。（ちからわざ）
Burp 標準だと下記2つのヘッダが Scan 対象となるようです。

- Referer
- User-Agent

とりあえず自動診断のカバー率あげたいって方にはいいかなと思います。
よければ使ってみてください！

注意点として

- 悪用しないようにお願いします。
- Scan がなかなか終わりません。。。

## 動作確認環境

- Windows 10 Professional バージョン 21H2
  - openJDK 11.0.7
  - Burp Suite Professional v2022.9.6 
  - jython-standalone-2.7.2
- MacOS Big Sur 11.7.1
  - openJDK 11.0.16.1
  - Burp Suite Professional v2022.9.6
  - jython-standalone-2.7.2

## ソースコード

```py
from burp import IBurpExtender
from burp import IScannerInsertionPointProvider
from burp import IScannerInsertionPoint
from burp import IParameter
import string
import re

RE_HEADER_NAME = re.compile('(.*?:) ?')

class BurpExtender(IBurpExtender, IScannerInsertionPointProvider):
    
    def	registerExtenderCallbacks(self, callbacks):
    
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        callbacks.setExtensionName("ScanAddHeaders")
        callbacks.registerScannerInsertionPointProvider(self)
        print("success")
        
        return
        
    def getInsertionPoints(self, baseRequestResponse):

        insertionPoints = []
        requestInfo = self._helpers.analyzeRequest(baseRequestResponse)
        rawHeaders = requestInfo.getHeaders()

        headerCount = 0
        for rh in rawHeaders:
            headerCount += 1
            if headerCount == 1:
                continue
            
            # skip
            if rh.lower().startswith("content-length:"):
                continue
            if rh.lower().startswith("cookie:"):
                continue
            if rh.lower().startswith("connection:"):
                continue

            # target request header
            insertionPoints.append(InsertionPoint(self._helpers, baseRequestResponse.getRequest(), rh))

        return insertionPoints
        
class InsertionPoint(IScannerInsertionPoint):

    _headerName = ""

    def __init__(self, helpers, baseRequest, header):
        self._helpers = helpers
        self._baseRequest = baseRequest

        m = RE_HEADER_NAME.match(header)
        self._headerName = m.group()
        start = string.find(header, self._headerName) + len(self._headerName)
        end = len(header)
        self._insertionPointPrefix = header[:start]
        self._baseValue = header[start:end]
        self._insertionPointSuffix = header[end:]
        return
        
    def getInsertionPointName(self):
        return "header_param_"+self._headerName

    def getBaseValue(self):
        return self._baseValue

    def buildRequest(self, payload):
        input = self._insertionPointPrefix + self._helpers.bytesToString(payload) + self._insertionPointSuffix
        requestInfo = self._helpers.analyzeRequest(self._baseRequest)
        rawHeaders = requestInfo.getHeaders()
        rawByteBody = self._baseRequest[requestInfo.getBodyOffset():]
        rawBody = self._helpers.bytesToString(rawByteBody)

        headers = []
        for rh in rawHeaders:
            if rh.startswith(self._headerName):
                headers.append(input)
            else:
                headers.append(rh)
        
        return self._helpers.buildHttpMessage(headers, rawBody)

    def getPayloadOffsets(self, payload):
        return None

    def getInsertionPointType(self):
        return IScannerInsertionPoint.INS_EXTENSION_PROVIDED
```

## 導入手順

1. ソースコードをコピーして hogehoge.py などてきとーな名前でファイルに保存します。
2. Burp Suite を起動し、保存したファイルを拡張機能として追加します。

## TIPS

- Scanner 利用時に自動でヘッダーが insertion points に入ります。
- ヘッダーの中で content-length, cookie, connection は除外しています。
Scan が不要なヘッダーがある場合は同じように除外してください。

## 補足

もし不具合とかあったらすみません。。
なにかもっとうまいやり方があれば教えて下さい。