Hello guys, I am here to write about one of my favorites founds on a Bug Bounty program, a SSRF that allow me to reach the AWS internal API (aka: 169.254.169.254).
PS: This post is a translation of my original post I made in Portuguese a few months ago, sorry if something is grammatically wrong, English is not my first language
The Site
The site itself has quite simple, its basically a windows
Paint but with steroids, you can upload images and play with it.
The Flaw
While testing the upload image function I notice that is possible to choose an image from flicker.com and use it on my project, so using BurpSuite I try to debug this functionality and notice that the request is not that restrictive.
As you guys can see is possible to completely control the URL
parameter, and not necessary I need to use flicker.com
So, the first thing I try is to change the URL parameter to
point to my VPS, I get a request on my server (using python3 http.server) but
the response I got from the original request was just a generic error message talking
“only imagens allowed”. I upload an image on my VPS and just try again, but
this time a pass the URL to the image (http://my.vps/image.png).
To my surprise a got two requests to /image.png, at first
this went unnoticed, but when I notice I think “When I point to my server
without a valid image, I just got one request with leads to an error message,
but with a valid image I got two requests. Maybe I can try something like DNS
rebind but with HTTP”. For those unfamiliar, DNS rebinding is a technique to
circumvent SSRF protections, because the vulnerable application performs two
DNS requests before the HTTP request, the first is used to validate a filter,
for example blocking if the DNS resolves 127.0.0.1, as the server will make a
second DNS request to fetch the contents of the page later, only the first
resolution cannot point to 127.0.0.1 but the second (and more important) can.
I can try something like this, but with HTTP instead of DNS,
so I write a simple NodeJS server with express, the code is the following:
const express = require('express')
const app = express()
var c = 2
app.get('/', (req, res) => {
console.log(req.rawHeaders)
if(c % 2 === 0)
{
c++
return res.sendFile(__dirname + '/static/tunnel.jpg') //my jpg file
}
return res.redirect("http://169.254.169.254/latest/dynamic/instance-identity/document")
})
Basically, the server will respond the first request with a
valid image and the second request with a redirect to the AWS API. To my
happiness the code works in the first try.
And I won a bounty.


