What is DNS Rebinding?
Imagine you are a comuter :D People give you URLs and you load them
Of course you won’t load url that points to your internal network… That would be stupid right?
Because of this some clever developer wrote code like this to prevent it from happening
To make explaining this easier
ip_banlist
is list of IPs you are blockingdomain
is the URL you are trying to fetchgetHostname
is a function that resolves a domain/URL to actual IP address or translates it from eg. octal to IPV4/6import requests from core_funcs import getHostname from banlists import ip_banlist def secureFetch(domain): if getHostname(domain) not in ip_banlist: r = requests.get(domain) return r.text
“You can’t just bypass this”
— a not so clever Developer
Turns out I actually can!
And that’s what DNS Rebinding is about!
Let’s go through the function line by line
- Let’s say the function is ran with
domain='http://wtf.geleta.eu'
and that theip_banlist = ['169.254.169.254', '127.0.0.1']
- First it runs a DNS query with wtf.geleta.eu which returns 12.34.56.78 which is not in
ip_banlist
so our journey continues!!! - In the meantime the DNS record for wtf.geleta.eu magically changes to 127.0.0.1 ๐ฆน๐ปโ
- now the request is made to
http://wtf.geleta.eu
so again somewhere in therequests.get()
the dns query is ran again and now with DNS record changed to 127.0.0.1 Soooo there’s nothing stopping us from retrieving localhost ๐๐๐
So that’s the theory behind this whole thing. Pretty primitive right?
What do we actually need to make this happen
- Since we can’t manually change the dns record in milliseconds as the program runs, we need a custom DNS server configured to somehow figure out what IP should it resolve to and set TTL to 0 so no caching happens on the backend
- Some “interface” to configure the domain - what should it resolve to, how many times, stuff like this
- A fair bit of luck obviously
When I found this bug I used https://lock.cmpxchg8b.com/rebinder.html but later on I figured out that it’s not ideal, it only takes 2 IPs and resolves between them randomly so I have to send like 100 requests to get 1 that actually went to localhost :D
(This was about 7-8 months ago, I made my own tool for this. So expect little product placement at the end of the post!)
How it went down with the actual vulnerability
I stumbled upon a service that I can configure to make a json request, set headers, etc. Then it gives me the http response
When i set the url to some internal/banned ip like 127.0.0.1
it gave me something like: The request was blocked
After few hours of trying to bypass it I was like “This is unbreakable, I’m gonna get some food”
Then I got some food and minute after that I remembered that my friend Jan Masarik did one challenge when we were hacking Fireshell CTF 2019 ctf with our CTF team The challenge was about dns rebinding. Writeup: https://ctftime.org/writeup/13005
The actual ctf challenge was created by ELB so If you are reading this I just want to say BIG thank you for making this challenge!
So I used the technique from writeup. I set the rebinding to 127.0.0.1/google ip and after sending 100 request with burp intruder 2 of them came back with different lenght than others, I click on one of them and see a html code with title which was name of the company
And I was like
NO WAY!!!!! IT ACTUALLY FUCKING WORKED WTFFFFFF I’M A 1337 HAXXXXXOR NOW
With dns rebinding confirmed, I didn’t actually know what to do… Everything I have ever hacked before were just ctfs - and this is where the challenge usually ends, you have the flag and your are good to go
It doesn’t work that well IRL
Now all I had was some ssrf that I didn’t know what I can use it for.
Few hours went by and there I was sending keybase message to Jan Masarik because I was stuck again. I told him that it was an amazon instance and he sent me some ip adress - 169.254.169.254 I clicked on it and nothing happened, that IP didn’t exist Then he told me that it is the aws metadata IP and if I can retrieve data from there, I basically own their whole aws (It wasn’t completely true as you find out in a while but I was really really excited) I immediately fired up intruder and in few seconds I recieved a response with aws keys
Now again I was like
And I love the ssrfs too!
Back Into reality
Those were some trashy keys, I couldn’t do almost anything with them…
Turns out I can only r/w some buckets but there weren’t any useful, those that were hosted on frontend weren’t writable (my favorite was the one with cookbooks - see screenshot) It made me laugh but I was disappointed. I tried to escalate my privs for another few hours and-or figure out what else could I do but there wasn’t much of it :(
Ok so the vuln had some Impact so I could report it. I set severity to P2 Now all left to do was enumerate and possibly get a RCE if I was lucky
Fast forward a week
I didn’t have any response from the company,no fix, no lawsuit, nothing at all. Perhaps I should report it as P1. But whatever! It was good for me, I could enumerate more.
AAAAND After chaining with other ssrf…
This was a bit easier - there was a ftp connection vulnerable to ssrf - When some other service than ftp was passed in, let’s say 127.0.0.1:22 server errored out with Bad FTP RESPONSE: SSH-2.0-OpenSSH_someversion
So using this I was able to enumerate open internal ports on their server
Another thing that was possible was bruteforcing ftp credentials on 127.0.0.1:21 since it was open too, I tried it with top-1k but it didn’t work out :(
So I just enumerated the ports…
Fast forward another few hours
I found a Monit Admin interface I was able to interact with via dns rebinding ssrf It had an buffer overread vuln so I was able to read some memory (+1 point in impact :D) Aaand I could shut down the whole instance using shutdown function in Monit (+10 points)
Then I reported this too!
I got a response in a fucking month………
Meanwhile I turned into skeleton
But eventually they responded! They fixed it, gave me a not that big bounty (It’s a small program), everyone was happy, life went on :D
Lessons learned
Bugs exist everywhere
I you are stuck, go back few steps and start again
If you are stuck after doing the step above - message your mentor/more expirienced hacker they will always help you
Be patient AF
If you have free time, create some great tool! or contribute to other great tools
BB is not entirely about money, It’s more about the things you learn
Now it’s time for some self-advertisment
Are you tired of exploiting DNS Rebinding without gui?
This may sound Scriptkiddie-ish but I actually wanted something with gui and logs
How it went down
I was on a vacation and I got sick probably from the food and I couldn’t go out swimming. So I pulled out my laptop and started working on a Flask api connected to modified dns server via SQL and Redis… And I Can’t forget the React frontend, It was the worst thing of it all. Sorry frontend fanboys, I just value my mental health.
After 1.5 days Everything except from the React app of course was done, You can actually check the code out Here and the Live Version with dns server and everything is Here - you can register, create rebind rules, use it to hack something, watch logs and stuff like that. Yes it’s and http link I know that and I hate myself for that but I’m too lazy to spend 2 minutes with certbot
For those who didn’t look thamselves what it does is
I tell it to make a subdomain that will resolve to
1.2.3.4
3 times and then to127.0.0.1
1 timeIt puts the data into db and gives me something like
y1982ehiuwqh82319j2139821.gel0.space
when I make a query to this domain, dns server looks into db, loads the data into redis for quicker future access and then resolves it based on the rules given
If you have a bit of free time, don’t watch netflix - Hack, create and most importantly contribute to https://github.com/makuga01/dnsFookup ๐ I will be veryveryvery happy if someone adds some feature to it or adds something to the frontend, the BE api is nice and working but the frontend is a problem for me
Anyway thanks for reading! Hope you liked this writeup, If you have some questions/suggestions/you just wanna talk with some cringy script kiddie just DM me on twitter @marek_geleta or anywhere else I will almost certainly respond to you in few minutes, I like talking to people ๐
I’m sorry for the amount of text/things learned I will get better I promise, I just like writing stories with incorrect grammar
PS.
sory for my Englandish, It not my primar languge