本教程将演示一些功夫与Team Cymru的Python whois模块。在infosec中的攻击和防御角色中,你需要做很多whois查看,这个python模块可以节省你的时间。让我们跳进去开始玩这个模块的功能。
安装模块后,您可以导入模块并检查它提供的功能:
>>> 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']>>>
现在我们可以使用“查找”功能查找单个IP地址。在稍后的脚本中,我们将使用“lookupmany”,因为它允许我们传递一个IP数组:
>>> google = c.lookup('8.8.8.8')>>> 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'>>>
所以从这里我们可以将它包装在for循环中并反复进行,但Team Cymru已经提供了一个名为“lookupmany”的函数,它比循环查找函数要好得多。下面是一个评论很多的脚本,它显示了如何将所有这些结合在一起以从文件中读取IP列表以执行whois查找。
我通常做的是使用tcpdump,BPF过滤器和bash-fu提取感兴趣的IP。下面我们用“tcp”抓取SYNs
[13] = 2“然后将STDOUT传递给awk的STDIN并使用”awk'{print $ 6}'获取该行中的第6个元素,然后使用最后一个awk命令拉出IP,最后将STDOUT重定向到文件:
~$ tcpdump -ttttnnr t.cap tcp[13]=2 | awk '{print $6}' | awk -F "." '{print $1"."$2"."$3"."$4}' > ips.txtreading from file t.cap, link-type LINUX_SLL (Linux cooked)~$ python ip2net.py -r ips.txt[+] Querying from: ips.txt173.194.0.0/16 # - 173.194.8.102 (US) - GOOGLE - Google Inc.,US~$
现在让我们快速浏览一下大量评论的ip2net.py脚本,这样你就可以理解它是如何分解的:
#!/usr/bin/env pythonimport sys, os, optparsefrom cymruwhois import Client def look(iplist): c=Client() # creates an instance of the Client class try: if ips != None: r = c.lookupmany_dict(iplist) # leverages the lookupmany_dict() function to pass in a list of IPs for ip in iplist: # Iterates over the ips in the list to use a key value in the dictionary from lookupman_dict() net = r[ip].prefix; owner = r[ip].owner; cc = r[ip].cc # gets the networking information from the dictionary line = '%-20s # - %15s (%s) - %s' % (net,ip,cc,owner) # formats the line to print cleanly print line except:pass def checkFile(ips): # Checks to ensure the file can be read 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 # Assigns a -r <fileName> to variable 'ips' if (ips == None) and (ip == None): # If proper arguments aren't given print the script usage print parser.usage sys.exit(0) if ips != None: # Execute if ips has a value checkFile(ips) # Execute the function to check if the file can be read iplist = [] # create the ipslist list object for line in open(ips, 'r'): # Parse File to create a list iplist.append(line.strip('n')) # Appends that line in the file to list and removes the new line char look(iplist) # pass the iplist list object to the look() function else: # Executes lookup() function for a single IP stored in variable '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()