Burp Suite User Forum

Create new post

Macro: How to receive a parameter from POST response to use it in the next GET request

shredder | Last updated: Nov 27, 2017 07:55AM UTC

Hi community, I am currently testing a REST API and I would like to use a JSON parameter from a POST response in the next GET request. The workflow is the following: 1. POST to application like: POST /rest/requests [...] { "parameter":"test", } 2. The application replies with a unique ID in JSON format: {"ID":"yourID"} 3. If I use now "yourID" within a GET request to a different URL I could get more details about the parameters stored in the DB like: GET /rest/requests/detail/<ID> I would like to automate this with a macro to check for SQL injections etc. It should run a POST, extract the ID and run a GET request with this ID afterwards. Is this somehow possible with Burp?

PortSwigger Agent | Last updated: Nov 27, 2017 09:27AM UTC

Hi, Thanks for your message. In general, this is possible in Burp using Macros and Session Handling Rules. These are available in Project options > Sessions. The particular example you mention is not possible, because Session Handling Rules can't replace a URL path parameter. If the GET request was /detail?id=<ID> they could handle it. However, you can use the Custom Parameter Handler extension. Brief instructions: Click + in the tab bar to create a new rule Select: This tab will work only on requests containing this expression: /rest/requests/detail/ Find matches to this expression: <ID> Replace each target with the follow: A value returned by issuing a single request Paste the POST request into the left-hand text area. Click Issue Extract the value from its response: "ID" "(.*)" Please read the Custom Parameter Handler documentation for more information.

Burp User | Last updated: Nov 28, 2017 09:48AM UTC

Hi Paul, thank you very much for your prompt answer. This goes somehow in the right direction, but does not solve my problem as the focus is on the GET request and not on the original POST request that I would like to have an eye on. I would like to - let's say - do an active scan on the first POST request. The response to a single POST request does not contain the real content of what is stored in the DB. Only the ID comes back. To get the real content of the DB - and perhaps to find an indicator of a vulnerability - I need to do an additional GET request on that ID. So what I would like to have is when doing an active scan on a POST request: 1. Create the POST request containing the payload 2. Extract the ID from the response 3. Create a GET request with the ID to the detail URL 4. Compare the response from that GET request with the initial POST and its payload to find any vulnerabilities. Do you think that this might be possible?

PortSwigger Agent | Last updated: Nov 28, 2017 09:50AM UTC

Hi Shredder, Ok, I see what you mean. One of the actions for a Session Handling Rule is "Run a post-request macro" which can nearly do what you want. Unfortunately, it does not support URL path parameters. To handle your app you'll need to do some extension coding. This can be relatively simple - I recommend using Python for simple scenarios. What I suggest you do is implement the IHttpListener interface. This has a processMessage callback when requests are send or responses received. I would setup the post-request macro to use a normal URL parameter - /rest/requests/detail?id=<ID> - and in processMessage rewrite the request to /rest/requests/detail/<ID> In fact, I've had a go at coding an extension for you: https://gist.github.com/pajswigger/b5e980be06f799e70f565601c3349167 Please let us know if you need any further assistance.

Burp User | Last updated: Nov 28, 2017 12:06PM UTC

Hi Paul, thank you so much for your script. This helps a lot in regards to the URL writing, which is great. Unfortunately I am still not quite where I want to be. I totally understand what you want me to do, but in this case I have a problem with the post-request macro then. You want me to set up a post-request macro that does a GET on /rest/requests/detail?id=<ID>. Your extension will to the URL rewriting. That's fine. But in the macro I do not know how to set the id from the originally invoked POST request (like from the intruder or scanner). This seems to be not possible. What is working: Define a macro that issues a POST request itself and replaces the id in the upcoming GET request afterwards. But this won't help as the payload from the intruder or scanner won't be considered and this defined macro is then executed separately. With that in mind my only problem now is to let the post-request macro - the one that only does the GET - somehow get the response from the POST that has been invoked by the intruder or scanner. I hope the problem is somehow understandable.

PortSwigger Agent | Last updated: Nov 28, 2017 12:09PM UTC

Hi Shredder, Oh yes, you're right. If this was a pre-request macro you could define a custom extraction to fetch the JSON token. But that doesn't work for a port-request macro. I've tweaked the extension to rewrite the JSON as a form, which causes the automatic parameter handling to work correctly. This is getting pretty hacky at this point, but it does work. We need: Macro 1: GET /rest/requests/detail?id=123 Session rule: Scope /rest/requests - action, run post-request Macro 1 If that doesn't work for you, then we'll have to leave this. We're right at the limit of Session Handling Rules. Having been though all this, I guess an obvious question is: are we going to make this easier? There is a major update to Spider planned that aims to autodetect things like this.

Burp User | Last updated: Nov 29, 2017 07:49AM UTC

Hi Paul, thank you so much. This is exactly what I needed and it works like a charm. Perhaps it would be a nice feature to pass variables between different macros to do this without scripting? I guess this kind of testing is not that unusual. Again: Thank you very much!

You must be an existing, logged-in customer to reply to a thread. Please email us for additional support.