[ dns hijacker v1.0 ]

pedram amini (pedram@redhive.com)
www.redhive.com

Inspired by an idea I came up with while sitting on the john I set out to 
write a program that would sniff dns requests aned spoof answers. 800 lines
of code and 25 hours later I had given birth to dnshijacker.

The following is a run-down on what it can do, and how you can go about 
doing it.


/**************************************
 *  uses                              *
 **************************************/

Aside from the tremendous comical value of redirecting your friends to gay
porno sites there are a few other (possibly legitimate) uses to dnshijacker.
Firstly, sites can be filtered based on keywords in domain names. Of course
this can easily be bypassed through the usage of a proxy. The seconde, in
my opinion, more useful is to hijack the queries for all the popular ad
servers (such as doubleclick). That way not only are you alleviating
yourself from the ghastly site of advertisements, but you've also upped 
your level of privacy a notch or two.

Along with the prankster, the blackhat will probably find the most uses for
dnshijacker. The possibilities are endless. One could easily mirror a site
(hotmail, etrade, online banking, etc) and redirect requests to that mirror
for login/password collection. Another target for attack is the auto-update
features that most windows applications use. Next time Winamp or AOL Instant
Messenger check for an update, the request can be redirected to yourself,
an "update available" answer can then be spoofed, and a trojan wrapped
executable sent to the victim.

/**************************************
 *  compiling                         *
 **************************************/

dnshijacker was built and tested on an x86 running redhat linux 6.1
it requires libpcap (www.tcpdump.org) and libnet (www.packetfactory.net),
at the time I was using versions 0.4-19 and 1.0 respectively. To compile:

  gcc dnshijacker.c -lpcap -lnet `libnet-config --defines` -o dnshijacker

You can optionally compile with -DDEBUG to enable (messy) debug messages.

/**************************************
 *  command line options              *
 **************************************/

-d <ip address>
You can set the default answer that dnshijacker will respond with using the -d
switch followed by an ip address in normal dotted quad form (xxx.xxx.xxx.xxx).
dnshijacker will use the default address in the case that no match is found for
the current question in the fabrication table or if no fabrication table is present
to begin with.

-f <filename>
The -f switch is used to point dnshijacker to the location of your custom fabrication
table. The file must be readable, see below for a guide to the fabrication table.

-i <interface>
Specify the interface to work on. Pretty simple.

-p
The -p switch puts dnshijacker into print only mode. I use this when I just want to
take a look at traffic patterns to build my fabrication table. It was also useful
during the development/debug stage and I just left it around.

-v
The -v switch will make dnshijacker print more verbose information, basically this
includes all the dnsheader segments.

dnshijacker will also accept an optional tcpdump style filter string. The key to
this is that the program works only on what it can see. This is best explained
by example...

Say I want to only watch dns traffic, but I want to watch traffic both to and from
dns servers. Well in this case the default "udp dst port 53" is not going to cut it,
so we run dnshijacker with:

    dnshijacker -p udp src or dst port 53

What if we wanted to spoof answers, but also wanted to see traffic from dns servers...

    dnshijacker -f ftable udp src or dst port 53

dnshijacker is smart enough not to attempt to spoof answers to answers. The more
practical usage of the filter however is when you want to only hijack certain
peoples questions. Say for example I only want to hijack johnny's (10.0.0.5) questions...

    dnshijacker -f ftable udp dst port 53 and src 10.0.0.5

On a final note, when the -f and -d switches are used together obviously the -f takes
precedence. In the case that a match is not found then dnshijacker will fall back to
using the default address.


/**************************************
 *  the fabrication table             *
 **************************************/

The fabrication table is where you link spoofed answers to real domains. The first
column is the list of domains for which we wish to spoof answers for. The second
column is the answer we spoof with. Anything after the second column is considered
a comment, I prefer to delimit comments with a '#' just to keep things tidy.
Probably the best way to explain the format would be by example. So, say for
instance you want hijack all requests for www.microsoft.com and redirect them to
www.apple.com (17.254.0.91). The table entry would read:

www.microsoft.com       17.254.0.91     # answer = apple.com

Remember that anything past the second column is a comment. What if we want to also
redirect secure.microsoft.com www.insecure.org (208.184.74.98)? ...

www.microsoft.com       17.254.0.91     # www.apple.com
secure.microsoft.com    208.184.74.98   # www.insecure.org

Lastly, say we wanted to redirect <anything>.microsoft.com to www.apple.com...

microsoft.com           17.254.0.91     # www.apple.com

This works because our table entries represent the needle, and the dns question is
the haystack. So as long as the needle exists somewhere within the haystack a match
exists.

The maximum number of entries is currently 50. If you need more then that, change
the define in the header file and recompile.


/**************************************
 *  extras                            *
 **************************************/

Also included in the package are 2 programs ask_dns and answer_dns. These were used
during development/debugging, but I figured someone may find them useful so I left
them in here. ask_dns surprisingly will ask a dns question:

	ask_dns <source_ip> <port> <destination_ip> <port> <dns_id>

answer_dns will write a dns answer. This is actually more useful then ask_dns in that
it can be used to spoof an answer to someone not on your lan. Of course you need to be
able to guess when the victim is looking up the name that you wish to hijack and what
the dns id will be. answer_dns will write <#_packets> packets and increment <dns_id>
by one each time (easing the burden of guessing the id).

	answer_dns <source_ip> <port> <destination_ip> <port> <dns_id> <#_packets>

Both programs use static data, that can easily be changed however by using dnshijacker's
source as a guide.


/**************************************
 *  brief technical rundown           *
 **************************************/

dnshijacker uses the libpcap interface for packet capturing. The program starts off by
initializing the capture device through this interface. Once this and other initialization
is complete dnshijacker falls into an infinite packet capturing loop.

Each captured packet is passed to parse_dns(), which first checks to make sure we
can use this packet and then steps through the packet and pulls out all relevant/necessary
information. parse_dns() is also responsible for building the payload of the answer we are
going to spoof. It does so by first calling search_table(), which will search through the
user specified fabrication table and return (if any) the appropriate answer. Armed with
this information parse_dns() will complete the construction of the payload. All information
generated by parse_dns() is stored in our globally declared structure chewy_center.

The next step is to make sure we want to spoof an answer. First we check if the print only
flag is on, if not we call spoof_dns() and pass to it the socket on which we wish to write.
spoof_dns() will check a few more conditions before attempting to do anything, if the
conditions pass then we will begin constructing our spoof packet. This is all done through
libnet's raw socket API. spoof_dns() builds the packet headers from information stored in
chewy_center, it then tacks on the payload and writes the packet.

EOF