翻墙路由器的原理与实现(7)_掘图志

返回首页
当前位置: 主页 > 路由器设置 >

翻墙路由器的原理与实现(7)

时间:2016-02-01 13:38点击:

OpenWRT提供了NetfilterQueue的C的库。但是使用C来做实验太笨重了。所以我选择了Python。但是Python的NetfilterQueue的库没有在OpenWRT中。下载https://github.com/fqrouter/fqrouter解压后可以得到一个名字叫fqrouter的目录。然后给feeds.conf添加一行src-link fqrouter /opt/fqrouter/package。把/opt/fqrouter替换为你解压的目录。然后scripts/feeds update -a,再执行scripts/feeds install python-netfilterqueue就添加好了。然后在make menuconfig中选择Languages=>Python=>python-netfilterqueue。

有了这个库就赋予了我们使用Python任意抓包,修改包和发包的能力。在OpenWRT上,除了python没有第二种脚本语言可以如此简单地获得这些能力。

安装Python的dpkt

能够抓取和发送IP包之后,第二个头疼的问题是如何解析和构造任意的IP包。Python有一个库叫dpkt可以帮我们很好地完成这项任务。这是我们选择Python做实验的第二个重要理由。

在路由器上直接下载,然后解压缩,拷贝其中的dpkt目录到/usr/lib/python2.7/site-packages下。

DNS劫持观测

我们要做的第一个实验是用python代码观测到DNS劫持的全过程。

应用层观测

dig是DNS的客户端,可以很方便地构造出我们想要的DNS请求。dig @8.8.8.8 twitter.com。可以得到相应如下:

; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5494
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0   

;; QUESTION SECTION:
;twitter.com.                        IN        A   

;; ANSWER SECTION:
twitter.com.                4666        IN        A        59.24.3.173   

;; Query time: 110 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sun Jan 13 13:22:10 2013
;; MSG SIZE  rcvd: 45

可以很清楚地看到我们得到的错误答案59.24.3.173。

抓包观测

使用iptables我们可以让特定的IP包经过应用层的代码,从而使得我们用python观测DNS查询过程提供了可能。代码如下,保存文件名dns_hijacking_obversation.py(https://gist.github.com/4524294):

from netfilterqueue import NetfilterQueue
import subprocess
import signal   
 
def observe_dns_hijacking(nfqueue_element):
   print('packet past through me')
   nfqueue_element.accept()   
 
nfqueue = NetfilterQueue()
nfqueue.bind(0, observe_dns_hijacking)   
 
def clean_up(*args):
   subprocess.call('iptables -D OUTPUT -p udp --dst 8.8.8.8 -j QUEUE', shell=True)
   subprocess.call('iptables -D INPUT -p udp --src 8.8.8.8 -j QUEUE', shell=True)   
 
signal.signal(signal.SIGINT, clean_up)   
 
try:
   subprocess.call('iptables -I INPUT -p udp --src 8.8.8.8 -j QUEUE', shell=True)
   subprocess.call('iptables -I OUTPUT -p udp --dst 8.8.8.8 -j QUEUE', shell=True)
   print('running..')
   nfqueue.run()
except KeyboardInterrupt:
   print('bye')

执行python dns_hijacking_observation.py,再使用dig @8.8.8.8 twitter.com应该可以看到package past through me。这就说明DNS的请求和答案都经过了python代码了。

上一步主要是验证NetfilterQueue是不是工作正常。这一步则要靠dpkt的了。代码如下,文件名相同(https://gist.github.com/4524299):

from netfilterqueue import NetfilterQueue  

import subprocess  

import signal  

import dpkt  

import traceback  

import socket      

   

def observe_dns_hijacking(nfqueue_element):  

   try:  

       ip_packet = dpkt.ip.IP(nfqueue_element.get_payload())  

       dns_packet = dpkt.dns.DNS(ip_packet.udp.data)  

       print(repr(dns_packet))  

       for answer in dns_packet.an:  

           print(socket.inet_ntoa(answer['rdata']))  

       nfqueue_element.accept()  

   except:  

       traceback.print_exc()  

       nfqueue_element.accept()      

   

nfqueue = NetfilterQueue()  

nfqueue.bind(0, observe_dns_hijacking)      

   

def clean_up(*args):      

   

------分隔线----------------------------
推荐内容