Learning about Server Side Request Forgery (SSRF)
SSRF also known as server side request forgery is an all time favourite for bug hunters and it does exactly what it says. Sometimes easy to find and just as easy to exploit. A server side request forgery bug will allow an attacker to make a request on behalf of the victim (the website we're testing) and because this request comes internally this means it is usually trusted and requests will go through. This then opens the window for an attacker to extract something such as AWS keys (as long as you can read the response). To re-iterate, you can control a REQUEST that their SERVER makes. If the server allows for a response then it's easy enough to prove what you can read, however sometimes you can't read the response and this is Blind SSRF, which we'll explore further below.
If you pause right now and google 'SSRF aws' and you will see lots of disclosed issues which can give you a very clear idea on how these are pulled off. A really great report is this one by honoki: https://hackerone.com/reports/508459
Finding SSRF bugs
When hunting for SSRF bugs I first begin primarily with looking for features that will take an URL parameter already. This can mean something such as an API console or webhook and typically these features are found on the developer portal (developer.example.com
or example.com/developer
). The reason for wanting to find & test these features first is because they are designed to take an URL parameter and do something. This means that filering should exist around this feature to prevent malicious requests and you can spend time trying to understand how the filter works and learn to bypass it.
Don't forget to think about PDF generators which allow you to control the input, such as MARKDOWN with HTML, or other elements such as XML The code is executed server side which means code you provide, such as a javascript proof of concept to read file://etc/passwd
, will be processed and rendered in the PDF!
<script>
function resp () {
document.write(this.responseText);
}
var xmlreq = new XMLHttpRequest();
xmlreq.addEventListener("load", resp);
xmlreq.open("GET", "file://etc/passwd");
xmlreq.send();
</script>
Examples of SSRF found in Webhooks and PDF generators
- Webhook https://hackerone.com/reports/243277
- Webhook https://hackerone.com/reports/56828
- Webhook https://hackerone.com/reports/301924
- Webhook https://hackerone.com/reports/344032
- PDF Generator Owning the clout through SSRF and PDF Generators
- PDF Generator Finding SSRF via HTML Injection inside a PDF file on AWS EC2
Sometimes when browsing a website you will even see certain parameter names such as url=
, targetUrl=
, requestUrl=
, path=
. Anytime you see either an URL being supplied in a request, attempt to make a request to a domain you control. If you receive a pingback to your server, start investigating where it came from, and what you can control. (response etc).
As well as features and parameter names infront of you, what about the headers you send? Some websites will send a query to urls in the Referer header to check where a user came from as well as querying X-Forwarded-For
values (such as an DNS request). Simply set Referer: https://www.yourdomain.com
and start logging requests via your own private collaborator server.
Method: DNS Rebinding
If you've got a victims website querying your domain for an DNS answer then you may be able to execute commands behind their firewall. A really great write-up on DNS rebinding can be found here by Daniel Miessler. There is no point in me re-inventing the wheel & explaining it when he does an amazing job. https://danielmiessler.com/blog/dns-rebinding-explained/
Tip: Using open redirects
A lot of researchers will hold onto open url redirects bug for when they discover a potential SSRF bug. This is because sometimes when you have a feature which takes an URL parameter it may block any external requests (such as trying to query example.com
). However with an open url redirect on their domain, you can supply this in the URL parameter and hope that their server follows the redirect & lands you a valid SSRF bug. This is because sometimes the code will trust the root domain and allow the input, but will follow the redirect!
Exploiting SSRF bugs and payloads
When trying to test for SSRF bugs your aim is to prove you can successfully access & read internal content and hopefully read the response, however sometimes reading isn't always possible and we get what is typically called a blind SSRF. This means you can send a request successfully to an internal subdomain/IP but you are unable to read the response. With these type of bugs to prove the impact I recommend trying to send a request to common ports used, for example popular software such as Jira runs on :8080
. If you can prove you can access these internal areas then it should be enough to show impact of the bug.
As well as trying to access certain images used by certain software, attempting to visit a random port vs a common port such as :80
can help prove that the connections are successful. If you try access :1337
and it times out/fails, then perhaps you can begin probing for open ports based on this.
Common SSRF payloads - don't forget to try with https:
and http:
- http://127.0.0.1:80
- http://0.0.0.0:80
- http://localhost:80
- http://[::]:80/
- http://spoofed.burpcollaborator.net
- http://localtest.me
- http://customer1.app.localhost.my.company.127.0.0.1.nip.io
- http://mail.ebc.apple.com redirect to 127.0.0.6 == localhost
- http://bugbounty.dod.network redirect to 127.0.0.2 == localhost
- http://127.127.127.127
- http://2130706433/ = http://127.0.0.1
- http://[0:0:0:0:0:ffff:127.0.0.1]
- localhost:+11211aaa
- http://0/
- http://1.1.1.1 [email protected]# @3.3.3.3/
- http://127.1.1.1:80\@127.2.2.2:80/
- http://127.1.1.1:80\@@127.2.2.2:80/
- http://127.1.1.1:80:\@@127.2.2.2:80/
- http://127.1.1.1:80#\@127.2.2.2:80/
- http://169.254.169.254
- 0://evil.com:80;http://google.com:80/
Source: You can view more here: SwisskyRepo - PayloadsAllTheThings
Bypass via redirect (that you host)
If all your attempts to acesss internal content fail then what you can try testing how they handle redirects from an url you control (rather than needing to use an open url redirect). Using some basic PHP code (or via other means such as using https://bugbounty.dod.network
) you can force a redirect to internal services.
<?php
header("Location: 127.0.0.1");
?>
The logic behind the developer is: If this url is 127.0.0.1
then block. But because we provided our URL, example.com
, the code allows it but follows the redirect & to 127.0.0.1
and outputs internal content. Bypassed!
  Tip from @zseano
When wanting to find SSRF I will always look for any sort of developer portal which may contain something such as web hook testing. These areas let you naturally input an URL so filtering will usually exist. Filters that can be bypassed..!
Test your knowledge with BugBountyHunter Challenges
-
We have free labs for this vulnerability coming soon. Currently it is only available on our members web application BARKER.