09
Developing an extension with the Montoya API: automatic session management part 2
Medium30MIN
Writing an extension with Java and Montoya API
This module involves transitioning the login automation previously done with Python to a Java implementation of the Montoya API. Here we are using Portswigger's sample example that we opened in our IDEA environment in the previous module. You can also find documentation in the same way here.
We will modify this as follows, so the HttpHandlerExample.java file looks like this.
JAVA
1```java
2package example.httphandler;
3
4import burp.api.montoya.BurpExtension;
5import burp.api.montoya.MontoyaApi;
6
7public class HttpHandlerExample implements BurpExtension {
8 @Override
9 public void initialize(MontoyaApi api) {
10 api.extension().setName("HTTP Handler Example");
11
12 //Register our http handler with Burp.
13 api.http().registerHttpHandler(new MyHttpHandler(api));
14 }
15}TEXT
1
2Here we practically just set our own name for this extension using the *setName* function. All the more complex functionality happens in the *MyHttpHandler.java* file:
3
4```java
5```java
6package example.httphandler;
7
8import burp.api.montoya.MontoyaApi;
9import burp.api.montoya.http.handler.*;
10import burp.api.montoya.http.message.requests.HttpRequest;
11import burp.api.montoya.http.HttpService;
12import burp.api.montoya.http.message.HttpRequestResponse;
13import burp.api.montoya.logging.Logging;
14import burp.api.montoya.http.message.HttpHeader;
15
16import java.util.List;
17
18import static burp.api.montoya.http.handler.RequestToBeSentAction.continueWith;
19import static burp.api.montoya.http.handler.ResponseReceivedAction.continueWith;
20
21class MyHttpHandler implements HttpHandler {
22 private static Logging logging = null;
23 private static String session_token;
24 private static MontoyaApi api;
25
26 public MyHttpHandler(MontoyaApi api) {
27 this.logging = api.logging();
28 this.api = api;
29 this.session_token = null;
30 }
31
32 @Override
33 public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent requestToBeSent) {
34 if (isTarget(requestToBeSent)) {
35 if (session_token != null) {
36 logging.logToOutput("Setting new cookies to request");
37 HttpRequest modRequest = requestToBeSent.withUpdatedHeader("Cookie","session="+session_token);
38 return continueWith(modRequest);
39 }
40 }
41
42 return continueWith(requestToBeSent);
43 }
44
45 @Override
46 public ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived responseReceived) {
47
48 if (needsLogin(responseReceived)) {
49 logging.logToOutput("Updating cookies");
50 makeAuth();
51
52 HttpRequest orig_req = responseReceived.initiatingRequest().withUpdatedHeader("Cookie","session="+session_token);
53 HttpService httpService = HttpService.httpService("127.0.0.1",5000,false);
54 HttpRequestResponse resp = api.http().sendRequest(orig_req);
55 return continueWith(resp.response());
56 }
57
58 return continueWith(responseReceived);
59 }
60
61 private static boolean isTarget(HttpRequestToBeSent httpRequestToBeSent) {
62 return httpRequestToBeSent.url().contains("127.0.0.1:5000");
63 }
64
65 private static boolean needsLogin(HttpResponseReceived httpResponseReceived) {
66 if (httpResponseReceived.statusCode() == (short)302) {
67 List<HttpHeader> headers = httpResponseReceived.headers();
68 for (HttpHeader header : headers)
69 {
70 if (header.toString().equalsIgnoreCase("Location: /")) {
71 return true;
72 }
73 }
74 }
75
76 return false;
77 }
78
79 private static void makeAuth() {
80 HttpService httpService = HttpService.httpService("127.0.0.1",5000,false);
81 HttpRequest req = HttpRequest.httpRequest(httpService, "POST /login HTTP/1.1\r\nHost: 127.0.0.1:5000\r\nContent-Length: 17\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nusername=username");
82 HttpRequestResponse resp = api.http().sendRequest(req);
83 session_token = resp.response().cookies().getFirst().value();
84 }
85}TEXT
1
2The functionality is completely the same as in the Python version. The only notable differences are that in this example, we no longer use the *processHttpMessage* function, but rather two separate functions: *handleHttpRequestToBeSent* and *handleHttpResponseReceived*. The former is responsible for handling requests and the latter for responses. We also have three custom functions:
3
4- *isTarget - *which essentially just checks if the URL address contains our target identifier.
5- *needsLogin* - which checks if the login cookie has expired based on the HTTP response. It iterates through the headers and checks the status code.
6- *makeAuth* - which performs a programmatic reauthentication and updates the shared *session\_token* value.1 / 2
Hakatemia Pro
Learn to hack — start here
Hundreds of interactive courses, virtual labs and CTF challenges in your browser. Start a free trial — no card required.