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'])defindex(): url = request.form['text'] parser =urlparse(url).hostname info = socket.gethostbyname(parser) global_check = ipaddress.ip_address(info).is_globalif info notinBLACKLISTand global_check ==True:returnrender_template('index.html',mah_id=requests.get(url).text)elif global_check ==False:returnrender_template('index.html',mah_id='Access Violation: Private IP Detected')@app.route('/flag')defflag():# only allow access from localhostif request.remote_addr !='127.0.0.1':return'Unauthorized!',401returnsend_file('./flag.txt')
The Vulnerability: Double DNS Resolution
The web application resolves the domain name twice:
socket.gethostbyname(parser) - for the SSRF filter check
requests.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 TTL
Submit URLhttp://attacker.htb/flag to the web application:
First resolution β 1.1.1.1 (passes is_global check)
global_check = True β proceeds to render_template
Rebind DNS to resolve attacker.htb to 127.0.0.1
Second resolution (by requests.get) β 127.0.0.1
Web application fetches http://127.0.0.1/flag
Flag 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.get
Provide URL http://ourdomain.htb:8000/flag
Breakpoint triggers after SSRF filter passes
Rebind in /etc/hosts:
Continue execution β requests.get resolves to 127.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.1
B: 1.1.1.1
Generated 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 be 127.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)
Starting nameserver...
UDP server loop running in thread: Thread-1
TCP server loop running in thread: Thread-2
Got a request for attacker.com. Type: A
------------------------ Counter for host attacker.com. 1
---- Reply:
;; ANSWER SECTION:
attacker.com. 0 IN A 1.1.1.1
Got a request for attacker.com. Type: A
------------------------ Counter for host attacker.com. 2
---- Reply:
;; ANSWER SECTION:
attacker.com. 0 IN A 127.0.0.1