4 ms·
I imagine one way to do it is to make the attacking request to a redirect. Since the back-end conflates the attacking request and the next request (or a portion
by kbenson 7y ago
I imagine one way to do it is to make the attacking request to a redirect. Since the back-end conflates the attacking request and the next request (or a portion of the next request), you can get that next request, including the headers (i.e. cookies) as the body/payload redirected to that external site. If the attacker controls that external site, they then can see the cookie data.
Another way would be to make it so the next request is the content of a param which is displayed in some manner. For example, if it's the content to a message post to a slack forum.
Those different than what they outline in the article, but neither seems unlikely to be found on the back-end in some manner. Redirects are often locked down, but not always, and finding something that sends a variable back to you (such as a form port target that you know will error "helpfully") doesn't seem like it would be hard to me.
- bawolff 7y agoI'm not sure I am understanding > I imagine one way to do it is to make the attacking request to a redirect. Since the back-end conflates the attacking request and the next request (or a portion of the next request), you can get that next request, including the headers (i.e. cookies) as the body/payload redirected to that external site. If the attacker controls that external site, they then can see the cookie data. Are you suggesting that if the backend server was setup as an HTTP proxy, you could get the backend server to proxy the merged request somewhere else? That's true, but it seems pretty unlikey that the backend servers would be setup that way. Although i think i might just be misunderstanding what you mean. > Another way would be to make it so the next request is the content of a param which is displayed in some manner. For example, if it's the content to a message post to a slack forum. I.e. you're suggesting basically using this as a CSRF attack to post part of the victims request (including secret cookie) somewhere public to retrieve later? I think this would work in certain situations but would be difficult to pull off. Its a bit more complicated because if the site was using csrf tokens you would need to make sure the victim request was a POST with a token,but that is easy enough - retry until it happens. The bigger issue is the request body would be kind of malformed. If the endpoint you are posting to accepts application/x-www-urlencoded (and not json), i imagine its interpreted super liberally. I guess the biggest issue is if ; is considered a form field separator (since user-agent usually has ; in it). I think some standards tried to promote that, but i dont know if webservers actually implement it. If they do,it would be very difficult for the attacker to control the name of the form field, and thus actually get the part they wanted publicly posted
- kbenson 7y ago> Are you suggesting that if the backend server was setup as an HTTP proxy, you could get the backend server to proxy the merged request somewhere else? I'm suggesting that since the back-end server may see the requests as a single request with the second request as part of teh payload of your crafted request, the question then becomes one of "In what ways can I get this site to show one of my params". That's similar to a CSRF, but simpler in that that you don't care that it's unescaped, you just care that it's in the source in some way, since it's what should be displayed back to you for your request. My form example is straightforward. Imagine you are requesting http://slack.com/help/search http://slack.com/help/search. If you reorder the params slightly, such that the "query" param is last, you might get a good chunk of the next request to be sent to the back-end as your query param, which slack will helpfully display for you both on the page and in in the search input on the resulting page. It will clean our newlines, and likely some other characters, but that hardly seems a problem. > I.e. you're suggesting basically using this as a CSRF attack to post part of the victims request (including secret cookie) somewhere public to retrieve later? Yep. > I think this would work in certain situations but would be difficult to pull off. Its a bit more complicated because if the site was using csrf tokens... I just found one and used it in an example above. Took me less than 5 minutes (I tried a different form that did have a csrf token first). > The bigger issue is the request body would be kind of malformed. That's a problem for if you want it to look legit to someone else. If you just have to note that it has the equivalent of /\sCookie:\s(\S+)\s/ in it... well that's not too bad. Removing the newlines makes it all one string, but in the example above they helpfully replace them with spaces. Even if they didn't, it's probably not hard to see where the next header begins. > I guess the biggest issue is if ; is considered a form field separator (since user-agent usually has ; in it). Depends on how you do it. My example above uses GET, so any ampersand (which is probably likely to exist in many queries) will throw it off. A POST might offer more options. Even with the GET, you might be able to run it enough times to find a post as the included second request, and that's less likely to have an ampersand in the URL, and you would probably scoop up all the headers at least. If you post with multipart mime, depending on how lenient it is on a final terminator, you might not have any problem at all if you find the right page to post to. I did just confirm that that same search page doesn't seem to honor params passed in a POST, so that's good (for Slack). I think the bottom line is that once you can make part or all of someone else's HTTP request show as part of your request's payload, it's a drastically lower bar for exploiting, as there are many possible ways to exfiltrate the data at that point, and they only have to screw up by allowing one of them to work.