dnsspoof 是一个DNS欺骗工具,只要给出将要重定向的域名和域名重定向到的IP,就可以实现DNS欺骗。
下载地址:http://monkey.org/~dugsong/dsniff/
dnsspoof是dsniff工具集中的一个。
dnsspoof依赖2个三方库:libpcap , libnet
libpcap下载地址:http://www.tcpdump.org
libnet下载地址:http://code.google.com/p/ips-builder/downloads/detail?name=libnet-1.0.2a.tar.gz&can=2&q=
我这里使用的版本是:
dsniff-2.3.tar.gz
libnet-1.0.2a.tar.gz
libpcap-1.2.0rc1.tar.gz
【源代码编译】
首先编译 libpcap
tar -zxvf libpcap-1.2.0rc1.tar.gz
mkdir /usr/local/libpcap-1.2.0
cd libpcap-1.2.0
./configure --prefix=/usr/local/libpcap-1.2.0/
make
make install
然后编译 libnet
tar -zxvf libnet-1.0.2a.tar.gz
mkdir /usr/local/libnet-1.0.2a
cd libnet-1.0.2a
./configure --prefix=/usr/local/libnet-1.0.2a/
make
make install
dnsspoof 源代码包括下面几个文件:
err.h
err.c
queue.h
pcaputil.h
pcaputil.c
version.h
strlcpy.h
strlcpy.c
dnsspoof.c
strlcpy.h是我添加的头文件,为的是声明strlcpy函数。
size_t strlcpy(char *dst, const char *src, size_t siz);
dnsspoof.c需要修改包含文件路径
#include "sys/queue.h"
#include "err.h"
#include "pcaputil.h"
#include "version.h"
#include "strlcpy.h"
宏定义 in_addr_t
#define in_addr_t u_int32_t
编译命令行是
gcc -g -Wall -o dnsspoof dnsspoof.c pcaputil.c err.c strlcpy.c -I /usr/local/libpcap-1.2.0/include/ -I /usr/local/libnet-1.0.2a/include/ -L /usr/local/libpcap-1.2.0/lib -L /usr/local/libnet-1.0.2a/lib -lpcap -lnet -lresolv -DLIBNET_LIL_ENDIAN
编译后生成可执行文件 dnsspoof
【使用方法】
在本层目录下创建一个文件,dnsspoof.hosts
文件格式为
#[将要重定向到的IP] [空格或者TAB] [将要重定向的域名]
192.168.61.1 www.baidu.com
执行命令行是
dnsspoof -i 网络接口 -f 需要重定向的域名-IP文件 libpcap过滤表达式
./dnsspoof -i eth0 -f ./dnsspoof.hosts udp dst port 53 and src 192.168.61.109
如果想要欺骗本机,需要修改一下dnsspoof.c文件中的代码
snprintf(buf, sizeof(buf), "udp dst port 53 and not src %s",
libnet_host_lookup(lnet_ip, 0));
修改为
snprintf(buf, sizeof(buf), "udp dst port 53 and src %s",
libnet_host_lookup(lnet_ip, 0));
执行dnsspoof的时候就可以不带libpcap过滤表达式
./dnsspoof -i eth0 -f ./dnsspoof.hosts
【源码分析】
main函数首先根据传入的参数 -f hosts 调用dns_init(dev, hosts);
dns_init解析文件,将IP-域名取出后保存到链表中 SLIST_INSERT_HEAD (&dns_entries, de, next);
接着调用pcap_init,pcap_init做的事情就是使用libpcap打开网卡,设置为混杂模式,按给定的过滤器表达式编译、
设置过滤器
接着调用pcap_dloff,取得IP数据头的偏移量
接着使用 libnet 接口函数 libnet_open_raw_sock 创建原始套接字。
接着进入大循环阶段 pcap_loop(pcap_pd, -1, dns_spoof, NULL);
每当有一个数据包被截获,调用 dns_spoof
dns_spoof 函数分析一个 DNS 查询报文,找到需要解析的域名,调用 dns_lookup_a 或者 dns_lookup_ptr 查询链表中保存的域名
检查是不是我们想要欺骗的域名,
如果是,调用 libnet_build_ip,libnet_build_udp,memcpy,libnet_do_checksum,构造一个DNS响应报文,
调用 libnet_write_ip 发送这个构造的报文。
如果不是直接返回。
当应用程序接收到这个响应报文后,gethostbyname 函数就已经返回了。