nccgroup / AutoRepeater

Automated HTTP Request Repeating With Burp Suite
https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2018/january/autorepeater-automated-http-request-repeating-with-burp-suite/
MIT License
846 stars 107 forks source link

Replacement rules in requests with Content-Type: multipart/form-data #2

Open ghost opened 6 years ago

ghost commented 6 years ago

I found two issues in requests with Content-Type: multipart/form-data.

In order to better reproduce these issues, I'm sending this base request:

POST / HTTP/1.1
Host: www.google.com
Connection: close
Content-Length: 177
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.0 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0Bmuvd5DrV6Q690A
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundary0Bmuvd5DrV6Q690A
Content-Disposition: form-data; name="csrf_token"

20F4C2E40C658A7CF60080C4342227DD
------WebKitFormBoundary0Bmuvd5DrV6Q690A

1 - If you select as a replacement rule the following configuration:

Type: Request Param Value Match: 20F4C2E40C658A7CF60080C4342227DD Replace: aaa Which: Replace First Regex Match: Disabled

and send the previous request to AutoRepeater, you will see this modified request:

POST / HTTP/1.1
Host: www.google.com
Connection: close
Content-Length: 277
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.0 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0Bmuvd5DrV6Q690A
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundary0Bmuvd5DrV6Q690A
Content-Disposition: form-data; name="csrf_token"

20F4C2E40C658A7CF60080C4342227DD
------WebKitFormBoundary0Bmuvd5DrV6Q690A
Content-Disposition: form-data; name="csrf_token"

aaa
------WebKitFormBoundary0Bmuvd5DrV6Q690A

so instead of replacing the value in the parameter csrf_token with aaa, it is appending an additional parameter. Ideally, the expected request should be

POST / HTTP/1.1
Host: www.google.com
Connection: close
Content-Length: 277
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.0 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0Bmuvd5DrV6Q690A
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundary0Bmuvd5DrV6Q690A
Content-Disposition: form-data; name="csrf_token"

aaa
------WebKitFormBoundary0Bmuvd5DrV6Q690A

2 - If the request includes the following parameter:

------WebKitFormBoundary0Bmuvd5DrV6Q690A
Content-Disposition: form-data; name="photo_file"; filename=""
Content-Type: application/octet-stream

------WebKitFormBoundary0Bmuvd5DrV6Q690A

the request is not received correctly. For example:

POST / HTTP/1.1
Host: www.google.com
Connection: close
Content-Length: 277
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.0 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0Bmuvd5DrV6Q690A
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundary0Bmuvd5DrV6Q690A
Content-Disposition: form-data; name="csrf_token"

20F4C2E40C658A7CF60080C4342227DD
------WebKitFormBoundary0Bmuvd5DrV6Q690A
Content-Disposition: form-data; name="photo_file"; filename=""
Content-Type: application/octet-stream

------WebKitFormBoundary0Bmuvd5DrV6Q690A

will output this error:

java.lang.UnsupportedOperationException: Action is not supported for this parameter type
    at burp.sve.a(Unknown Source)
    at burp.sve.removeParameter(Unknown Source)
    at burp.Replacement.updateBurpParamName(Replacement.java:148)
    at burp.Replacement.updateRequestParamValue(Replacement.java:265)
    at burp.Replacement.performReplacement(Replacement.java:331)
    at burp.AutoRepeater.lambda$modifyAndSendRequestAndLog$21(AutoRepeater.java:1202)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
justinmoore commented 6 years ago

Thanks for the new issue. Hopefully I'll have time to look into this tomorrow during the day.

justinmoore commented 6 years ago

@rsmith31415 So I've began looking into this and unfortunately Burp's Extender API doesn't cleanly handle multipart form parameters so I'm going to need to implement a good bit of logic to handle these.

ghost commented 6 years ago

@m00r3 Interesting. I'm sure there are parsers for multipart/form-data available in java. Hopefully, they provide enough flexibility to construct a new request in the more difficult case of removing a parameter completely.

justinmoore commented 6 years ago

@rsmith31415 I've done a fair bit of research and it seems like the only reasonable way to fix this is to implement some code that does multipart form handling myself. I'm assuming implementing this will take a bit of time so in the interim I'm going to fix the exception that gets thrown and fix the bug in the regular full body string replace where bytes without valid characters get stomped which should allow AutoRepeater to still do the performs the same actions as the replace parameter functionality.

ghost commented 6 years ago

@m00r3 Do you think that's the way Burp Suite deals with every type of content type? It looks like a lot of work and it is very likely this specific content type won't be an isolated case.

justinmoore-ncc commented 6 years ago

@rsmith31415 I'm not actually sure how Burp Suite manages it internally. They may have some functionality implemented that's not exposed through the Burp Extender API. In the interim while I implement parsing multipart forms the "replace string" replacement should cover any cases where the param replacement wouldn't work.

justinmoore commented 6 years ago

I'm marking this "won't fix" for the time being because the "Request String" replacement largely covers the functionality this bug fix would provide. I'm hoping that either Burp's API just automatically fixes this issue or that I can find a better HTTP parser to replacement Burp's API with.