ssrf – TechKranti https://techkranti.com CyberSecurity Revolution Fri, 13 Dec 2024 10:43:08 +0000 en-US hourly 1 https://wordpress.org/?v=6.7.1 169658937 Preventing/Fixing SSRF Issues https://techkranti.com/preventing-fixing-ssrf-issues/ Fri, 13 Dec 2024 10:43:08 +0000 https://techkranti.com/?p=871 SSRF in a nutshell:

When a server-based application allows end-users to specify a URL that the server then fetches and processes, the application is susceptible to SSRF attacks. Examples of such features include Webhooks, Blog Import, or Profile picture update using URL.

Attackers can abuse this functionality by passing an internal URL that is inaccessible from the Internet but accessible from the application server’s local network.

This can lead to attackers accessing internal systems or cloud metadata endpoints, which can sometimes lead to full cloud compromise.

Fixing or preventing SSRF issues

✅ Don’t introduce an SSRF-susceptible functionality

The best way to mitigate risk is risk avoidance. If the functionality isn’t essential for business, don’t implement features that allow users to specify URLs that are fetched by the application backend.

If you have to add this feature, implement the below checks to prevent SSRF issues.

✅ Prevent bare IP addresses in user-supplied URLs

There is no real need for such features to allow users to enter IP address URLs and these can be safely blocked without any side effects.

It is extremely difficult to assess whether a bare IP address is safe to fetch in such a functionality. Even if you blocklist internal or metadata IPs, there are ways to get around this using octal IPs, decimal IPs, or IPv6. Implementing more checks leads to more headaches and more potential opportunities for failure.

I have never seen this implemented as a security measure in such functionalities, but I believe that this can eliminate a lot of headaches for developers.

✅ Strict Allow-listing

If the feature is supposed to fetch resources from a limited set of sites, an allowlist of hostnames should be created and the URL passed by the user should be checked against the list of allowlisted hostnames.

If allowlisting does not meet your business use case, then follow the below guidance.

✅ Verify IP by resolving the requested host

Resolve the hostname supplied. After resolution, block requests with the below IPs.

Block IPv4 IPs in the following ranges:

0.0.0.0 – 0.255.255.255

10.0.0.0 – 10.255.255.255

127.0.0.0 – 127.255.255.255

169.254.169.254

172.16.0.0 – 172.32.255.255

192.168.0.0 – 192.168.255.255

Block the following IPv6 IPs:

::1

0:0:0:0:0:0:0:1

✅ Prevent DNS Rebinding Attacks

Just ensuring that the resolved IP of a host does not match a blocklist is not enough. An attack called DNS rebinding can be used by attackers to bypass such checks.

Attackers configure DNS servers to alternate DNS responses between a public IP address and an internal IP address. This way, when the first request is sent to check whether the hostname corresponds to an allowed IP address, the DNS server responds with the allowed IP address.

However, in the subsequent request that is sent when actually fetching the resource, the DNS server responds with an internal IP address.

This can be prevented by forcing the HTTP client module to use the IP address resolved in the validation step.

This way, you can ensure that the HTTP request sent to fetch the resource is sent to the IP address that has already been validated instead of relying on the subsequent resolution.

✅ Only allow http: scheme in the URL

This can be done to prevent attackers from providing schemes such as file: that can be abused to trick the application into fetching local files. Or worse, protocols like gopher: can be used to send system commands on open ports.

✅ Finally, don’t follow redirects

All the above checks may fail, if you allow the HTTP client to follow redirects. Redirects can be abused to cause the HTTP client to hit a restricted endpoint via a redirect.

Hope this helps you better secure your application code. If you have any questions or if you would like to discuss further, please feel free to get in touch via LinkedIn.

]]>
871
How I discovered an SSRF leading to AWS Metadata Leakage https://techkranti.com/ssrf-aws-metadata-leakage/ Mon, 10 Feb 2020 18:21:44 +0000 http://techkranti.com/?p=75 I am writing this story to share an experience I had recently discovering an SSRF vulnerability for a private program on H1. Since the program is private, I won’t divulge much information related to the platform, rather I will discuss my thought process when testing for this vulnerability.

The Vulnerable Endpoint

This platform allowed user to upload a bunch of filetypes. To be precise about the filetype the platform supported, I am just going to post the input file HTML tag straight from the page:

