| 
					
				 | 
			
			
				@@ -6,7 +6,6 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ##              good candidates for phishing and C2 domain names 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # To-do: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# Python 3 support  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # Add reputation categorizations to identify desireable vs undesireable domains 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # Code cleanup/optimization 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # Add Authenticated "Members-Only" option to download CSV/txt (https://member.expireddomains.net/domains/expiredcom/) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -92,9 +91,9 @@ if __name__ == "__main__": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         from texttable import Texttable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     except Exception as e: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print "Expired Domains Reputation Check" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print "[-] Missing dependencies: {}".format(str(e)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print "[*] Install required dependencies by running `pip install -r requirements.txt`" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print("Expired Domains Reputation Check") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print("[-] Missing dependencies: {}".format(str(e))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print("[*] Install required dependencies by running `pip install -r requirements.txt`") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         quit(0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     parser = argparse.ArgumentParser(description='Checks expired domains, bluecoat categorization, and Archive.org history to determine good candidates for C2 and phishing domains') 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -102,7 +101,7 @@ if __name__ == "__main__": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     parser.add_argument('-c','--check', help='Perform slow reputation checks', required=False, default=False, action='store_true') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     parser.add_argument('-r','--maxresults', help='Number of results to return when querying latest expired/deleted domains (min. 100)', required=False, type=int, default=100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     parser.add_argument('-w','--maxwidth', help='Width of text table', required=False, type=int, default=400) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    parser.add_argument('-f','--file', help='Input file containing potential domain names to check (1 per line)', required=False, type=str) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #parser.add_argument('-f','--file', help='Input file containing potential domain names to check (1 per line)', required=False, type=str) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     args = parser.parse_args() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ## Variables 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -118,9 +117,10 @@ if __name__ == "__main__": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     maxwidth=args.maxwidth 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    inputfile = False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if args.file: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        inputfile = args.file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # TODO: Add Input file support 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #inputfile = False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #if args.file: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #    inputfile = args.file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     t = Texttable(max_width=maxwidth) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     malwaredomains = 'http://mirror1.malwaredomains.com/files/justdomains' 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -157,10 +157,10 @@ If you plan to use this content for illegal purpose, don't.  Have a nice day :)' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print(disclaimer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print("") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print("********************************************") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    print("Start Time:             {}").format(timestamp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    print("TextTable Column Width: {}").format(str(maxwidth)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    print("Checking Reputation:    {}").format(str(check)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    print("Number Domains Checked: {}").format(maxresults) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    print("Start Time:             {}".format(timestamp)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    print("TextTable Column Width: {}".format(str(maxwidth))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    print("Checking Reputation:    {}".format(str(check))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    print("Number Domains Checked: {}".format(maxresults)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print("********************************************") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     runtime = 0 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -170,64 +170,80 @@ If you plan to use this content for illegal purpose, don't.  Have a nice day :)' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         runtime = maxresults * .15 / 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    print("Estimated Max Run Time: {} minutes").format(int(runtime)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    print("Estimated Max Run Time: {} minutes".format(int(runtime))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print("") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print('[*] Downloading malware domain list from {}'.format(malwaredomains)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     maldomains = downloadMalwareDomains() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     maldomains_list = maldomains.split("\n") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # Create an initial session 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     domainrequest = s.get("https://www.expireddomains.net",headers=headers,verify=False) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # Generate list of URLs to query for expired/deleted domains, queries return 25 results per page 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    urls = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # Use the keyword string to narrow domain search if provided 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # Need to modify this to pull more than the first 25 results 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if query: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print('[*] Fetching expired or deleted domains containing "{}"...').format(query) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print('[*] Fetching expired or deleted domains containing "{}"'.format(query)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         for i in range (0,maxresults,25): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if i == 0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                url = "{}/?q={}".format(expireddomainsqueryurl,query) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                urls.append("{}/?q={}".format(expireddomainsqueryurl,query)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 headers['Referer'] ='https://www.expireddomains.net/domain-name-search/?q={}&start=1'.format(query) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                url = "{}/?start={}&q={}".format(expireddomainsqueryurl,i,query) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                urls.append("{}/?start={}&q={}".format(expireddomainsqueryurl,i,query)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 headers['Referer'] ='https://www.expireddomains.net/domain-name-search/?start={}&q={}'.format((i-25),query) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            print("[*]  {}".format(url)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # Annoyingly when querying specific keywords the expireddomains.net site requires additional cookies which  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            #  are set in JavaScript and not recognized by Requests so we add them here manually. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # May not be needed, but the _pk_id.10.dd0a cookie only requires a single . to be successful 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # In order to somewhat match a real cookie, but still be different, random integers are introduced 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r1 = random.randint(100000,999999) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r2 = random.randint(100000,999999) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r3 = random.randint(100000,999999) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print('[*] Fetching expired or deleted domains...') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for i in range (0,(maxresults),25): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            urls.append('https://www.expireddomains.net/backorder-expired-domains?start={}&o=changed&r=a'.format(i)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            urls.append('https://www.expireddomains.net/deleted-com-domains/?start={}&o=changed&r=a'.format(i)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            urls.append('https://www.expireddomains.net/deleted-net-domains/?start={}&o=changed&r=a'.format(i)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            urls.append('https://www.expireddomains.net/deleted-org-domains/?start={}&o=changed&r=a'.format(i)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            pk_str = '843f8d071e27aa52' + '.1496' + str(r1) + '.2.1496' + str(r2) + '.1496' + str(r3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            jar = requests.cookies.RequestsCookieJar() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            jar.set('_pk_id.10.dd0a', '843f8d071e27aa52.1496597944.2.1496602069.1496601572.', domain='expireddomains.net', path='/') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            jar.set('_pk_ses.10.dd0a', '*', domain='expireddomains.net', path='/') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            domainrequest = s.get(url,headers=headers,verify=False,cookies=jar) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for url in urls: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            domains = domainrequest.text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print("[*]  {}".format(url)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # Turn the HTML into a Beautiful Soup object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            soup = BeautifulSoup(domains, 'lxml') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            table = soup.find("table") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # Annoyingly when querying specific keywords the expireddomains.net site requires additional cookies which  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        #  are set in JavaScript and not recognized by Requests so we add them here manually. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # May not be needed, but the _pk_id.10.dd0a cookie only requires a single . to be successful 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # In order to somewhat match a real cookie, but still be different, random integers are introduced 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                for row in table.findAll('tr')[1:]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        r1 = random.randint(100000,999999) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        r2 = random.randint(100000,999999) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        r3 = random.randint(100000,999999) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    # Alternative way to extract domain name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    # domain = row.find('td').find('a').text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        pk_str = '843f8d071e27aa52' + '.1496' + str(r1) + '.2.1496' + str(r2) + '.1496' + str(r3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    cells = row.findAll("td") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        jar = requests.cookies.RequestsCookieJar() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        jar.set('_pk_id.10.dd0a', '843f8d071e27aa52.1496597944.2.1496602069.1496601572.', domain='expireddomains.net', path='/') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        jar.set('_pk_ses.10.dd0a', '*', domain='expireddomains.net', path='/') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        domainrequest = s.get(url,headers=headers,verify=False,cookies=jar) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        domains = domainrequest.text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # Turn the HTML into a Beautiful Soup object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        soup = BeautifulSoup(domains, 'lxml') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        table = soup.find("table") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for row in table.findAll('tr')[1:]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # Alternative way to extract domain name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # domain = row.find('td').find('a').text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                cells = row.findAll("td") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if len(cells) >= 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    output = "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if query: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if len(cells) >= 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        output = "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c0 = row.find('td').find('a').text   # domain 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c1 = cells[1].find(text=True)   # bl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c2 = cells[2].find(text=True)   # domainpop 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -246,99 +262,8 @@ If you plan to use this content for illegal purpose, don't.  Have a nice day :)' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c15 = cells[15].find(text=True) # list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c16 = cells[16].find(text=True) # status 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c17 = cells[17].find(text=True) # related links 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        available = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if c8 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            available += ".com " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if c9 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            available += ".net " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if c10 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            available += ".org " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if c11 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            available += ".de " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        # Skip additional reputation checks if this domain is already categorized as malicious  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if c0 in maldomains_list: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            print("[-] Skipping {} - Identified as known malware domain").format(c0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            bluecoat = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            ibmxforce = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            if c3 == '-': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                bluecoat = 'ignored' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                ibmxforce = 'ignored' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            elif check == True: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                bluecoat = checkBluecoat(c0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                print "[+] {} is categorized as: {}".format(c0, bluecoat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                ibmxforce = checkIBMxForce(c0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                print "[+] {} is categorized as: {}".format(c0, ibmxforce) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                # Sleep to avoid captchas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                time.sleep(random.randrange(10,20)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                bluecoat = "skipped" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                ibmxforce = "skipped" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            # Append parsed domain data to list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            data.append([c0,c3,c4,available,bluecoat,ibmxforce]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            except:  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print "[-] Error: No results found on this page!" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # Retrieve the most recent expired/deleted domain results 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    elif inputfile: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print('[*] Fetching domain reputation from file: {}').format(inputfile) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        # read in file contents to list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            domains = [line.rstrip('\r\n') for line in open(inputfile, "r")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        except IOError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            print '[-] Error: "{}" does not appear to exist.'.format(inputfile) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            exit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print('[*] Domains loaded: {}').format(len(domains)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for domain in domains: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if domain in maldomains_list: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print("[-] Skipping {} - Identified as known malware domain").format(domain) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                bluecoat = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ibmxforce = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                bluecoat = checkBluecoat(domain) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print "[+] {} is categorized as: {}".format(domain, bluecoat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ibmxforce = checkIBMxForce(domain) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print "[+] {} is categorized as: {}".format(domain, ibmxforce) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                # Sleep to avoid captchas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                time.sleep(random.randrange(10,20)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                data.append([domain,'-','-','-',bluecoat,ibmxforce]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print('[*] Fetching {} expired or deleted domains...').format(query) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        # Generate list of URLs to query for expired/deleted domains, queries return 25 results per page 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        urls = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for i in range (0,(maxresults/4),25): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            urls.append('https://www.expireddomains.net/backorder-expired-domains?start={}&o=changed&r=a'.format(i)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            urls.append('https://www.expireddomains.net/deleted-com-domains/?start={}&o=changed&r=a'.format(i)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            urls.append('https://www.expireddomains.net/deleted-net-domains/?start={}&o=changed&r=a'.format(i)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            urls.append('https://www.expireddomains.net/deleted-org-domains/?start={}&o=changed&r=a'.format(i)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for url in urls: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            print("[*]  {}".format(url)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            expireddomains = s.get(url,headers=headers,verify=False).text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # Turn the HTML into a Beautiful Soup object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            soup = BeautifulSoup(expireddomains, 'lxml') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            table = soup.find("table") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                for row in table.findAll('tr')[1:]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    cells = row.findAll("td") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if len(cells) >= 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        output = "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c0 = cells[0].find(text=True)   # domain 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c1 = cells[1].find(text=True)   # bl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c2 = cells[2].find(text=True)   # domainpop 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -354,51 +279,87 @@ If you plan to use this content for illegal purpose, don't.  Have a nice day :)' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c12 = cells[12].find(text=True) # tld registered 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c13 = cells[13].find(text=True) # changes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         c14 = cells[14].find(text=True) # whois 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        c15 = ""                        # not used 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        c16 = ""                        # not used 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        c17 = ""                        # not used 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         # Expired Domains results have an additional 'Availability' column that breaks parsing "deleted" domains 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         #c15 = cells[15].find(text=True) # related links 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        available = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if c8 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            available += ".com " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if c9 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            available += ".net " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if c10 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            available += ".org " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if c11 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            available += ".de " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        # Skip additional reputation checks if this domain is already categorized as malicious  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if c0 in maldomains_list: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            print("[-] Skipping {} - Identified as known malware domain").format(c0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    available = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if c8 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        available += ".com " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if c9 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        available += ".net " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if c10 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        available += ".org " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if c11 == "available": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        available += ".de " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    status = "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if c16: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        status = c16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    # Skip additional reputation checks if this domain is already categorized as malicious  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if c0 in maldomains_list: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        print("[-] Skipping {} - Identified as known malware domain").format(c0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        bluecoat = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ibmxforce = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if c3 == '-': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            bluecoat = 'ignored' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            ibmxforce = 'ignored' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        elif check == True: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            bluecoat = checkBluecoat(c0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            print("[+] {} is categorized as: {}".format(c0, bluecoat)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            ibmxforce = checkIBMxForce(c0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            print("[+] {} is categorized as: {}".format(c0, ibmxforce)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            # Sleep to avoid captchas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            time.sleep(random.randrange(10,20)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            bluecoat = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            ibmxforce = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            if c3 == '-': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                bluecoat = 'ignored' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                ibmxforce = 'ignored' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            elif check == True: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                bluecoat = checkBluecoat(c0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                print "[+] {} is categorized as: {}".format(c0, bluecoat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                ibmxforce = checkIBMxForce(c0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                print "[+] {} is categorized as: {}".format(c0, ibmxforce) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                # Sleep to avoid captchas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                time.sleep(random.randrange(10,20)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                bluecoat = "skipped" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                ibmxforce = "skipped" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            # Append parsed domain data to list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            data.append([c0,c3,c4,available,bluecoat,ibmxforce]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            except:  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print "[-] Error: No results found on this page!" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            bluecoat = "skipped" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            ibmxforce = "skipped" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        # Append parsed domain data to list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        data.append([c0,c3,c4,available,status,bluecoat,ibmxforce]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        except:  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            print("[-] Error: No results found on this page!") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # TODO: Add support of input file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # Retrieve the most recent expired/deleted domain results 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # elif inputfile: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #     print('[*] Fetching domain reputation from file: {}').format(inputfile) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #     # read in file contents to list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #     try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #         domains = [line.rstrip('\r\n') for line in open(inputfile, "r")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #     except IOError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #         print '[-] Error: "{}" does not appear to exist.'.format(inputfile) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #         exit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #     print('[*] Domains loaded: {}').format(len(domains)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #     for domain in domains: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #         if domain in maldomains_list: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #             print("[-] Skipping {} - Identified as known malware domain").format(domain) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #         else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #             bluecoat = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #             ibmxforce = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #             bluecoat = checkBluecoat(domain) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #             print "[+] {} is categorized as: {}".format(domain, bluecoat) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #             ibmxforce = checkIBMxForce(domain) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #             print "[+] {} is categorized as: {}".format(domain, ibmxforce) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #             # Sleep to avoid captchas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #             time.sleep(random.randrange(10,20)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #             data.append([domain,'-','-','-',bluecoat,ibmxforce]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # Sort domain list by column 2 (Birth Year) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sortedData = sorted(data, key=lambda x: x[1], reverse=True)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     t.add_rows(sortedData) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    header = ['Domain', 'Birth', '#', 'TLDs', 'BC', 'IBM'] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    header = ['Domain', 'Birth', '#', 'TLDs', 'Status', 'BC', 'IBM'] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     t.header(header) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # Build HTML Table 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -412,6 +373,7 @@ If you plan to use this content for illegal purpose, don't.  Have a nice day :)' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     <th>Birth</th> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     <th>Entries</th> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     <th>TLDs Available</th> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <th>Status</th> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     <th>Bluecoat</th> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     <th>Categorization</th> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     <th>IBM-xForce</th> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -432,10 +394,12 @@ If you plan to use this content for illegal purpose, don't.  Have a nice day :)' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         htmlTableBody += '<td>{}</td>'.format(i[1]) # Birth 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         htmlTableBody += '<td>{}</td>'.format(i[2]) # Entries 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         htmlTableBody += '<td>{}</td>'.format(i[3]) # TLDs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        htmlTableBody += '<td>{}</td>'.format(i[4]) # Status 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         htmlTableBody += '<td><a href="https://sitereview.bluecoat.com/sitereview.jsp#/?search={}" target="_blank">Bluecoat</a></td>'.format(i[0]) # Bluecoat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        htmlTableBody += '<td>{}</td>'.format(i[4]) # Bluecoat Categorization 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        htmlTableBody += '<td>{}</td>'.format(i[5]) # Bluecoat Categorization 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         htmlTableBody += '<td><a href="https://exchange.xforce.ibmcloud.com/url/{}" target="_blank">IBM-xForce</a></td>'.format(i[0]) # IBM xForce 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        htmlTableBody += '<td>{}</td>'.format(i[5]) # IBM x-Force Categorization 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        htmlTableBody += '<td>{}</td>'.format(i[6]) # IBM x-Force Categorization 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         htmlTableBody += '<td><a href="http://www.borderware.com/domain_lookup.php?ip={}" target="_blank">WatchGuard</a></td>'.format(i[0]) # Borderware WatchGuard 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         htmlTableBody += '<td><a href="https://www.namecheap.com/domains/registration/results.aspx?domain={}" target="_blank">Namecheap</a></td>'.format(i[0]) # Namecheap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         htmlTableBody += '<td><a href="http://web.archive.org/web/*/{}" target="_blank">Archive.org</a></td>'.format(i[0]) # Archive.org 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -449,8 +413,7 @@ If you plan to use this content for illegal purpose, don't.  Have a nice day :)' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     log.close 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print("\n[*] Search complete") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    print("[*] Log written to {}\n").format(logfilename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    print("[*] Log written to {}\n".format(logfilename)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print(t.draw()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |