发新话题
打印

通过nslookup的-vc参数用TCP协议解析域名

通过nslookup的-vc参数用TCP协议解析域名

DNS的问题,已经有很多讨论了
在网上有人介绍,通过tcp协议解析域名,可以获得正确的IP
但Windows默认是udp解析域名,而且无法设置成通过tcp协议解析域名。有人想办法通过修改dnsapi.dll实现tcp方式解析域名。
前些天看到网上有介绍使用nslookup -vc的参数,强制使用tcp解析域名。
网上已有用java、python等编写的dns工具用来解析dns污染的问题。今天我试用Perl写了一个程序,运行在Linux服务器上,效果还可以。
原理是,在53端口监听udp的查询请求,把请求信息中的域名信息分离出来,用nslookup -vc的方式和Google的DNS进行tcp通信,最后再把获取的正确IP用udp的方式发给客户端。

在互联网上也可以使用这个服务,可以做一个简单的测试,查询twitter.com的IP:
在命令行键入:nslookup twitter.com 8.8.8.8,返回的IP是:
Address: 37.61.54.158   (这个IP是错误的,说明DNS信息被污染了)
在命令行键入:nslookup -vc twitter.com 8.8.8.8,返回的IP是:
Address: 199.59.149.198  (这个IP是正确的,是通过tcp方式查询的)
在命令行键入:nslookup twitter.com 202.194.185.214,返回的IP是:
Address: 199.59.149.198  (这个IP是正确的) 
这说明,这个搭建的DNS,是可以解决DNS污染问题的

原文:http://blog.itpub.net/21129783/viewspace-710816

TOP

修改Windows下dnsapi.dll强制使用TCP进行DNS查询

首先我承认,我一时脑洞,好好的一个人,浪费几小时去折腾这破玩意。
先看看效果:



由于之前在路由上设置了内网的TCP转发,可惜DNS查询在Windows下默认使用的是UDP方式,而且居然没有修改的方式!
在网上搜索之后,发现可以通过修改 dnsapi.dll 的方式来实现强制使用TCP进行DNS查询,但是很可惜的是作者没说具体的方法。妈蛋我一下子就兴奋了,这是赤裸裸地挑衅啊!

知道该怎么做之后就是开工了,先去MSDN上看看关于 dnsapi.dll 的手册,找到下面2条:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682016(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/cc982162(v=vs.85).aspx
DnsQuery是系统查询DNS时调用的函数,DNS Constants是一些常量,对我们接下来修改dll会很有帮助。

由于是Windows 8.1系统,有32位和64位的dll,我们要分析修改2次。
首先是32位的dll,这个在 C:\Windows\SysWOW64\dnsapi.dll 。
Windows下自然是用Visual Studio调试,随便写个程序来调用dnsapi:

1


2


3


4


5


6


7


8


9


10


#include <Windows.h>
#include <WinDNS.h>

#pragma comment(lib, "Dnsapi.lib")

int main()
{
  DnsQuery(L"www.google.com", DNS_TYPE_A, DNS_QUERY_USE_TCP_ONLY | DNS_QUERY_BYPASS_CACHE, NULL, NULL, NULL);
  return 0;
}



然后就是调试,跟踪,可惜我没有去下载Windows的调试符号文件(pdb),不然可能会更轻松点。
跟到这个:

很好,在前几行断点处可以看出 [ebx] 是我们传入的Options,这里我们可以看出他在和一些常量做比较,这个 4000000h 由于在常量表(DNS Query Options)找不到值为 0x04000000 的定义,我觉得可能这个值就是保留定义的,也不大可能用上,于是决定放弃这个数值,来加上 DNS_QUERY_USE_TCP_ONLY 标志。(主要是没有调试文件搞得调了半天,也没找到其他更好的修改方式了,如果有人知道,请务必告知!)
于是,就在图中 71B34795 改成:

1


2


3


4


5


6


7


8


__asm {
  or ecx, 2
  mov [ebx], ecx
  xor eax, eax
  nop
  nop
  nop
}



这样,对于Windows 8.1的32位的 dnsapi.dll (6.3.9600.17039) 做出的修改就是:

1


2


3


4


5


6


7


8


9


10


00003B95: 8B -> 83
00003B96: C1 -> C9
00003B97: 8B -> 02
00003B98: 53 -> 89
00003B99: 04 -> 0B
00003B9A: 25 -> 33
00003B9B: 00 -> C0
00003B9C: 00 -> 90
00003B9D: 00 -> 90
00003B9E: 04 -> 90



下面就是64位的dll,这个在 C:\Windows\System32\dnsapi.dll 。
调试的方法和32位的相同,记得要更换编译方式,然后开始调试反汇编代码。

这里找到的代码和32位的大致相同。接下来打开IDA找到这个代码的位置。

将其改成这个样子:

这样,对于Windows 8.1的64位的 dnsapi.dll (6.3.9600.17039) 做出的修改就是:

1


2


3


4


5


6


7


8


9


10


00002C07: 0F -> 83
00002C08: BA -> C8
00002C09: E0 -> 02
00002C0A: 1A -> 90
00002C0B: 0F -> 49
00002C0C: 82 -> 89
00002C0D: 3E -> 45
00002C0E: 78 -> 00
00002C0F: 04 -> 90
00002C10: 00 -> 90



这样就算搞定了,强制设置上 DNS_QUERY_USE_TCP_ONLY 这个标志,也就是强制走TCP。
然后我们需要把文件拷回去,记得先要修改对应目录下的文件的安全性,然后改名成 dnsapi.dll.bak 做个备份,最后把我们的修改后的文件拷贝进去就好了。

最好重启一下,然后就可以在Wireshark中看到效果啦~

最后附上我修改好32位和64位的 dnsapi.dll (6.3.9600.17039) 文件:
https://bless.moe/io/win/mod/dnsapi/

另外,我们需要注意一点,像在 chrome://flags/ 开启了实验性异步 DNS 客户端的 Chrome 等软件会使用自带的DNS客户端,不走系统的DNS解析,所以可能还是UDP方式查询DNS。

原文:https://bless.moe/blog/po/1067

TOP

发新话题