如何搭建TCP代理(三)

来源:岁月联盟 编辑:猪蛋儿 时间:2020-03-24

使用Netcat探测DNS请求
当数据包通过你的便携式计算机时,我们已使用Wireshark对其进行被动检查。现在,我们将使用另一种称为netcat的工具来主动监听传入的DNS请求,甚至发送回基本的DNS响应,这将允许你的手机再次开始与部分互联网进行连接。
Netcat是一个读写TCP和UDP网络连接数据的工具,如上所述,你的智能手机通过UDP端口53发送DNS请求,要使用netcat监听这些请求,请运行以下命令:
sudo ncat -nluvvv 53
在一个终端,该命令需要以sudo身份运行,因为它监听的是一个编号较低的敏感端口。
现在,当你试图用智能手机访问一个网站时,你应该会看到一个DNS请求打印在你的笔记本电脑的终端上。由于该请求并不是为方便人类阅读而设计的,因此它在大多数情况下看起来都像是乱码。然而,你应该仍然能够在其中找出你试图访问的网站的主机名。

你可能需要停止并启动ncat监听器几次才能使其正常工作,如果你仍然无法使其正常运行,那么只要你的智能手机发送的数据包出现在Wireshark中,你就不必担心。
现在,我们已经使用Wireshark和Netcat检查了你的智能手机的DNS请求。但是,你的笔记本电脑仍然不知道如何响应。它不会将DNS响应发送回你的智能手机,因此你的智能手机仍然无法实际加载你要访问的页面。不过,你可以使用netcat的一个更高级的选项发送回DNS响应。
使用Netcat发送回DNS响应
ncat UDP监听器具有--exec选项,你可以使用--exec指定当UDP监听器接收到数据包时netcat应该运行的命令。 Netcat将数据包的内容输入到stdin上--exec指定的命令中,并将命令写入标准输出的任何输出发送回数据包的原始发送者。例如,为了在监听器收到UDP数据包时运行Python脚本,可以运行:
sudo ncat -nluvvv --keep-open --exec "/usr/bin/python /PATH/TO/THE/SCRIPT.py" 53
让我们使用--exec响应智能手机的DNS请求,将以下Python脚本保存到笔记本电脑上。
import sys
 
# Read the first 2 bytes from the DNS request that netcat
# is piping in on stdin. These byte are the request ID and
# must be included at the start of the response so that the
# requester can match the response up with its original request
req_id = sys.stdin.read(2)
# Convert the bytes to hex
req_id_hex_str = ''.join(["%02X" % ord(c) for c in str(req_id)])
# This is hex for the DNS response body "robertheaton.com
# is at IP address 104.18.32.191". To give yourself some
# confidence that I'm telling the truth, run:
#
# python -c "print bytearray.fromhex('$COPY_THE_HEX_STRING_HERE')"
#
# in a terminal.
resp_body_str = "818000010002000000000c726f62657274686561746f6e03636f6d0000010001c00c000100010000012b0004681220bfc00c000100010000012b0004681221bf"
该脚本将我从Wireshark复制并粘贴的标准硬编码的,预先生成的DNS响应输出到stdout。此硬编码的响应告诉请求者(你的智能手机)robertheaton.com解析为IP地址104.18.32.191。为了确保请求者可以将我们的响应与原始请求匹配,脚本将读取请求的前2个字节(表示DNS请求ID),并将其添加到主响应正文中。之所以必须这样做,是因为UDP是无连接协议,并且不会为你的智能手机提供任何内置方式来将DNS响应与请求进行匹配。
你应该验证DNS响应十六进制字符串确实是我所声称的,你可以通过在终端中运行以下命令来确认响应是无害的:
python -c "print bytearray.fromhex('$COPY_THE_HEX_STRING_HERE')"
更好的方法是从Wireshark中复制你自己的DNS请求的十六进制代码,并在脚本中使用它。
你还应该检查自己是否信任脚本的其余部分,如果你使用sudo以root身份运行ncat,则该Python脚本也将以具有所有相关特权的root用户身份运行。不过请不要过分担心,我保证这一切都是完全良性和合法的。
要使用脚本将DNS响应发送回你的手机,请确保你的智能手机的DNS服务器仍然设置为你的笔记本电脑并运行:
sudo ncat -nluvvv --keep-open --exec "/usr/bin/python /PATH/TO/THE/SCRIPT.py" 53
现在,在智能手机上访问robertheaton.com以外的网站,或从Wireshark复制的响应中的主机名,你应该发现它仍然无法正常工作。这是因为你的智能手机笔记本电脑询问了诸如“facebook.com的IP地址是什么?”之类的问题,并且你的笔记本电脑发回了一个不合逻辑的“robertheaton.com的IP地址为104.18.32.191”。由于请求和响应的主机名不匹配,因此你的智能手机将完全忽略响应。
我们的原始DNS服务器可以使用的唯一主机名就是互联网上最重要的网站robertheaton.com。在你的智能手机上访问robertheaton.com,你应该会看到它正常加载。这是因为“robertheaton.com的IP地址是104.18.32.191”才是问题 “robertheaton.com的IP地址是什么?”的正确回复。
如何伪造DNS服务器?
随着DNS欺骗概念的验证,我们现在准备构建和运行我们的完整的、虚假的DNS服务器。我用一个简短的Python脚本和强大的网络库scapy为我们编写了这样一个服务器。同样,这个脚本需要使用sudo来运行,以便允许它在端口53上监听。将该脚本复制到笔记本电脑上,并使用以下命令运行:
sudo python /PATH/TO/SCRIPT.py
此代码也在GitHub上:
import dns.resolver
import scapy.all as scapy
import netifaces as ni
 
def handle_packet_fn(iface, spoof_ip, spoof_domains):
    def handle_packet(packet):
        ip = packet.getlayer(scapy.IP)
        udp = packet.getlayer(scapy.UDP)

[1] [2] [3] [4]  下一页