AutoRepeater icon indicating copy to clipboard operation
AutoRepeater copied to clipboard

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

Open ghost opened this issue 7 years ago • 7 comments

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)

ghost avatar Feb 05 '18 02:02 ghost

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

justinmoore avatar Feb 05 '18 04:02 justinmoore

@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.

justinmoore avatar Feb 07 '18 16:02 justinmoore

@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.

ghost avatar Feb 08 '18 19:02 ghost

@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.

justinmoore avatar Feb 12 '18 03:02 justinmoore

@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.

ghost avatar Feb 15 '18 01:02 ghost

@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-ncc avatar Feb 21 '18 18:02 justinmoore-ncc

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.

justinmoore avatar Jul 05 '18 17:07 justinmoore