#!/opt/local/bin/python # (c) Adam Pridgen adam.pridgen@thecoverofnight.com # GPL v3 i # # # This is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation version 2 of the License. # # This is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # details. # # You should have received a copy of the GNU General Public License along # with this; if not, write to the Free Software Foundation, Inc., 51 # Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or jfgi from perform_dig_whois import * from threading import * import threading import random import time import dns.resolver from socket import * MAX_POOL = 512 COUNT = 10 pool_sema = BoundedSemaphore(value=512) # let the first 256 threads start out and kick into gear thread_pool_limit = 256 write_lock = Lock() def open_socks5_connection(host, port): s = None try: s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP ) except: sleep(4) s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP ) s.connect((host,port)) # send socks5 auth negotiation s.send("\x05\x01\x00") r = s.recv(3) if r[0] != "\x05": print "Fail" raise exceptions.Exception("Bad Socks Proxy Value: %02x"%ord(r)) if r[1] != "\x00": print "Fail" raise exceptions.Exception("Bad Socks Proxy Auth Value: %02x"%ord(r)) return s def build_socks5_resolution_req(ipaddr): req = "\x05\xF1\x00\x01" #[SOCKS5 | PTR_RESOLVE | RESERVED | REVERSE_LOOKUP] ip = inet_aton(ipaddr) req += (ip + "\x00\x00" ) return req REASONS = {0: 'succeeded', 1: 'general SOCKS server failure', 2: 'connection not allowed by ruleset', 3: 'Network unreachable', 4: 'Host unreachable', 5: 'Connection refused', 6: 'TTL expired', 7: 'Command not supported', 8: 'Address type not supported'} def socks5_resolve_ip(ipaddr, host="127.0.0.1", port=9050, timeout=3): sock = open_socks5_connection(host, port) req = build_socks5_resolution_req(ipaddr) sock.send(req) resp = sock.recv(1024) if resp[1] == "\x00": nlen = ord(resp[4]) name = resp[5:5+nlen] return 0,name else: return ord(resp[1]), None def readfile_progress(file): try: l = open(file).readlines() return [i.strip().split()[0] for i in l if i != "\n" and i != ""] except: print "No progress so far." return [] def prune_list(iplist,flist): compare_set = None iter_list = None if len(iplist) > len(flist): compare_set = set(iplist) iter_list = flist else: compare_set = set(flist) iter_list = iplist for i in iter_list: if i in compare_set: iplist.remove(i) continue return iplist def compare_time(orig): t = time.mktime(list(orig)) n = time.mktime(list(time.localtime())) return time.gmtime(n - t) def perform_socks5_resolve(ip, host="127.0.0.1", port=9050): res = socks5_resolve_ip(ip,host,port) if res[0] != 0: print "Failed to resolve %s: %s"%(ip, REASONS.get(res[0], "Unknown Failure")) return None if res[1].strip() == "": return None return res[1].strip() def tr_host_rlookup(ip, results): global pool_sema, thread_pool_limit pool_sema.acquire() r = perform_socks5_resolve(ip, host="127.0.0.1",port=9050) if not r is None: write_lock.acquire() print "\tFound: %s %s"%(ip, r.decode("utf-8")) out.write("%s %s\n"%(ip,r.decode("utf-8"))) results.append((ip, r)) write_lock.release() else: write_lock.acquire() out.write("%s %s\n"%(ip,"FAIL")) #results.append((ip, r)) write_lock.release() # need a thread safe list here #results.append((ip, r)) thread_pool_limit += 1 pool_sema.release() def host_rlookup(ip, results): global pool_sema, thread_pool_limit pool_sema.acquire() r = perform_host(ip, hargs="-t ptr") if not r is None: write_lock.acquire() print "\tFound: %s %s"%(ip, r.decode("utf-8")) out.write("%s %s\n"%(ip,r.decode("utf-8"))) results.append((ip, r)) write_lock.release() else: write_lock.acquire() out.write("%s %s\n"%(ip,"FAIL")) #results.append((ip, r)) write_lock.release() # need a thread safe list here #results.append((ip, r)) thread_pool_limit += 1 pool_sema.release() out = None # if __name__ == "__main__": if len(sys.argv) < 3: print '''usage: %s [-t] -t: use tor-resolve (not as accurate ip_list: iplisting like so: 192.168-169.1-255'''%sys.argv[0] i =0 use_tr = False print sys.argv if sys.argv[1] == "-t": use_tr = True i=1 ip_list = get_ips(sys.argv[i+1]) # arg 1 or 0 #plist = readfile_progress(sys.argv[i+2]) #ip_list = prune_list(ip_list, plist) out = open(sys.argv[i+2], "a+") # arg 1 or 2 thread_list = [] results = [] original_ip_list_len = len(ip_list) start_time = time.localtime() while len(ip_list) > 0: idx = random.randint(0, len(ip_list)) ip = ip_list.pop(idx) pruned_thread_list = False while thread_pool_limit <= 0: print "Uh-oh, must have started too many threads!" print "Time for an update:\n" print "*** Orginal List Length: %7d"%original_ip_list_len print "****Current List Length: %7d"%len(ip_list) print "****Resolution Completed: %7d"%(original_ip_list_len - len(ip_list)) print "****Resolved Nost Names: %7d"%(len(results)) r = compare_time(start_time) print "*****Elapsed Time: %s"%time.strftime("%H:%M:%S",r) print "****Number of Threads: %d"%len(thread_list) print "***Unused Thread Pool Count: %d"%thread_pool_limit def prune_thread_list(): t_idx = 0 print "Pruning the thread list down to a reasonable size" while t_idx < len(thread_list): if not thread_list[t_idx].isAlive(): thread_list.pop(t_idx) continue t_idx += 1 if not pruned_thread_list: prune_thread_list() if thread_pool_limit < 0: thread_pool_limit += 1 sleep(1) if thread_pool_limit + len(thread_list) != MAX_POOL: print "Thread Accounting is FAIL! Adding more threads to the pool: %d"%(MAX_POOL - (thread_pool_limit + len(thread_list))) thread_pool_limit += MAX_POOL - (thread_pool_limit + len(thread_list)) thread_pool_limit -= 1 t = None try: if use_tr: t = Thread(target=tr_host_rlookup, args=(ip,results)) else: t = Thread(target=host_rlookup, args=(ip,results)) t.start() thread_list.append(t) except KeyboardInterrupt: print "Quiting, but first all threads need to run their course." break except: print "Experienced an exception somewhere:\n%s"%(str(sys.exc_info()[0])) ip_list.append(ip) #ip,r = host_rlookup(ip) #results.append((ip,r)) print "************************\n\n\n\n" print "Quiting cleaning" print len(thread_list) for i in thread_list: while i.isAlive(): sleep(1) print results for ip,r in results: if not r is None: out.write("%s %s\n"%(ip,r)) out.close()