Sunday, May 16, 2021

SSRF to AWS API - HTTP/Image Rebinding??

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.



1 comment:

Using a feature to takeover your account - Hacking an SSO implementation

This week, I found a super cool bug that allowed me to steal any account in the vulnerable application. The target was a private bug bounty ...