##Whois自動查詢
這一章將教大家一些技巧性的東西,教大家使用Cymru's團隊提供的[whois模塊](https://pypi.python.org/pypi/cymruwhois/1.0)來做一個whois信息查詢工具,使用這個模塊可以幫你節省大量的的時間,廢話少說,現在就讓我們開始吧!
首先你需要安裝這個模塊并且可以使用之前我們講過的dir函數去看看這個模塊提供了那些功能:
```
>>> from cymruwhois import Client
>>> c = Client()
>>> dir(c)
['KEY_FMT', '__doc__', '__init__', '__module__', '_begin', '_connect', '_connected', '_disconnect', '_lookupmany_raw', '_readline', '_sendline', 'c', 'cache', 'disconnect', 'get_cached', 'host', 'lookup', 'lookupmany', 'lookupmany_dict', 'port', 'read_and_discard']
>>>
```
現在我們使用lookup函數來查詢一個單獨的IP地址,在后面我們會使用"lookupmany"來查詢一個IP數組列表:
```
>>> google = c.lookup('8.8.8.8') #譯者注:國內會被GFW
>>> google
<cymruwhois.record instance: 15169|8.8.8.8|8.8.8.0/24|US|GOOGLE - Google Inc.,US>
>>> type(google)
<type 'instance'>
>>>
```
現在我們有一個cymruwhois.record的實例,可以從中提取出下面這些信息:
```
>>>
>>> dir(google)
['__doc__', '__init__', '__module__', '__repr__', '__str__', 'asn', 'cc', 'ip', 'owner', 'prefix']
>>> google.ip
'8.8.8.8'
>>> google.owner
'GOOGLE - Google Inc.,US'
>>> google.cc
'US'
>>> google.asn
'15169'
>>> google.prefix
'8.8.8.0/24'
>>>
```
我們以前思考處理多個ip列表的時候是使用for循環來處理的,但在這里我們并不需要使用for循環去遍歷整個數組列表,我們可以使用Cymru團隊提供的"lookupmany"函數去代替自己寫的循環代碼,下面將演示了一個比較復雜的腳本:從一個文件里面讀取到IP列表,然后執行whois信息查詢:
我們通常使用tcpdump,BPF還有bash-fu來處理IP列表,下面我們抓取了SYN包里面"tcp[13]=2"的ip并且通過awk的通道stdout與stdin把第六個元素使用" awk ‘{print $6}’"抓取出來,然后把使用awk抓取出來的ip寫入到一個文件里面:
```
~$ tcpdump -ttttnnr t.cap tcp[13]=2 | awk '{print $6}' | awk -F "." '{print $1"."$2"."$3"."$4}' > ips.txt
reading from file t.cap, link-type LINUX_SLL (Linux cooked)
~$ python ip2net.py -r ips.txt
[+] Querying from: ips.txt
173.194.0.0/16 # - 173.194.8.102 (US) - GOOGLE - Google Inc.,US
~$
```
現在讓我看看ip2net.py這個腳本,里面有注釋可以幫助你快速的理解這個腳本究竟是干些什么:
**ip2net.py**
```
#!/usr/bin/env python
import sys, os, optparse
from cymruwhois import Client
def look(iplist):
c=Client() # 創建一個Client的實例類
try:
if ips != None:
r = c.lookupmany_dict(iplist) # 利用lookupmany_dict()函數傳遞IP列表
for ip in iplist: #遍歷lookupman_dict()傳入的值
net = r[ip].prefix; owner = r[ip].owner; cc = r[ip].cc #從字典里面獲取連接后的信息
line = '%-20s # - %15s (%s) - %s' % (net,ip,cc,owner) #格式化輸出
print line
except:pass
def checkFile(ips): # 檢查文件是否能夠讀取
if not os.path.isfile(ips):
print '[-] ' + ips + ' does not exist.'
sys.exit(0)
if not os.access(ips, os.R_OK):
print '[-] ' + ips + ' access denied.'
sys.exit(0)
print '[+] Querying from: ' +ips
def main():
parser = optparse.OptionParser('%prog '+ \
'-r <file_with IPs> || -i <IP>')
parser.add_option('-r', dest='ips', type='string', \
help='specify target file with IPs')
parser.add_option('-i', dest='ip', type='string', \
help='specify a target IP address')
(options, args) = parser.parse_args()
ip = options.ip # Assigns a -i <IP> to variable 'ip'
global ips; ips = options.ips # 賦值-r <fileName> 給變量 'ips'
if (ips == None) and (ip == None): # 如果缺少參數就輸出使用手冊
print parser.usage
sys.exit(0)
if ips != None: #檢查ips
checkFile(ips) #檢查文件是否能夠讀取
iplist = [] # 創建ipslist列表對象
for line in open(ips, 'r'): # 解析文件內容
iplist.append(line.strip('\n')) # 添加一行新內容并且刪除換行字符
look(iplist) # 調用look()函數
else: # 執行lookup()函數并且把內容存儲到變量 'ip'
try:
c=Client()
r = c.lookup(ip)
net = r.prefix; owner = r.owner; cc = r.cc
line = '%-20s # - %15s (%s) - %s' % (net,ip,cc,owner)
print line
except:pass
if __name__ == "__main__":
main()
```