python - 需要深入了解 Python 的这段内容

标签 python sockets dns recv

我正在努力使这一小段 Python 代码适合我自己的使用(它来自 sendpkm DNS 欺骗工具,用于将原始 Pokémon DS 游戏的 DNS 请求重定向到自己的计算机。)

def dnsspoof():
  s=socket.socket(); s.connect(("bash.org",80));
  me="".join(chr(int(x)) for x in s.getsockname()[0].split("."))
  print "Please set your DS's DNS server to",s.getsockname()[0]
  dnsserv=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  dnsserv.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
  dnsserv.bind(("0.0.0.0",53))
  while True:
    r=dnsserv.recvfrom(512)
    s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(('4.2.2.2', 53))
s.send(r[0])
rr=s.recv(512)
if "gamestats2" in rr: rr=rr[:-4]+me
dnsserv.sendto(rr, r[1])

serv=None
log=None

是否有人能好心地引导我了解套接字并解释这是如何为 DNS 查询返回 IP 的?我刚刚学习 Python。

最佳答案

端口 53 是标准 DNS 端口。但此代码不了解该数字之外的任何有关 DNS 的信息。它所做的只是监听端口 53,将任何请求转发到 4.2.2.2 上的服务器,并返回该服务器返回的任何内容。

换句话说,它是端口 53 上的哑字节代理,它可以工作,因为远程服务器是 DNS 服务器。

如果您想知道它是如何工作的:

dnsserv=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dnsserv.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
dnsserv.bind(("0.0.0.0",53))

这是创建套接字以监听端口的标准代码。您正在监听 UDP,因为这就是 INET/DGRAM 的含义。 setsockopt 意味着如果您退出并重新启动服务器,它将能够再次获取相同的端口。绑定(bind)表示监听端口 53 上的所有 IPv4 地址。

循环读取最多 512 字节的数据包,连接到远程服务器并发送相同的数据包,读取服务器的响应,然后将其发送回客户端。因为recvfrom返回一个(数据,地址)元组,所以您将r[0]发送到服务器,并将响应发送到r[1]。 (通过元组解包,这部分将更具可读性:data, address = recvfrom(...)。然后您可以使用名称而不是 r[0]。)

关于python - 需要深入了解 Python 的这段内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19472241/

相关文章:

python - 从库 python-chess on line 命令可视化完整的棋盘

c++ - Boost asio - 同步写入/读取 - 怎么做?

python - 属性错误 : module 'socketserver' has no attribute 'ForkingMixIn'

javascript - 如何检查 DNSSEC 是否符合 nodejs?

cookies - 如何设置仅对 example.com 等特定域有效但对其子域无效的 cookie?

linux - 绑定(bind)ip到子域

python - 根据第二个数据帧设置数据帧的值

python - 比较命名元组列表中的多个(但不是全部)元素

python - Django 在 CreateView 中禁用/排除字段,但在 UpdateView 中启用/包含它

windows - 使用临时端口的 Boost::asio UDP 广播