From a81e47bb55e80719d39c345e54664c08b849495b Mon Sep 17 00:00:00 2001 From: Felix Buschbeck Date: Thu, 12 Dec 2024 16:52:04 +0100 Subject: [PATCH] Refactor HTTP Cookie Extractor --- .../java/burp/objects/CstcHttpRequest.java | 20 +++++--- .../java/burp/objects/CstcHttpResponse.java | 28 +++++------ .../extractors/HttpCookieExtractor.java | 49 ++++++++++++++----- .../extractors/HttpCookieExtractorTest.java | 14 ++++-- 4 files changed, 74 insertions(+), 37 deletions(-) diff --git a/src/main/java/burp/objects/CstcHttpRequest.java b/src/main/java/burp/objects/CstcHttpRequest.java index ca61773..1c7334f 100644 --- a/src/main/java/burp/objects/CstcHttpRequest.java +++ b/src/main/java/burp/objects/CstcHttpRequest.java @@ -107,7 +107,7 @@ else if(contentType.equals("application/x-www-form-urlencoded")) { } } - throw new IllegalArgumentException("Input is not a vlaid request"); + throw new IllegalArgumentException("Input is not a valid request"); } case XML: String postBody = request.split("\n\n")[1].trim(); @@ -137,6 +137,18 @@ public String url() { return url; } + @Override + public boolean hasHeader(String name) { + try { + headerValue(name); + } + catch(IllegalArgumentException e) { + return false; + } + + return true; + } + @Override public boolean isInScope() { // TODO Auto-generated method stub @@ -227,12 +239,6 @@ public boolean hasHeader(HttpHeader header) { throw new UnsupportedOperationException("Unimplemented method 'hasHeader'"); } - @Override - public boolean hasHeader(String name) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'hasHeader'"); - } - @Override public boolean hasHeader(String name, String value) { // TODO Auto-generated method stub diff --git a/src/main/java/burp/objects/CstcHttpResponse.java b/src/main/java/burp/objects/CstcHttpResponse.java index 42fa366..5119aaf 100644 --- a/src/main/java/burp/objects/CstcHttpResponse.java +++ b/src/main/java/burp/objects/CstcHttpResponse.java @@ -44,7 +44,6 @@ public ByteArray body() { @Override public List cookies() { List cookieList = new ArrayList<>(); - String cookies = new String(); byte[] responseBytes = this.httpResponse.getBytes(); String response = new String(responseBytes); @@ -53,16 +52,11 @@ public List cookies() { for(String line : responseLines) { String[] header = line.split(": "); if(header[0].equals("Set-Cookie")) { - cookies = header[1]; + String[] cookie = header[1].split("="); + cookieList.add(new CstcCookie(cookie[0], cookie[1])); } } - for(String cookie : cookies.split("; ")) { - String[] c = cookie.split("="); - Cookie cc = new CstcCookie(c[0], c[1]); - cookieList.add(cc); - } - return cookieList; } @@ -90,6 +84,18 @@ public String bodyToString() { return response.split("\n\n")[1]; } + @Override + public String cookieValue(String name) { + List cookies = this.cookies(); + for(Cookie c : cookies) { + if(c.name().equals(name)) { + return c.value(); + } + } + + return null; + } + @Override public short statusCode() { // TODO Auto-generated method stub @@ -114,12 +120,6 @@ public Cookie cookie(String name) { throw new UnsupportedOperationException("Unimplemented method 'cookie'"); } - @Override - public String cookieValue(String name) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'cookieValue'"); - } - @Override public boolean hasCookie(String name) { // TODO Auto-generated method stub diff --git a/src/main/java/de/usd/cstchef/operations/extractors/HttpCookieExtractor.java b/src/main/java/de/usd/cstchef/operations/extractors/HttpCookieExtractor.java index b7078cb..3c4aa3d 100644 --- a/src/main/java/de/usd/cstchef/operations/extractors/HttpCookieExtractor.java +++ b/src/main/java/de/usd/cstchef/operations/extractors/HttpCookieExtractor.java @@ -1,5 +1,7 @@ package de.usd.cstchef.operations.extractors; +import java.util.List; + import org.bouncycastle.util.Arrays; import burp.BurpExtender; @@ -7,9 +9,11 @@ import burp.api.montoya.MontoyaApi; import burp.api.montoya.core.ByteArray; import burp.api.montoya.http.message.Cookie; +import burp.api.montoya.http.message.HttpHeader; import burp.api.montoya.http.message.requests.HttpRequest; import burp.api.montoya.http.message.responses.HttpResponse; import burp.objects.CstcByteArray; +import burp.objects.CstcHttpRequest; import de.usd.cstchef.Utils; import de.usd.cstchef.Utils.MessageType; import de.usd.cstchef.operations.Operation; @@ -26,22 +30,45 @@ public class HttpCookieExtractor extends Operation { protected ByteArray perform(ByteArray input, MessageType messageType) throws Exception { String cookieName = cookieNameField.getText(); - if( cookieName.length() == 0 ) - return factory.createByteArray(0); - if(messageType == MessageType.REQUEST){ + if(input.toString().isEmpty() || cookieName.isEmpty()) return factory.createByteArray(""); + + if(messageType == MessageType.REQUEST) { HttpRequest request = factory.createHttpRequest(input); - return checkNull(Utils.httpRequestCookieExtractor(request, cookieName)); + + // has Cookie header + if(request.hasHeader("Cookie")) { + String cookieHeaderValue = request.headerValue("Cookie"); + // has this particular cookie set + if(cookieHeaderValue.contains(cookieName + "=")) { + String[] cookies = cookieHeaderValue.split("; "); + cookieHeaderValue = ""; + for(String cookie : cookies) { + String[] c = cookie.split("="); + if(c[0].equals(cookieName)) { + return factory.createByteArray(c[1]); + } + } + } + else { + throw new IllegalArgumentException("Parameter name not found."); + } + } + + throw new IllegalArgumentException("Parameter name not found."); + } - else if(messageType == MessageType.RESPONSE){ - HttpResponse response = factory.createHttpResponse(input); - for(Cookie c : response.cookies()){ - if(c.name().equals(cookieName)) - return factory.createByteArray(checkNull(c.value())); + else if(messageType == MessageType.RESPONSE) { + String cookie = factory.createHttpResponse(input).cookieValue(cookieName); + + if(cookie == null) { + throw new IllegalArgumentException("Parameter name not found."); + } + else { + return factory.createByteArray(cookie); } - return factory.createByteArray(0); } - else{ + else { return parseRawMessage(input); } } diff --git a/src/test/java/de/usd/cstchef/operations/extractors/HttpCookieExtractorTest.java b/src/test/java/de/usd/cstchef/operations/extractors/HttpCookieExtractorTest.java index 4122950..7280c12 100755 --- a/src/test/java/de/usd/cstchef/operations/extractors/HttpCookieExtractorTest.java +++ b/src/test/java/de/usd/cstchef/operations/extractors/HttpCookieExtractorTest.java @@ -101,7 +101,8 @@ public void setup() { String resIn1 = """ HTTP/2 200 Ok Header1: a - Set-Cookie: cookie1=value1; cookie2=value2 + Set-Cookie: cookie1=value1 + Set-Cookie: cookie2=value2 """; String resOut1 = "value1"; @@ -112,7 +113,8 @@ public void setup() { String resIn2 = """ HTTP/2 200 Ok Header1: b - Set-Cookie: cookie1=value1; cookie2=value2 + Set-Cookie: cookie1=value1 + Set-Cookie: cookie2=value2 """; String resOut2 = "value2"; @@ -123,18 +125,20 @@ public void setup() { String resIn3 = """ HTTP/2 200 Ok Header1: c - Set-Cookie: cookie1=value1; cookie2=value2 + Set-Cookie: cookie1=value1 + Set-Cookie: cookie2=value2 """; String resOut3 = ""; String resCookie3 = "cookie3"; - Triplet resTriplet3 = new Triplet(resOut3, resCookie3, false); + Triplet resTriplet3 = new Triplet(resOut3, resCookie3, true); // empty cookieName String resIn4 = """ HTTP/2 200 Ok Header1: d - Set-Cookie: cookie1=value1; cookie2=value2 + Set-Cookie: cookie1=value1 + Set-Cookie: cookie2=value2 """; String resOut4 = "";