BurpSuite - Lisäosien rakentaminen

Lisäosan kehittäminen Montoya API:lla: automaattinen session hallinta osa 2

Keskitaso
30 min

Lisäosan kirjoittaminen Javalla ja Montoya API:lla

Tässä moduulissa jumpataan aiemmin Pythonilla tehty kirjautumisen automatisointi Montoya API:n Java toteutukselle. Käytämme tässä Portswiggerin malliesimerkkiä, jonka avasimme edellisessä moduulissa IDEA-ympäristössämme. Löydät myös samalla tavalla dokumentaatiota täältä.

Muokkaamme tätä seuraavalla tavalla, eli HttpHandlerExample.java -tiedosto näyttää seuraavanlaiselta.

package example.httphandler;

import burp.api.montoya.BurpExtension;
import burp.api.montoya.MontoyaApi;

public class HttpHandlerExample implements BurpExtension {
    @Override
    public void initialize(MontoyaApi api) {
        api.extension().setName("HTTP Handler Example");

        //Register our http handler with Burp.
        api.http().registerHttpHandler(new MyHttpHandler(api));
    }
}

Tässä asetamme käytännössä vain oman nimen tälle lisäosalle setName -funktiolla. Kaikki monimutkaisempi toimintalogiikka tapahtuu MyHttpHandler.java -tiedostossa:

package example.httphandler;

import burp.api.montoya.MontoyaApi;
import burp.api.montoya.http.handler.*;
import burp.api.montoya.http.message.requests.HttpRequest;
import burp.api.montoya.http.HttpService;
import burp.api.montoya.http.message.HttpRequestResponse;
import burp.api.montoya.logging.Logging;
import burp.api.montoya.http.message.HttpHeader;

import java.util.List;

import static burp.api.montoya.http.handler.RequestToBeSentAction.continueWith;
import static burp.api.montoya.http.handler.ResponseReceivedAction.continueWith;

class MyHttpHandler implements HttpHandler {
    private static Logging logging = null;
    private static String session_token;
    private static MontoyaApi api;

    public MyHttpHandler(MontoyaApi api) {
        this.logging = api.logging();
        this.api = api;
        this.session_token = null;
    }

    @Override
    public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent requestToBeSent) {
        if (isTarget(requestToBeSent)) {
            if (session_token != null) {
                logging.logToOutput("Setting new cookies to request");
                HttpRequest modRequest = requestToBeSent.withUpdatedHeader("Cookie","session="+session_token);
                return continueWith(modRequest);
            }
        }
        return continueWith(requestToBeSent);
    }

    @Override
    public ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived responseReceived) {

        if (needsLogin(responseReceived)) {
            logging.logToOutput("Updating cookies");
            makeAuth();

            HttpRequest orig_req = responseReceived.initiatingRequest().withUpdatedHeader("Cookie","session="+session_token);
            HttpService httpService = HttpService.httpService("127.0.0.1",5000,false);
            HttpRequestResponse resp = api.http().sendRequest(orig_req);
            return continueWith(resp.response());
        }
        return continueWith(responseReceived);
    }

    private static boolean isTarget(HttpRequestToBeSent httpRequestToBeSent) {
        return httpRequestToBeSent.url().contains("127.0.0.1:5000");
    }

    private static boolean needsLogin(HttpResponseReceived httpResponseReceived) {
        if (httpResponseReceived.statusCode() == (short)302) {
            List<HttpHeader> headers = httpResponseReceived.headers();
            for (HttpHeader header : headers)
            {
                if (header.toString().equalsIgnoreCase("Location: /")) {
                    return true;
                }
            }
        }
        return false;
    }

    private static void makeAuth() {
        HttpService httpService = HttpService.httpService("127.0.0.1",5000,false);
        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");
        HttpRequestResponse resp = api.http().sendRequest(req);
        session_token = resp.response().cookies().getFirst().value();
    }
}

Toimintalogiikka on täysin sama kuin Python versiossa. Ainoita huomioitavia eroja ovat, että tässä esimerkissä ei käytetä enää processHttpMessage -funktiota, vaan kahta erillistä handleHttpRequestToBeSent- ja handleHttpResponseReceived -funktiota. Toinen vastaa pyyntöjen käsittelystä ja toinen vastausten. Meillä on myös kolme omaa funktiota:

  • isTarget - joka käytännössä vain tarkistaa sisältääkö URL-osoite meidän kohteen tunnusmerkit.
  • needsLogin - joka tarkistaa, että onko kirjautumiseväste vanhentunut HTTP-vastauksen pohjalta. Iteroi otsakkeet ja tarkistaa statuskoodin.
  • makeAuth - joka suorittaa uudelleenkirjautumisen ohjelmallisesti ja päivittää yhteisen session_token-arvon.

Sekunnin kirjautumisaika PART 2

Tehtävässä käytetty sovellus on sama kuin edellisessä kirjautumisen tehtävässä, eli tämän kirjautumisen voimassaoloaika on vain sekunnin. Ratkaise tämä ongelma käyttäen uudempaa Montoya API:a ja hae lippu kirjautumisen takaa.

Tehtävät

Flag

Löydä lippu (flag) labraympäristöstä ja syötä se alle.

hakatemia pro

Valmis ryhtymään eettiseksi hakkeriksi?
Aloita jo tänään.

Hakatemian jäsenenä saat rajoittamattoman pääsyn Hakatemian moduuleihin, harjoituksiin ja työkaluihin, sekä pääset discord-kanavalle jossa voit pyytää apua sekä ohjaajilta että muilta Hakatemian jäseniltä.