论文部分内容阅读
[摘要]DNS欺骗攻击是攻击者常用的手法,它具有隐蔽性强、打击面广、攻击效果明显的特点。分析在以太网中利用对网络数据监听,来截获DNS报文,进而伪造DNS报文进行DNS欺骗的技术,并给出基于WinPcap的实现。
[关键词]DNS 欺骗 监听 WinPcap
中图分类号:TP3文献标识码:A文章编号:1671-7597(2009)0810042-01
一、DNS欺骗的基本原理
我们在设置我们的网络时经常要设置DNS地址。当我们输入一个网址的时候,就有一个DNS请求发到设置的DNS服务器上去,然后DNS服务器告诉你你访问的网站对应的IP。于是你的浏览器就会到相应的IP上面去取回网页。那么如果我想欺骗你,我只需要在DNS服务器给你答复之前给你一个假的回答就可以了。但在三层交换网络中,只有广播包会发到所有端口,其他包都只会在对应端口之间传送。要让他的DNS查询发到你的机器上来就需要伪装成网关,因为我们是通过网关上网,所以所有外发的包都要过网关。
而且ARP是后更新的,他和DNS相反,DNS对先到的回答做相应,ARP对后到的消息做缓存更新,于是我们就想出了一个好办法,比如我的MAC是01:02:03:04:05:06。首先,我告诉我想欺骗的主机,我是网关,比如我给172.30.52.174的主机发一个ARP查询或应答包说172.30.52.1(网关)对应的MAC是01:02:03:04:05:06,同时告诉网关172.30.52.174
的IP对应的MAC是01:02:03:04:05:06于是172.30.52.174把发给网关的包都给了我,同时网关也把给172.30.52.174的包都给了我,我在他们之间做一个包转发,就行了,这样所有的包都通过我了,后面的DNS欺骗就和前面一样了。
二、系统流程图
三、打开网卡并捕获数据流
DNS欺骗的基础是捕获DNS请求的数据包。首先我们就介绍如何捕获数据包。promisc指明网卡处于混杂模式,在正常情况下网卡只接受去往它的包而去往其他主机的数据包则被忽略。相反当网卡处于混杂模式时他将接收所有的流经它的数据包:这就意味着在共享介质的情况下我门可以捕获到其它主机的数据包。大部分的包捕获程序都将混杂模式设为默认,所有我们在下面的例子里也将网卡设为混杂模式。
to_ms参数指定读数据的超时控制,超时以毫秒计算。当在超时时间内网卡上没有数据到来时对网卡的读操作将返回。还有,如果网卡处于统计模式下to_ms还定义了统计的时间间隔。如果该参数为0那么意味着没有超时控制,对网卡的读操作在没有数据到来是将永远堵塞。如果为-1那么对网卡的读操作将立即返回不管有没有数据可读。
一旦网卡被打开,就可以调用pcap_dispatch()或pcap_loop()进行数据的捕获,这两个函数的功能十分相似不同的是pcap_dispatch()可以不被阻塞,而pcap_loop()在没有数据流到达时将阻塞。在简单的例子里用pcap_loop()就足够了,而在一些复杂的程序里往往用pcap_dispatch()。
这两个函数都有返回的参数,一个指向某个函数(该函数用来接受数据如该程序中的packet_handler)的指针,libpcap调用该函数对每个从网上到来的数据包进行处理和接收数据包。另一个参数是带有时间戳和包长等信息的头部,最后一个是含有所有协议头部数据报的实际数据。
四、一些协议和数据结构
首先我们来看DNS的包结构,我们知道DNS可以通过TCP也可以通过UDP传输,不过实际使用中99%以上使用UDP。所以下面只是对UDP的DNS做阐述。
DNS包结构是:以太网头+IP头+UDP头+DNS部分(B代表字节)
从以太网头开始:目的MAC(6B) | 源MAC(6B) | 0x0800(2B表示上层是IP)
IP头:协议版本和IP头长度(1B) | 服务(1B) | IP包长度(2B,去以太网头的长度) | ID号(2B) | 标识(1B) | 偏移(1B) | TTL(1B) | 0x11(上层协议UDP) | IP校验和(2B) | 源IP(4B) | 目的IP(4B)
UDP头:源端口(2B) | 目的端口(2B) | UDP包长度(2B,去以太网头和IP头) | UDP校验和(2B)
DNS部分:ID号(2B很重要) | 标识(2B) | 问题数目(2B) | 回答数目(2B) | 权威回答数目(2B) | 附加数目(2B) | 问题字段(长度不定) | 回答字段(长度不定) | 权威字段(长度不定) | 附加字段(长度不定)
问题和回答,权威,附加都是RR记录格式,格式如下:
名字(2B) | 类型(2B) | 类(2B) | 存活时间(4B) | 数据长度(2B) | IP地址(4B)
我们本着越简单越好的做法,构造尽量短的回复,所以回答个数为1,权威和附加都为0。如果是请求包,到问题字段就完了,如果是回答,还有构造回答字段。
五、DNS应答包
下面开始构造伪造包:
以太网部分:交换源和目的的MAC地址。IP部分:计算修改包长度为你构造的假包IP部分长度,标识改为0x04(不分段),校验和改为你计算的IP首部校验和,交换源和目的IP。UDP部分:交换源和目的端口号,包长度改为你构造的假包UDP部分长度。校验和可以添0x0000或者自己算(是可选字段,首先计算费时间,影响发包速度,其次容易算错,我算了3天,老是错,原来要加一个UDP伪头,参考《TCP/IP祥解》)。DNS部分:问题数0x0001,回答数0x0001,权威0x0000,附加0x0000,问题字段直接拷贝,回答字段如下:名字0xc00c,类和类型都是0x0001,时间添长点,长0x0004,IP:你想转向的IP地址。
到这里假的应答就伪造好了。先简要说说代码,这里只有构造DNS回应部分的代码,我们还做了网址匹配,捕获到数据包以后首先判断是否欺骗此IP,如果欺骗再构造欺骗数据包并发送给改机器,否则不处理。同时对不同的域名返回不同的地址。只有别人输入相应的网址才给转向指定的IP地址。
参考文献:
[1]蒋东兴、林鄂华,Windows Sockets网络程序设计指南,北京:清华大学出版社,1995年,7-29.
[2]Mclean著,《Windows 2000 TCP/IP技术内幕》,北京机械工业出版社,2001.10.
[3]Thomposn著,《MFC开发人员参考手册》,北京:机械工业出版社,1998.8.
[关键词]DNS 欺骗 监听 WinPcap
中图分类号:TP3文献标识码:A文章编号:1671-7597(2009)0810042-01
一、DNS欺骗的基本原理
我们在设置我们的网络时经常要设置DNS地址。当我们输入一个网址的时候,就有一个DNS请求发到设置的DNS服务器上去,然后DNS服务器告诉你你访问的网站对应的IP。于是你的浏览器就会到相应的IP上面去取回网页。那么如果我想欺骗你,我只需要在DNS服务器给你答复之前给你一个假的回答就可以了。但在三层交换网络中,只有广播包会发到所有端口,其他包都只会在对应端口之间传送。要让他的DNS查询发到你的机器上来就需要伪装成网关,因为我们是通过网关上网,所以所有外发的包都要过网关。
而且ARP是后更新的,他和DNS相反,DNS对先到的回答做相应,ARP对后到的消息做缓存更新,于是我们就想出了一个好办法,比如我的MAC是01:02:03:04:05:06。首先,我告诉我想欺骗的主机,我是网关,比如我给172.30.52.174的主机发一个ARP查询或应答包说172.30.52.1(网关)对应的MAC是01:02:03:04:05:06,同时告诉网关172.30.52.174
的IP对应的MAC是01:02:03:04:05:06于是172.30.52.174把发给网关的包都给了我,同时网关也把给172.30.52.174的包都给了我,我在他们之间做一个包转发,就行了,这样所有的包都通过我了,后面的DNS欺骗就和前面一样了。
二、系统流程图
三、打开网卡并捕获数据流
DNS欺骗的基础是捕获DNS请求的数据包。首先我们就介绍如何捕获数据包。promisc指明网卡处于混杂模式,在正常情况下网卡只接受去往它的包而去往其他主机的数据包则被忽略。相反当网卡处于混杂模式时他将接收所有的流经它的数据包:这就意味着在共享介质的情况下我门可以捕获到其它主机的数据包。大部分的包捕获程序都将混杂模式设为默认,所有我们在下面的例子里也将网卡设为混杂模式。
to_ms参数指定读数据的超时控制,超时以毫秒计算。当在超时时间内网卡上没有数据到来时对网卡的读操作将返回。还有,如果网卡处于统计模式下to_ms还定义了统计的时间间隔。如果该参数为0那么意味着没有超时控制,对网卡的读操作在没有数据到来是将永远堵塞。如果为-1那么对网卡的读操作将立即返回不管有没有数据可读。
一旦网卡被打开,就可以调用pcap_dispatch()或pcap_loop()进行数据的捕获,这两个函数的功能十分相似不同的是pcap_dispatch()可以不被阻塞,而pcap_loop()在没有数据流到达时将阻塞。在简单的例子里用pcap_loop()就足够了,而在一些复杂的程序里往往用pcap_dispatch()。
这两个函数都有返回的参数,一个指向某个函数(该函数用来接受数据如该程序中的packet_handler)的指针,libpcap调用该函数对每个从网上到来的数据包进行处理和接收数据包。另一个参数是带有时间戳和包长等信息的头部,最后一个是含有所有协议头部数据报的实际数据。
四、一些协议和数据结构
首先我们来看DNS的包结构,我们知道DNS可以通过TCP也可以通过UDP传输,不过实际使用中99%以上使用UDP。所以下面只是对UDP的DNS做阐述。
DNS包结构是:以太网头+IP头+UDP头+DNS部分(B代表字节)
从以太网头开始:目的MAC(6B) | 源MAC(6B) | 0x0800(2B表示上层是IP)
IP头:协议版本和IP头长度(1B) | 服务(1B) | IP包长度(2B,去以太网头的长度) | ID号(2B) | 标识(1B) | 偏移(1B) | TTL(1B) | 0x11(上层协议UDP) | IP校验和(2B) | 源IP(4B) | 目的IP(4B)
UDP头:源端口(2B) | 目的端口(2B) | UDP包长度(2B,去以太网头和IP头) | UDP校验和(2B)
DNS部分:ID号(2B很重要) | 标识(2B) | 问题数目(2B) | 回答数目(2B) | 权威回答数目(2B) | 附加数目(2B) | 问题字段(长度不定) | 回答字段(长度不定) | 权威字段(长度不定) | 附加字段(长度不定)
问题和回答,权威,附加都是RR记录格式,格式如下:
名字(2B) | 类型(2B) | 类(2B) | 存活时间(4B) | 数据长度(2B) | IP地址(4B)
我们本着越简单越好的做法,构造尽量短的回复,所以回答个数为1,权威和附加都为0。如果是请求包,到问题字段就完了,如果是回答,还有构造回答字段。
五、DNS应答包
下面开始构造伪造包:
以太网部分:交换源和目的的MAC地址。IP部分:计算修改包长度为你构造的假包IP部分长度,标识改为0x04(不分段),校验和改为你计算的IP首部校验和,交换源和目的IP。UDP部分:交换源和目的端口号,包长度改为你构造的假包UDP部分长度。校验和可以添0x0000或者自己算(是可选字段,首先计算费时间,影响发包速度,其次容易算错,我算了3天,老是错,原来要加一个UDP伪头,参考《TCP/IP祥解》)。DNS部分:问题数0x0001,回答数0x0001,权威0x0000,附加0x0000,问题字段直接拷贝,回答字段如下:名字0xc00c,类和类型都是0x0001,时间添长点,长0x0004,IP:你想转向的IP地址。
到这里假的应答就伪造好了。先简要说说代码,这里只有构造DNS回应部分的代码,我们还做了网址匹配,捕获到数据包以后首先判断是否欺骗此IP,如果欺骗再构造欺骗数据包并发送给改机器,否则不处理。同时对不同的域名返回不同的地址。只有别人输入相应的网址才给转向指定的IP地址。
参考文献:
[1]蒋东兴、林鄂华,Windows Sockets网络程序设计指南,北京:清华大学出版社,1995年,7-29.
[2]Mclean著,《Windows 2000 TCP/IP技术内幕》,北京机械工业出版社,2001.10.
[3]Thomposn著,《MFC开发人员参考手册》,北京:机械工业出版社,1998.8.