DNS Rebinding SSRF Bypass
After exploring how to bypass flawed SSRF filters with techniques such as localhost obfuscation, DNS resolution, and HTTP redirects, let us now bypass them using DNS rebinding.
Code Review - Identifying the Vulnerability
In this section, we will analyze D-Proxy, a web application that acts as a URL proxy; it allows us to specify any URL, and then it fetches and renders it for us.
Vulnerable Code
D-Proxy has two endpoints, of which one is only accessible locally (/flag):
@app.route('/', methods=['POST'])
def index():
url = request.form['text']
parser = urlparse(url).hostname
info = socket.gethostbyname(parser)
global_check = ipaddress.ip_address(info).is_global
if info not in BLACKLIST and global_check == True:
return render_template('index.html', mah_id=requests.get(url).text)
elif global_check == False:
return render_template('index.html', mah_id='Access Violation: Private IP Detected')
@app.route('/flag')
def flag():
# only allow access from localhost
if request.remote_addr != '127.0.0.1':
return 'Unauthorized!', 401
return send_file('./flag.txt')The Vulnerability: Double DNS Resolution
The web application resolves the domain name twice:
socket.gethostbyname(parser)- for the SSRF filter checkrequests.get(url)- to actually fetch the content
This makes the filter vulnerable to DNS rebinding.
Attack Methodology
Configure your domain (e.g.,
attacker.htb) to resolve to a non-blacklisted IP (e.g.,1.1.1.1) with a very low TTLSubmit URL
http://attacker.htb/flagto the web application:First resolution β
1.1.1.1(passesis_globalcheck)global_check = Trueβ proceeds torender_template
Rebind DNS to resolve
attacker.htbto127.0.0.1Second resolution (by
requests.get) β127.0.0.1Web application fetches
http://127.0.0.1/flagFlag is returned!
Critical: The timing must be extremely precise - DNS rebinding needs to occur between the two DNS resolutions.
Debugging the Application Locally
Setup
Add the domain to /etc/hosts:
Simulate DNS Rebinding
Set breakpoint before
requests.getProvide URL
http://ourdomain.htb:8000/flagBreakpoint triggers after SSRF filter passes
Rebind in
/etc/hosts:
Continue execution β
requests.getresolves to127.0.0.1β flag obtained!
Exploitation
Method 1: Using rbndr.us (Internet Required)
rbndr.us generates a domain that randomly resolves to two specified IP addresses.
Configuration:
A:
127.0.0.1B:
1.1.1.1Generated hostname:
7f000001.01010101.rbndr.us
Exploit:
Note: Since resolution is random, multiple attempts may be needed (first resolution must be
1.1.1.1, second must be127.0.0.1).
Method 2: Custom DNS Server with DNSrebinder (No Internet Required)
For internal networks without Internet access, use a rogue DNS server.
Requirements:
Compromise internal DNS configuration (via Webmin, PiHole, PRTG, ManageEngine, etc.)
Redirect DNS traffic to your rogue DNS server
Exploiting Internal Webapps
Scenario
D-Proxy vulnerable to DNS rebinding on internal network
Webmin server on port 10000 (can modify DNS configuration)
Step 1: Access Webmin
Default credentials: admin : <BLANK>
Step 2: Modify DNS Configuration
Navigate to:
Set DNS server to attacker's IP.
Step 3: Start Rogue DNS Server
Install DNSrebinder:
Start the DNS server:
Arguments explained:
--domain attacker.com- domain to handle--ip 1.1.1.1- first resolution (passes filter)--rebind 127.0.0.1- subsequent resolutions (bypasses filter)--counter 1- rebind after 1 request
Step 4: Exploit
Submit URL to D-Proxy:
DNS Server Output:
First query β 1.1.1.1 (passes filter) Second query β 127.0.0.1 (accesses /flag)
Question Walkthrough
Task: Get the flag from the /flag endpoint using DNS rebinding.
Step 1: Configure Webmin DNS
Navigate to
http://<TARGET_IP>:10000Login with
admin:<blank>Go to:
Networking β Network Configuration β Hostname and DNS ClientSet DNS server to your tun0 IP:
Step 2: Setup DNSrebinder
Step 3: Exploit
Visit the D-Proxy web app and search for:
The first DNS resolution returns 1.1.1.1 (passes filter), the second returns 127.0.0.1 (bypasses to localhost).
Last updated