From b7fed8e60175a5b794d503283adabe008de46537 Mon Sep 17 00:00:00 2001 From: James Kettle Date: Fri, 1 Feb 2019 14:34:58 +0000 Subject: [PATCH] Expose burp callbacks/helpers, and add req.getBurpRequest() for interopability --- src/BurpRequestEngine.kt | 6 ++--- src/Request.kt | 51 +++++++++++++++++++++++++++++++++--- src/RequestEngine.kt | 4 ++- src/RequestTable.kt | 8 +++--- src/RequestTableModel.kt | 2 +- src/ThreadedRequestEngine.kt | 5 ++-- src/fast-http.kt | 6 +++-- 7 files changed, 66 insertions(+), 16 deletions(-) diff --git a/src/BurpRequestEngine.kt b/src/BurpRequestEngine.kt index 21fa61b..41ed2c9 100644 --- a/src/BurpRequestEngine.kt +++ b/src/BurpRequestEngine.kt @@ -19,7 +19,7 @@ open class BurpRequestEngine(url: String, threads: Int, maxQueueSize: Int, overr } completedLatch = CountDownLatch(threads) - val target = URL(url) + target = URL(url) val service = Utils.callbacks.helpers.buildHttpService(target.host, target.port, target.protocol == "https") for(j in 1..threads) { @@ -61,11 +61,11 @@ open class BurpRequestEngine(url: String, threads: Int, maxQueueSize: Int, overr } } - var resp = Utils.callbacks.makeHttpRequest(service, req.getRawRequest()) + var resp = Utils.callbacks.makeHttpRequest(service, req.getRequestAsBytes()) connections.incrementAndGet() while (resp.response == null && shouldRetry(req)) { Utils.out("Retrying "+req.word) - resp = Utils.callbacks.makeHttpRequest(service, req.getRawRequest()) + resp = Utils.callbacks.makeHttpRequest(service, req.getRequestAsBytes()) connections.incrementAndGet() Utils.out("Retried "+req.word) } diff --git a/src/Request.kt b/src/Request.kt index 1cb4e81..31be9ec 100644 --- a/src/Request.kt +++ b/src/Request.kt @@ -11,6 +11,10 @@ open class Request(val template: String, val word: String?, val learnBoring: Int constructor(template: String): this(template, null, 0) + fun getBurpRequest(): IHttpRequestResponse { + return BurpRequest(this) + } + fun getRequest(): String { if (word == null) { return template @@ -29,15 +33,14 @@ open class Request(val template: String, val word: String?, val learnBoring: Int return template.replace("%s", word) } - fun getRawRequest(): ByteArray { + fun getRequestAsBytes(): ByteArray { return fixContentLength(getRequest().toByteArray(Charsets.ISO_8859_1)) } - fun getRawResponse(): ByteArray? { + fun getResponseAsBytes(): ByteArray? { return response?.toByteArray(Charsets.ISO_8859_1) } - fun fixContentLength(request: ByteArray): ByteArray { if (String(request).contains("Content-Length: ")) { val start = getBodyStart(request) @@ -123,4 +126,46 @@ open class Request(val template: String, val word: String?, val learnBoring: Int return i } + + +} + +class BurpRequest(val req: Request): IHttpRequestResponse { + + + override fun getRequest(): ByteArray { + return req.getRequestAsBytes() + } + + override fun getResponse(): ByteArray? { + return req.getResponseAsBytes() + } + + override fun getHttpService(): IHttpService { + val url = req.engine!!.target + return Utils.callbacks.helpers.buildHttpService(url.host, url.port, url.protocol) + } + + override fun getComment(): String? { + return null + } + + override fun setComment(comment: String?) { + } + + override fun getHighlight(): String? { + return null + } + + override fun setResponse(message: ByteArray?) { + } + + override fun setRequest(message: ByteArray?) { + } + + override fun setHttpService(httpService: IHttpService?) { + } + + override fun setHighlight(color: String?) { + } } \ No newline at end of file diff --git a/src/RequestEngine.kt b/src/RequestEngine.kt index 1f1ca48..2eb3c43 100644 --- a/src/RequestEngine.kt +++ b/src/RequestEngine.kt @@ -1,6 +1,7 @@ package burp import java.io.* +import java.net.URL import java.util.* import java.util.concurrent.CountDownLatch import java.util.concurrent.LinkedBlockingQueue @@ -23,6 +24,7 @@ abstract class RequestEngine { lateinit var requestQueue: LinkedBlockingQueue abstract val callback: (Request, Boolean) -> Boolean abstract val maxRetriesPerRequest: Int + lateinit var target: URL fun invokeCallback(req: Request, interesting: Boolean){ try { @@ -165,7 +167,7 @@ abstract class RequestEngine { reqTable.model.fireTableRowsDeleted(0, requestsFromTable.size) for (request in copy) { - val interesting = processResponse(request, request.getRawResponse()!!) + val interesting = processResponse(request, request.getResponseAsBytes()!!) callback(request, interesting) } diff --git a/src/RequestTable.kt b/src/RequestTable.kt index 3f534c5..adea9ee 100644 --- a/src/RequestTable.kt +++ b/src/RequestTable.kt @@ -45,8 +45,8 @@ class RequestTable(val service: IHttpService, val handler: AttackHandler): JPane fun setCurrentRequest(req: Request?) { //println("Setting current request to "+req!!.word) currentRequest = req!! - requestEditor.setMessage(req.getRawRequest(), true) - responseEditor.setMessage(req.getRawResponse(), false) + requestEditor.setMessage(req.getRequestAsBytes(), true) + responseEditor.setMessage(req.getResponseAsBytes(), false) } init { @@ -109,11 +109,11 @@ class RequestTable(val service: IHttpService, val handler: AttackHandler): JPane } override fun getRequest(): ByteArray? { - return currentRequest?.getRawRequest() + return currentRequest?.getRequestAsBytes() } override fun getResponse(): ByteArray? { - return currentRequest?.getRawResponse() + return currentRequest?.getResponseAsBytes() } } diff --git a/src/RequestTableModel.kt b/src/RequestTableModel.kt index e94d207..0f426bf 100644 --- a/src/RequestTableModel.kt +++ b/src/RequestTableModel.kt @@ -10,7 +10,7 @@ class TableRequest(val req: Request) { init { - val resp = req.getRawResponse() ?: "".toByteArray() + val resp = req.getResponseAsBytes() ?: "".toByteArray() code = Utils.callbacks.helpers.analyzeResponse(resp).statusCode length = req.response?.length ?: 0 diff --git a/src/ThreadedRequestEngine.kt b/src/ThreadedRequestEngine.kt index d670b39..127d94c 100644 --- a/src/ThreadedRequestEngine.kt +++ b/src/ThreadedRequestEngine.kt @@ -15,10 +15,11 @@ import kotlin.concurrent.thread open class ThreadedRequestEngine(url: String, val threads: Int, maxQueueSize: Int, val readFreq: Int, val requestsPerConnection: Int, override val maxRetriesPerRequest: Int, override val callback: (Request, Boolean) -> Boolean, val timeout: Int): RequestEngine() { private val connectedLatch = CountDownLatch(threads) - private val target = URL(url) + private val threadPool = ArrayList() init { + target = URL(url) if (maxQueueSize > 0) { requestQueue = LinkedBlockingQueue(maxQueueSize) @@ -151,7 +152,7 @@ open class ThreadedRequestEngine(url: String, val threads: Int, maxQueueSize: In if (req == null) break inflight.addLast(req) - socket.getOutputStream().write(req.getRawRequest()) + socket.getOutputStream().write(req.getRequestAsBytes()) readCount++ requestsSent++ diff --git a/src/fast-http.kt b/src/fast-http.kt index 451fc21..1f72f4d 100644 --- a/src/fast-http.kt +++ b/src/fast-http.kt @@ -93,11 +93,13 @@ fun evalJython(code: String, baseRequest: String, endpoint: String, baseInput: S val pyInterp = PythonInterpreter() // todo add path to bs4 pyInterp.set("target", Target(baseRequest, endpoint, baseInput)) pyInterp.set("wordlists", Wordlist(Bruteforce(), Utils.witnessedWords.savedWords)) - pyInterp.set("handler", handler) - //pyInterp.set("helpers", BurpExtender.callbacks.helpers) pyInterp.set("outputHandler", outputHandler) pyInterp.set("table", outputHandler) + if (Utils.gotBurp) { + pyInterp.set("callbacks", Utils.callbacks) + pyInterp.set("helpers", Utils.callbacks.helpers) + } pyInterp.exec(Scripts.SCRIPTENVIRONMENT) pyInterp.exec(code) pyInterp.exec("queueRequests(target, wordlists)")