<input type="file" class="button button--invert" onclick="this.value = null;" ngf-accept="file_input_accept_string || utils.FILE_INPUT_ACCEPT_STRING" ngf-select="onFileSelect($files)" accept=".jpg,.jpeg,.png,.tiff,.eps,.ico,.gif,.bmp,.txt,.md,.pdf,.html,.htm,.rtf,.doc,.docx,.xls,.xlsx,.ppt,.pps,.ppsx,.pptx,.dot,.dotx,.xlt,.xltx,.odt,.oth,.odg,.odp,.ods,.odi,.oxt,.csv,audio/*,text/*,application/msword*,application/vnd.ms-*,application/vnd.oasis.opendocument.*,application/pdf">

Whatever filetype you upload to the platform, it converts the file to a PDF soon after upload. One filetype that caught my eye from the above list was “.html”. I started mentally reverse engineering the server backend responsible for generating the PDF from the HTML file.

Hypothesis #1:
My initial guess was that the server must be using some sort of a headless browser to render the HTML page and then exporting the page to PDF. My best guess was that it would be a headless Chromium running via Puppeteer. It was time to verify my hypothesis. I put together a basic HTML file and checked Burp for the response body when downloading the PDF file. Turned out, it wasn’t using Headless Chrome. PDFs created using headless Chrome have a Creator tag with the value “Skia/PDF m77”. Skia is graphics library created and maintained by Google. It is responsible for the ‘Save As PDF’ feature you use on Chrome. Hypothesis #1 disproven.

I had no other hypothesis to understand how this PDF must have been generated. Now, was the time to probe deeper. I wanted to understand if the rendering engine used by the backed attempted to access external resources referenced in the webpage.

Question #1: Does the renderer access external resources?
I put together this simple HTML to test if external resources are accessed.

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Attack</title>
  </head>
  <body>
    <img src="https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_2x.png"/>
  </body>
</html>

Let’s see what the server produces for us:

The answer is YES. The server does download external resources. This is where I realized that I may find a wonderful SSRF here. Moving ahead. Next question that came to my mind.

Question #2: How does the HTTP request look like when the server fetches external resources?
To check for SSRF, most people like to use Burp Collaborator. I, on the other hand, like to use https://postb.in. So, I created a postbin and generated the following HTML file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Attack</title>
  </head>
  <body>
    <img src="https://postb.in/1581356305957-2842711033299?hello=world"/>
  </body>
</html>

Now, let’s see what the server gives out. I uploaded this file, waited for the PDF generation to complete and headed over to postb.in to check the fetch log. This is what postb.in had to show:

Sweet!

Large programs will accept and award such a report because it exposes the real IP address of the requesting server. But I did not stop here. I wanted real impact to show.

On further analyzing the HTTP request, I noticed this weird looking user-agent string: wkhtmltopdf. The name itself reveals half the story. This is probably some library used by the server to convert HTML files to PDF. I googled it and was directed to https://wkhtmltopdf.org/. OK, so my Question #1 was answered. This is how the server converted HTML to PDF. This also partially proves Hypothesis #1 because wkhtmltopdf is indeed a headless user agent.

Now that I had a confirmed SSRF, it was time to try accessing sensitive endpoints or attempt to access internal files. Through initial recon, I had learned that this server was hosted on AWS. So the most sensitive endpoint to test would be the AWS Instance Metadata Service. More about this here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html

Hypothesis #2:
‘wkhtmltopdf’ will render sensitive data on the renderer before processing the output to a PDF. To test this hypothesis, I used the following payload:

  <body>
    <iframe
      src="http://169.254.169.254/latest/meta-data/"
      width="500"
      height="1000"
    ></iframe>
  </body>

And here’s what the server gives us:

Voila!

Hypothesis Proven. That’s impact right there. It feels great to report such critical findings to programs. I reported this vulnerability at night. It was triaged the next morning by H1 staff and rated Critical with a score of 10.0. Sweet!

As a side note, most of the SSRF PoCs will have an attempt to access the internal network. That is true for traditional on-premise hosted servers. On the cloud, that’s not true, unless the company is running a VPC.

Something about the format of my bounty hunting stories:

If you have read to this point, you would probably be wondering that this article does not deserve this length. It would have been easier for the reader if the main PoC was summed up in the first or second para. Yes, you are right. But, I write for myself. When trying to read bug bounty articles, I always try to look for the thought process of the hacker behind the find. Just concentrating on the PoC won’t take you far. Understanding and adapting your thought process is key to bounty hunting. Hence, instead of just writing what worked, I focus on writing how I reached to the final step that leads to the attack.

Happy Hacking!

]]>
75