(.*?)', re.S)
79 | link_regex = re.compile('(.*?) ', re.S)
80 | links = []
81 | try:
82 | results_tbl = tbl_regex.findall(resp)[0]
83 | except IndexError:
84 | results_tbl = ''
85 | links_list = link_regex.findall(results_tbl)
86 | links = list(set(links_list))
87 | for link in links:
88 | subdomain = link.strip()
89 | if not subdomain.endswith(self.domain):
90 | continue
91 | if subdomain and subdomain not in self.subdomains and subdomain != self.domain:
92 | self.subdomains.append(subdomain.strip())
93 | return links
94 |
95 | if __name__ == "__main__":
96 | proxy = {"https":"https://127.0.0.1:9988"}
97 | proxy = {"http":"http://127.0.0.1:9988"}
98 | proxy = {}
99 | x = DNSdumpster("meizu.com",proxy)
100 | print x.run()
--------------------------------------------------------------------------------
/teemo/domainsites/Googlect.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 | #根据证书返回结构,会返回带*号的域名,可用于查找属于同机构的多个域名,和相似域名。
6 |
7 | from lib.log import logger
8 | import time
9 | from lib.myparser import parser
10 | from random import Random,uniform #googlect
11 | import ast
12 | from lib import myrequests
13 | req = myrequests
14 | try:
15 | import requests.packages.urllib3
16 | requests.packages.urllib3.disable_warnings()
17 | except:
18 | pass
19 |
20 | class Googlect():
21 | #https://www.google.com/transparencyreport/jsonp/ct/search?domain=apple.com&incl_exp=true&incl_sub=true&token=CAo%3D&c=_callbacks_._4ixpyevsd
22 | #https://transparencyreport.google.com/transparencyreport/api/v3/httpsreport/ct/certsearch?include_expired=true&include_subdomains=true&domain=jd.com
23 | def __init__(self, domain, proxy=None):
24 | self.verify = ""
25 | #self.domain = urlparse.urlparse(domain).netloc
26 | self.domain = domain
27 | self.token = ""
28 | self.dns_names = []
29 | self.subjects = []
30 | self.hashs = []
31 | self.num_result = 0
32 | self.website = 'https://transparencyreport.google.com/transparencyreport/api/v3/httpsreport/ct'
33 | self.subdomains = []
34 | self.engine_name = "GoogleCT"
35 | self.timeout = 10
36 | self.print_banner()
37 | self.proxy = proxy
38 | self.domain_name = []
39 | self.smiliar_domain_name = []
40 | self.email = []
41 | self.result = ""
42 | return
43 |
44 | def print_banner(self):
45 | logger.info("Searching now in {0}..".format(self.engine_name))
46 | return
47 |
48 | def random_sleep(self):
49 | time.sleep(uniform(0,2))
50 |
51 | def random_str(self, randomlength=8):
52 | rstr = ''
53 | chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
54 | length = len(chars) - 1
55 | random = Random()
56 | for i in range(randomlength):
57 | rstr += chars[random.randint(0, length)]
58 | return rstr.lower()
59 |
60 | def run(self):
61 | self.parser_subject()
62 | self.dns_names = list(set(self.dns_names))
63 | for item in self.dns_names:
64 | if self.domain in item:
65 | self.domain_name.append(item)
66 | else:
67 | self.smiliar_domain_name.append(item)
68 | #self.subjects = list(set(self.subjects))
69 | logger.info("{0} found {1} domains".format(self.engine_name, len(self.dns_names)))
70 | return self.domain_name,self.smiliar_domain_name,self.email
71 | def req(self, url):
72 | headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/40.0',
73 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
74 | 'Accept-Language': 'en-GB,en;q=0.5',
75 | 'Accept-Encoding': 'gzip, deflate',
76 | }
77 | try:
78 | resp = req.get(url, headers=headers, timeout=self.timeout,proxies = self.proxy,verify=False)
79 | if resp.status_code == 200:
80 | if hasattr(resp, "text"):
81 | self.result = resp.text
82 | else:
83 | self.result = resp.content
84 | return True
85 | else:
86 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1], resp.reason))
87 | return False
88 | except Exception as e:
89 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
90 | return False
91 | def parser_subject(self):
92 | try:
93 | #certsearch?include_expired=true&include_subdomains=true&domain=jd.com
94 | url = '{0}/certsearch?domain={1}&include_expired=true&include_subdomains=true'.format(
95 | self.website, self.domain)
96 | if self.req(url):
97 | result = (self.result[6:-1]).replace("\n","").replace("[","").replace("]","").split(",")[-4]
98 | total_page = (self.result[6:-1]).replace("\n","").replace("[","").replace("]","").split(",")[-1]
99 | current_page = (self.result[6:-1]).replace("\n", "").replace("[", "").replace("]", "").split(",")[-2]
100 | self.token = ast.literal_eval(result)
101 | rawres = parser(self.result, self.domain)
102 | domains = rawres.hostnames()
103 | if domains!= None:
104 | self.dns_names.extend(domains)
105 | '''
106 | while current_page < total_page:#重复请求,页面未变,该如何修改页面呢?
107 | url = "https://transparencyreport.google.com/transparencyreport/api/v3/httpsreport/ct/certsearch/page?p={0}".format(self.token)
108 | if self.req(url):
109 | print "xxxxx"
110 | current_page = \
111 | (self.result[6:-1]).replace("\n", "").replace("[", "").replace("]", "").split(",")[-2]
112 | print current_page
113 | rawres = parser(self.result, self.domain)
114 | domains = rawres.hostnames()
115 | self.dns_names.extend(domains)
116 | else:
117 | break
118 | '''
119 | except Exception as e:
120 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
121 | return
122 |
123 | if __name__ == "__main__":
124 | proxy = {"https":"https://127.0.0.1:9988"}
125 | proxy = {}
126 | x = Googlect("meizu.com",proxy)
127 | #print x.parser_dnsname()
128 | print x.run()
--------------------------------------------------------------------------------
/teemo/domainsites/Ilink.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | from lib.common import *
7 | from lib.log import logger
8 | from lib import myrequests
9 | req = myrequests
10 |
11 | '''
12 | website offline
13 | '''
14 |
15 | class Ilink():
16 | def __init__(self, domain, proxy=None):
17 | self.url = 'http://i.links.cn/subdomain/'
18 | self.proxy = proxy
19 | #self.domain = urlparse.urlparse(domain).netloc
20 | self.domain = domain
21 | self.subdomains = []
22 | self.engine_name = "Ilinks"
23 | self.domain_name = []
24 | self.smiliar_domain_name = []
25 | self.email = []
26 | self.timeout = 25
27 | self.print_banner()
28 | return
29 |
30 | def print_banner(self):
31 | logger.info("Searching now in {0}..".format(self.engine_name))
32 | return
33 |
34 | def run(self):
35 | try:
36 | payload = {
37 | 'b2': 1,
38 | 'b3': 1,
39 | 'b4': 1,
40 | 'domain': self.domain
41 | }
42 | r = req.post(self.url,data=payload,proxies=self.proxy).content
43 | subs = re.compile(r'(?<=value\=\"http://).*?(?=\">Next page')
64 | link = link_regx.findall(resp)
65 | link = re.sub('host=.*?%s'%self.domain, 'host=%s'%self.domain, link[0])
66 | url = 'http://searchdns.netcraft.com'+link
67 | return url
68 |
69 | def create_cookies(self, cookie):
70 | cookies = dict()
71 | cookies_list = cookie[0:cookie.find(';')].split("=")
72 | cookies[cookies_list[0]] = cookies_list[1]
73 | cookies['netcraft_js_verification_response'] = hashlib.sha1(urllib.unquote(cookies_list[1])).hexdigest()
74 | return cookies
75 |
76 | def get_cookies(self,headers):
77 | if 'set-cookie' in headers:
78 | cookies = self.create_cookies(headers['set-cookie'])
79 | else:
80 | cookies = {}
81 | return cookies
82 |
83 | def enumerate(self):
84 | start_url = self.base_url.format(domain='example.com')
85 | resp = self.req(start_url)
86 | cookies = self.get_cookies(resp.headers)
87 | url = self.base_url.format(domain=self.domain)
88 | while True:
89 | resp = self.get_response(self.req(url,cookies))
90 | self.extract_domains(resp)
91 | if not 'Next page' in resp:
92 | return self.subdomains
93 | break
94 | url = self.get_next(resp)
95 |
96 | def extract_domains(self, resp):
97 | link_regx = re.compile('')
98 | try:
99 | links_list = link_regx.findall(resp)
100 | for link in links_list:
101 | subdomain = urlparse.urlparse(link).netloc
102 | if not subdomain.endswith(self.domain):
103 | continue
104 | if subdomain and subdomain not in self.subdomains and subdomain != self.domain:
105 | #if verbose:
106 | #print "%s%s: %s%s"%(R, self.engine_name, W, subdomain)
107 | self.subdomains.append(subdomain.strip())
108 | return links_list
109 | except Exception as e:
110 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
111 | pass
112 |
113 |
114 | if __name__ == "__main__":
115 | proxy = {"https":"https://127.0.0.1:9988","http":"http://127.0.0.1:9988"}
116 | proxy = {}
117 | x = Netcraft("meizu.com",proxy)
118 | print x.run()
--------------------------------------------------------------------------------
/teemo/domainsites/PassiveDNS.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | #this can search email address ,but not returned
7 | from lib import myparser
8 | from lib.log import logger
9 | from lib import myrequests
10 | req = myrequests
11 |
12 | class PassiveDNS():
13 | def __init__(self, domain, proxy=None):
14 | self.proxy = proxy
15 | self.base_url = 'http://ptrarchive.com/tools/search.htm?label={domain}'
16 | self.domain = domain
17 | self.subdomains = []
18 | self.engine_name = "PassiveDNS"
19 | self.domain_name = []
20 | self.smiliar_domain_name = []
21 | self.email = []
22 | self.timeout = 25
23 | self.print_banner()
24 | self.results= ""
25 | return
26 |
27 | def run(self):
28 | domain_list = self.enumerate()
29 | for domain in domain_list:
30 | if "older.sublist3r" in domain:
31 | pass
32 | else:
33 | self.domain_name.append(domain)
34 | logger.info("{0} found {1} domains".format(self.engine_name, len(self.domain_name)))
35 | return self.domain_name,self.smiliar_domain_name,self.email
36 |
37 | def print_banner(self):
38 | logger.info("Searching now in {0}..".format(self.engine_name))
39 | return
40 |
41 | def req(self, url):
42 | headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/40.0',
43 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
44 | 'Accept-Language': 'en-GB,en;q=0.5',
45 | 'Accept-Encoding': 'gzip, deflate',
46 | }
47 | try:
48 | resp = req.get(url, headers=headers, timeout=self.timeout, proxies = self.proxy)
49 | return resp.content
50 | except Exception as e:
51 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
52 | return None
53 |
54 | def enumerate(self):
55 | url = self.base_url.format(domain=self.domain)
56 | self.results = self.req(url)
57 | return self.get_hostnames()
58 |
59 | def get_hostnames(self):
60 | rawres = myparser.parser(self.results, self.domain)
61 | return rawres.hostnames()
62 |
63 | if __name__ == "__main__":
64 | proxy = {"https":"https://127.0.0.1:9988","http":"http://127.0.0.1:9988"}
65 | proxy = {}
66 | x = PassiveDNS("meizu.com",proxy)
67 | print x.run()
--------------------------------------------------------------------------------
/teemo/domainsites/Pgpsearch.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | import httplib
7 | from lib import myparser
8 | from lib.log import logger
9 | from lib import myrequests
10 | req = myrequests
11 | # to do :return emails
12 |
13 | class Pgpsearch:
14 |
15 | def __init__(self, domain, proxy = None):
16 | self.domain = domain
17 | self.proxy = proxy
18 | self.results = ""
19 | self.url = "http://pgp.mit.edu/pks/lookup?search={domain}&op=index".format(domain =self.domain)
20 | #self.server = "pgp.rediris.es:11371" Not working at the moment
21 | self.userAgent = "(Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
22 | self.engine_name = "PGP"
23 | self.domain_name = []
24 | self.smiliar_domain_name = []
25 | self.email = []
26 | self.timeout = 25
27 | self.print_banner()
28 |
29 | def print_banner(self):
30 | logger.info("Searching now in {0}..".format(self.engine_name))
31 | return
32 |
33 | def process(self):
34 | try:
35 | resp = req.get(url=self.url,proxies = self.proxy,timeout = self.timeout)
36 | self.results = resp.content
37 | except Exception,e:
38 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1], e))
39 |
40 | def get_emails(self):
41 | rawres = myparser.parser(self.results, self.domain)
42 | return rawres.emails()
43 |
44 | def get_hostnames(self):
45 | rawres = myparser.parser(self.results, self.domain)
46 | return rawres.hostnames()
47 | def run(self):
48 | self.process()
49 | self.domain_name = self.get_hostnames() # how to receive emails.
50 | self.email = self.get_emails()
51 | logger.info("{0} found {1} domains and {2} emails".format(self.engine_name, len(self.domain_name), len(self.email)))
52 | return self.domain_name,self.smiliar_domain_name,self.email
53 |
54 | if __name__ == "__main__":
55 | proxy = {"https":"https://127.0.0.1:9988","http":"http://127.0.0.1:9988"}
56 | proxy = {}
57 | x= Pgpsearch("meizu.com",proxy)
58 | print x.run()
--------------------------------------------------------------------------------
/teemo/domainsites/Sitedossier.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | from lib.captcha import *
7 | from lib.log import logger
8 | import re
9 | from lib import myrequests
10 | req = myrequests
11 |
12 | class Sitedossier():
13 | def __init__(self, domain, proxy=None):
14 | #self.domain = urlparse.urlparse(domain).netloc
15 | self.proxy = proxy
16 | self.domain = domain
17 | self.url = 'http://www.sitedossier.com/parentdomain/{0}'.format(self.domain)
18 | self.subdomains = []
19 | self.engine_name = "Sitedossier"
20 | self.domain_name = []
21 | self.smiliar_domain_name = []
22 | self.email = []
23 | self.timeout = 25
24 | self.print_banner()
25 | self.captcha = Captcha()
26 | return
27 |
28 | def print_banner(self):
29 | logger.info("Searching now in {0}..".format(self.engine_name))
30 | return
31 |
32 | def run(self):
33 | try:
34 | r = self.get_content(self.url)
35 | self.parser(r)
36 | self.domain_name = list(set(self.domain_name))
37 | except Exception, e:
38 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1], e))
39 |
40 | logger.info("{0} found {1} domains".format(self.engine_name, len(self.domain_name)))
41 | return self.domain_name,self.smiliar_domain_name,self.email
42 |
43 | def get_content(self, url):
44 | #logger.info('request: {0}'.format(url))
45 | r = req.get(url,proxies = self.proxy).text
46 | if self.human_act(r) is True:
47 | return r
48 | else:
49 | self.get_content(url)
50 |
51 | def parser(self, response):
52 | npage = re.search('Show', response)
53 | if npage:
54 | for sub in self.get_subdomain(response):
55 | self.domain_name.append(sub)
56 | nurl = 'http://www.sitedossier.com/parentdomain/{0}'.format(npage.group(1))
57 | response = self.get_content(nurl)
58 | self.parser(response)
59 | else:
60 | for sub in self.get_subdomain(response):
61 | self.domain_name.append(sub)
62 |
63 | def get_subdomain(self, response):
64 | domain = re.compile(r'(?<=)')
65 | for sub in domain.findall(response):
66 | yield sub
67 |
68 | def human_act(self, response):
69 | if 'auditimage' in response or 'blacklisted' in response:
70 | imgurl = self.get_audit_img(response)
71 | if imgurl is not None:
72 | ret = self.captcha.verification(imgurl)
73 | if ret.has_key('Result'):
74 | self.audit(ret['Result'])
75 | return True
76 | else:
77 | raise Exception("captcha_verification_is_empty")
78 | else:
79 | raise Exception("audit_img_is_empty")
80 | else:
81 | return True
82 |
83 | def audit(self, code):
84 | payload = {'w':code}
85 | url = 'http://www.sitedossier.com/audit'
86 | r = req.post(url, data=payload, proxies = self.proxy)
87 |
88 | def get_audit_img(self, response):
89 | auditimg = re.compile(r'(?<= .*?(.*?)',re.S)
67 | try:
68 | links = link_regx.findall(resp)
69 | for link in links:
70 | subdomain = link.strip()
71 | if not subdomain.endswith(self.domain):
72 | continue
73 | if subdomain not in self.subdomains and subdomain != self.domain:
74 | #if verbose:
75 | #print "%s%s: %s%s"%(R, self.engine_name, W, subdomain)
76 | self.subdomains.append(subdomain.strip())
77 | except Exception as e:
78 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1], e))
79 |
80 |
81 | if __name__ == "__main__":
82 | proxy = {"https":"https://127.0.0.1:9988","http":"http://127.0.0.1:9988"}
83 | #proxy = {}
84 | x = Virustotal("meizu.com",proxy)
85 | print x.run()
--------------------------------------------------------------------------------
/teemo/domainsites/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'bit4'
2 |
--------------------------------------------------------------------------------
/teemo/domian:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ATpiu/farmscan_domain/5b71eb316d7c146786eb140260cfc7e52c46b2dd/teemo/domian
--------------------------------------------------------------------------------
/teemo/ips:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ATpiu/farmscan_domain/5b71eb316d7c146786eb140260cfc7e52c46b2dd/teemo/ips
--------------------------------------------------------------------------------
/teemo/ips.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ATpiu/farmscan_domain/5b71eb316d7c146786eb140260cfc7e52c46b2dd/teemo/ips.txt
--------------------------------------------------------------------------------
/teemo/lib/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/teemo/lib/captcha.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | import json
4 | import time
5 | import requests
6 |
7 | class Captcha(object):
8 | """docstring for Captcha"""
9 | def __init__(self):
10 | super(Captcha, self).__init__()
11 | self.url = 'http://api.ysdm.net/create.json'
12 | self.username = 'a61323636'
13 | self.password = '123456'
14 | self.timeout = 90
15 | self.softid = 1
16 | self.softkey = 'b40ffbee5c1cf4e38028c197eb2fc751'
17 | self.typeid = 3000
18 |
19 | def verification(self, filename):
20 | (cnt,retry) = (0, 3)
21 | while True:
22 | try:
23 | if cnt >= retry:
24 | break # over max_retry_cnt
25 | payload = {
26 | 'username': self.username,
27 | 'password': self.password,
28 | 'timeout': self.timeout,
29 | 'softid': self.softid,
30 | 'softkey': self.softkey,
31 | 'typeid': self.typeid,
32 | }
33 | multiple_files = [('image', ('captcha.gif', open(filename, 'rb'), 'image/gif')),]
34 | r = requests.post(self.url, data=payload, files=multiple_files)
35 | return json.loads(r.text)
36 | except Exception, e:
37 | cnt += 1
38 | print('{0} [INFO] {1}'.format(
39 | time.strftime('%Y-%m-%d %H:%M:%S'), str(e)))
40 | else:
41 | cnt = 0
42 |
43 | # captcha = Captcha()
44 | # imgurl = 'http://ce.wooyun.org/captcha.php'
45 | # print captcha.verification(imgurl)
46 |
47 |
48 |
--------------------------------------------------------------------------------
/teemo/lib/color.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | import colorama
7 |
8 | class color:#if not class,when call G\Y\B,the colorama.init() will not be executed. Error will occure!!!
9 | def __init__(self):
10 | colorama.init()
11 | self.G = colorama.Fore.GREEN # green
12 | self.Y = colorama.Fore.YELLOW # yellow
13 | self.B = colorama.Fore.BLUE # blue
14 | self.R = colorama.Fore.RED # red
15 | self.W = colorama.Fore.WHITE # white
16 |
17 | color = color()
--------------------------------------------------------------------------------
/teemo/lib/colorlog.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | # Courtesy http://plumberjack.blogspot.com/2010/12/colorizing-logging-output-in-terminals.html
7 | # Tweaked to use colorama for the coloring
8 |
9 | import colorama
10 | import logging
11 | import sys
12 |
13 | colorama.init()
14 | G = colorama.Fore.GREEN # green
15 | Y = colorama.Fore.YELLOW # yellow
16 | B = colorama.Fore.BLUE # blue
17 | R = colorama.Fore.RED # red
18 | W = colorama.Fore.WHITE # white
19 |
20 | class ColorizingStreamHandler(logging.StreamHandler):
21 | color_map = {
22 | logging.DEBUG: colorama.Fore.BLUE,
23 | logging.INFO: colorama.Fore.GREEN,
24 | logging.WARNING: colorama.Fore.YELLOW,
25 | logging.ERROR: colorama.Fore.RED,
26 | logging.CRITICAL: colorama.Back.RED,
27 | }
28 |
29 | def __init__(self, stream, color_map=None):
30 | logging.StreamHandler.__init__(self,
31 | colorama.AnsiToWin32(stream).stream)
32 | if color_map is not None:
33 | self.color_map = color_map
34 |
35 | @property
36 | def is_tty(self):
37 | isatty = getattr(self.stream, 'isatty', None)
38 | return isatty and isatty()
39 |
40 | def format(self, record):
41 | message = logging.StreamHandler.format(self, record)
42 | if self.is_tty:
43 | # Don't colorize a traceback
44 | parts = message.split('\n', 1)
45 | parts[0] = self.colorize(parts[0], record)
46 | message = '\n'.join(parts)
47 | return message
48 |
49 | def colorize(self, message, record):
50 | try:
51 | return (self.color_map[record.levelno] + message +
52 | colorama.Style.RESET_ALL)
53 | except KeyError:
54 | return message
55 |
56 |
57 | logger = logging.getLogger('Teemo')
58 |
59 | LOGGER_HANDLER = ColorizingStreamHandler(sys.stdout)
60 | FORMATTER = logging.Formatter("\r[%(asctime)s] [%(levelname)s] %(message)s", "%H:%M:%S")
61 | LOGGER_HANDLER.setFormatter(FORMATTER)
62 |
63 | logger.addHandler(LOGGER_HANDLER)
64 | logger.setLevel(logging.INFO)
65 |
66 | if __name__ == '__main__':
67 | handler = ColorizingStreamHandler(sys.stdout)
68 | formatter = logging.Formatter('%(message)s')
69 | handler.setFormatter(formatter)
70 | logger.addHandler(handler)
71 | logger.setLevel(logging.DEBUG)
72 |
73 | logger.debug('debug message')
74 | logger.info('info message')
75 | logger.warning('warning message')
76 | logger.error('error message')
77 | logger.critical('critical message')
--------------------------------------------------------------------------------
/teemo/lib/common.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | import re
4 | import socket
5 | from config import *
6 |
7 | import json
8 | import colorama
9 |
10 | # from tldextract import extract, TLDExtract
11 |
12 | import requests.packages.urllib3
13 | requests.packages.urllib3.disable_warnings()
14 |
15 | def is_domain(domain):
16 | domain_regex = re.compile(
17 | r'(?:[A-Z0-9_](?:[A-Z0-9-_]{0,247}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,}(?=2:
94 | smaller = netaddr.spanning_cidr(tmpIPlist) #type is IPNetwork
95 | #if smaller != net:
96 | smaller_subnet.add(smaller)
97 | elif len(tmpIPlist) ==0:
98 | print "{0} has no ip".format(net)
99 |
100 | result = []
101 | for item in smaller_subnet:
102 | result.append(str(item))
103 | return result
104 |
105 | def smaller_network():
106 | #list = ['192.168.0.0', '192.168.0.245', '192.168.0.255']
107 | #list = ['192.168.2.245']
108 | x = netaddr.spanning_cidr(list)
109 | print x
110 |
111 |
112 | if __name__ == "__main__":
113 | domains = open("C:\Users\jax\Desktop\hrpc (2).txt").readlines()
114 |
115 | x,lines= domains2ips(domains,"172.30.35.35")
116 | #print x
117 | #print smaller_network()
118 | print iprange(x)# problem
--------------------------------------------------------------------------------
/teemo/lib/log.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | import logging
7 | import sys
8 | import os
9 | sys.path.extend("E:\wolaidai\github\Teemo\\")
10 | reload(sys)
11 |
12 | LOGGER = logging.getLogger("TeemoLog")
13 |
14 | LOGGER_HANDLER = None
15 | try:
16 | from thirdparty.ansistrm.ansistrm import ColorizingStreamHandler
17 |
18 | disableColor = False
19 |
20 | for argument in sys.argv:
21 | if "disable-col" in argument:
22 | disableColor = True
23 | break
24 |
25 | if disableColor:
26 | LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
27 | else:
28 | LOGGER_HANDLER = ColorizingStreamHandler(sys.stdout)
29 | except ImportError,e:
30 | #print e
31 | LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
32 |
33 | FORMATTER = logging.Formatter("\r[%(asctime)s] [%(levelname)s] %(message)s", "%H:%M:%S")
34 |
35 | LOGGER_HANDLER.setFormatter(FORMATTER)
36 | LOGGER.addHandler(LOGGER_HANDLER)
37 | LOGGER.setLevel(logging.INFO)
38 |
39 | logger = LOGGER
40 |
41 | if __name__ == "__main__":
42 | engine_name ="xx"
43 | logger.warning("warning")
44 | logger.info("log")
45 | logger.debug("debug")
46 | logger.error("sss")
47 | logger.info("Searching now in {0}..".format(engine_name))
48 | print os.path.basename(__file__)
--------------------------------------------------------------------------------
/teemo/lib/myparser.py:
--------------------------------------------------------------------------------
1 | import string
2 | import re
3 | import urllib
4 |
5 |
6 | class parser:
7 |
8 | def __init__(self, results, word):
9 | self.results = results
10 | self.word = word
11 | self.temp = []
12 |
13 | def genericClean(self):
14 | self.results = re.sub('', '', self.results)
15 | self.results = re.sub('', '', self.results)
16 | self.results = re.sub('', '', self.results)
17 | self.results = re.sub('', '', self.results)
18 | #self.results = re.sub('%2f', ' ', self.results)
19 | #self.results = re.sub('%3a', ' ', self.results)
20 | self.results = re.sub('', '', self.results)
21 | self.results = re.sub('', '', self.results)
22 | self.results = re.sub('','',self.results)
23 | self.results = re.sub('','',self.results)
24 |
25 | i= 3
26 | while True:
27 | self.results = urllib.unquote(self.results)
28 | if "%25" in self.results and i>0:
29 | self.results = urllib.unquote(self.results)
30 | i -= 1
31 | continue
32 | else:
33 | self.results = urllib.unquote(self.results)
34 | i -= 1
35 | break
36 |
37 |
38 | for e in ('>', ':', '=', '<', '/', '\\', ';', '&', '%3A', '%3D', '%3C'):
39 | self.results = string.replace(self.results, e, ' ')
40 |
41 | def urlClean(self):
42 | self.results = re.sub('', '', self.results)
43 | self.results = re.sub('', '', self.results)
44 | self.results = re.sub('%2f', ' ', self.results)
45 | self.results = re.sub('%3a', ' ', self.results)
46 |
47 | for e in ('<', '>', ':', '=', ';', '&', '%3A', '%3D', '%3C'):
48 | self.results = string.replace(self.results, e, ' ')
49 |
50 | def emails(self):
51 | self.genericClean()
52 | reg_emails = re.compile(
53 | # Local part is required, charset is flexible
54 | # https://tools.ietf.org/html/rfc6531 (removed * and () as they provide FP mostly )
55 | '[a-zA-Z0-9.\-_+#~!$&,;=:]+' +
56 | '@' +
57 | '[a-zA-Z0-9.-]*' +
58 | self.word)
59 | self.temp = reg_emails.findall(self.results)
60 | emails = self.unique()
61 | return emails
62 |
63 | def fileurls(self, file):
64 | urls = []
65 | reg_urls = re.compile('', '', self.results)
77 | self.results = re.sub('', '', self.results)
78 | reg_people = re.compile('>[a-zA-Z0-9._ ]* - Google\+')
79 | #reg_people = re.compile('">[a-zA-Z0-9._ -]* profiles | LinkedIn')
80 | self.temp = reg_people.findall(self.results)
81 | resul = []
82 | for x in self.temp:
83 | y = string.replace(x, ' | LinkedIn', '')
84 | y = string.replace(y, ' profiles ', '')
85 | y = string.replace(y, 'LinkedIn', '')
86 | y = string.replace(y, '"', '')
87 | y = string.replace(y, '>', '')
88 | if y != " ":
89 | resul.append(y)
90 | return resul
91 |
92 |
93 |
94 | def people_twitter(self):
95 | reg_people = re.compile('(@[a-zA-Z0-9._ -]*)')
96 | #reg_people = re.compile('">[a-zA-Z0-9._ -]* profiles | LinkedIn')
97 | self.temp = reg_people.findall(self.results)
98 | users = self.unique()
99 | resul = []
100 | for x in users:
101 | y = string.replace(x, ' | LinkedIn', '')
102 | y = string.replace(y, ' profiles ', '')
103 | y = string.replace(y, 'LinkedIn', '')
104 | y = string.replace(y, '"', '')
105 | y = string.replace(y, '>', '')
106 | if y != " ":
107 | resul.append(y)
108 | return resul
109 |
110 | def people_linkedin(self):
111 | reg_people = re.compile('">[a-zA-Z0-9._ -]* \| LinkedIn')
112 | #reg_people = re.compile('">[a-zA-Z0-9._ -]* profiles | LinkedIn')
113 | self.temp = reg_people.findall(self.results)
114 | resul = []
115 | for x in self.temp:
116 | y = string.replace(x, ' | LinkedIn', '')
117 | y = string.replace(y, ' profiles ', '')
118 | y = string.replace(y, 'LinkedIn', '')
119 | y = string.replace(y, '"', '')
120 | y = string.replace(y, '>', '')
121 | if y != " ":
122 | resul.append(y)
123 | return resul
124 |
125 | def profiles(self):
126 | reg_people = re.compile('">[a-zA-Z0-9._ -]* - Google Profile')
127 | self.temp = reg_people.findall(self.results)
128 | resul = []
129 | for x in self.temp:
130 | y = string.replace(x, ' Google Profile', '')
131 | y = string.replace(y, '-', '')
132 | y = string.replace(y, '">', '')
133 | if y != " ":
134 | resul.append(y)
135 | return resul
136 |
137 | def people_jigsaw(self):
138 | res = []
139 | #reg_people = re.compile("'tblrow' title='[a-zA-Z0-9.-]*'>")
140 | reg_people = re.compile(
141 | "href=javascript:showContact\('[0-9]*'\)>[a-zA-Z0-9., ]*")
142 | self.temp = reg_people.findall(self.results)
143 | for x in self.temp:
144 | a = x.split('>')[1].replace("[a-zA-Z0-9]*')
168 | self.temp = reg_sets.findall(self.results)
169 | sets = []
170 | for x in self.temp:
171 | y = string.replace(x, '>', '')
172 | y = string.replace(y, '(.*?)')
178 | temp = reg_hosts.findall(self.results)
179 | for x in temp:
180 | if x.count(':'):
181 | res = x.split(':')[1].split('/')[2]
182 | else:
183 | res = x.split("/")[0]
184 | self.temp.append(res)
185 | hostnames = self.unique()
186 | return hostnames
187 |
188 | def unique(self):
189 | self.new = []
190 | for x in self.temp:
191 | if ".." in x: #remove domain name like "IP...www.domain.com"
192 | pass
193 | elif x not in self.new:
194 | self.new.append(x)
195 | return self.new
196 | if __name__ == "__main__":
197 | print("xx")
--------------------------------------------------------------------------------
/teemo/lib/myrequests.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | import config
7 | from lib.log import logger
8 | import traceback
9 | import requests
10 | import requests as __requests__
11 | try:
12 | import requests.packages.urllib3
13 | requests.packages.urllib3.disable_warnings()
14 | except:
15 | pass
16 | '''
17 | 这个类的主要目的是对requests的参数都设置一个默认的值,调用时如果没有参数参数,就使用config中的默认值。
18 | 如果有传入,就是用传入的值。这样,可以在config中全局控制,也可以在具体的调用时定制化控制。
19 | 当然,在具体调用时也可以通过读取config进行修改然后在传入。
20 |
21 | 使用traceback.print_exc(),是为了让这个类和元素requests的表现一模一样。
22 | '''
23 |
24 | if config.allow_http_session:
25 | requests = requests.Session()
26 |
27 | def get(url,stream=False,allow_redirects=config.allow_redirects,headers=config.headers,
28 | cookies = None,timeout=config.timeout,proxies = None,verify= config.allow_ssl_verify):
29 |
30 | try:
31 | result = requests.get(url,
32 | stream=stream,
33 | allow_redirects=allow_redirects,
34 | headers=headers,
35 | cookies = cookies,
36 | timeout=timeout,
37 | proxies=proxies,
38 | verify=verify)
39 | return result
40 | except Exception, e:
41 | raise e#这个信息会被调用它的代码的try ..except捕获,而不会直接在这里输出错误信息,让程序输出更工整
42 | #logger.error("Error in {0}: {1}".format(__file__.split('/')[-1], e))
43 |
44 | # return empty requests object
45 | #return __requests__.models.Response()
46 |
47 | def post(url, data, stream=False, allow_redirects=config.allow_redirects, headers=config.headers,cookies = None,
48 | timeout=config.timeout, proxies = None, verify =config.allow_ssl_verify):
49 | """ data = {'key1': 'value1', 'key2': 'value2'} """
50 | try:
51 | result = requests.post(url,
52 | data=data,
53 | stream=stream,
54 | allow_redirects=allow_redirects,
55 | headers=headers,
56 | cookies = cookies,
57 | timeout=timeout,
58 | proxies=proxies,
59 | verify=verify)
60 | return result
61 | except Exception, e:
62 | raise e
63 | #traceback.print_exc()
64 | #logger.error("Error in {0}: {1}".format(__file__.split('/')[-1], e))
65 | # return empty requests object
66 | #return __requests__.models.Response()
67 |
68 | if __name__ == "__main__":
69 | print type(get("http://www.baidu.com:8000",timeout=1).content)
70 | #requests.get("http://www.baidu.com:8000",timeout=1)
--------------------------------------------------------------------------------
/teemo/lib/zonetransfer.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | import os
7 | import re
8 | import dns.resolver, dns.zone
9 | from lib.log import logger
10 |
11 | class zonetransfer:
12 | def __init__(self,domain):
13 | self.domain= domain
14 | self.nsservers = []
15 | self.results =[]
16 | self.has_zone_transfer = 0
17 |
18 |
19 | def get_ns_server(self):
20 | try:
21 | resolver = dns.resolver.Resolver()
22 | resolver.timeout = 5
23 | resolver.lifetime = 10
24 |
25 | # 使用阿里DNS服务器,效果不咋滴
26 | #resolver.nameservers = ["223.5.5.5", "223.6.6.6"]
27 |
28 | answers = resolver.query(self.domain, "NS")
29 | if answers:
30 | for answer in answers:
31 | #print answer
32 | self.nsservers.append(str(answer))
33 | except Exception, e:
34 | pass
35 | #print "[-]get ns server error! try: dig %s NS +short" %(domain) , str(e)
36 |
37 | def get_ns_server_nslookup(self):
38 | #result = os.system("nslookup -type=ns {0}".format(domain))
39 | result = os.popen('nslookup -type=ns ' + self.domain).read()
40 | #print result
41 | #其实域名后是否有点对axfr查询无影响
42 | '''
43 | if sys.platform == 'win32':
44 | dns_servers = re.findall('nameserver = (.*?)\n', result)
45 | else:
46 | dns_servers = re.findall('nameserver = (.*?)\.\n', result)
47 | '''
48 | dns_servers = re.findall('nameserver = (.*?)\n', result)
49 | self.nsservers.extend(dns_servers)
50 |
51 | def axfr_check(self, domain, nsserver):
52 | try:
53 | zone = dns.zone.from_xfr(dns.query.xfr(str(nsserver), domain, timeout=5, lifetime=10))
54 | if zone:
55 | self.has_zone_transfer += 1
56 | names = zone.nodes.keys()
57 | names.sort()
58 | for n in names:
59 | record = zone[n].to_text(n)
60 | self.results.append(record)
61 | print record
62 | except Exception, e:
63 | #print "[get xfr error]", domain, "\t", nsserver, str(e)
64 | pass
65 |
66 | def check(self):
67 | logger.info("Doing Zone Transfer Check ...")
68 | try:
69 | self.get_ns_server()
70 | self.get_ns_server_nslookup()
71 | except Exception as e:
72 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
73 |
74 | if len(self.nsservers) == 0:
75 | logger.info("None NS Server found for {0}.".format(self.domain))
76 | else:
77 | for _ in self.nsservers:
78 | has_zone_transfer = self.axfr_check(self.domain, _)
79 |
80 | if has_zone_transfer != 0 and len(self.results) != 0:
81 | logger.info("Zone Transfer Detected for {0}".format(self.domain))
82 | fp = open("..\\output\\{0}_zone_transfer.txt".format(self.domain), "wb")
83 | fp.writelines(self.results)
84 | fp.close()
85 | for item in self.results:
86 | print item
87 | if has_zone_transfer == 0 or len(self.results) == 0:
88 | logger.info("Zone Transfer False")
89 |
90 |
91 | if __name__ == '__main__':
92 | '''
93 | a = get_ns_server("meizu.com")
94 | b = get_ns_server_nslookup("meizu.com")
95 | print a
96 | print b
97 |
98 | for _ in ["ns1.as6453.net"]:
99 | z= axfr_check("bf",_)
100 | '''
101 | zonetransfer("meizu.com").check()
102 |
--------------------------------------------------------------------------------
/teemo/mail:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ATpiu/farmscan_domain/5b71eb316d7c146786eb140260cfc7e52c46b2dd/teemo/mail
--------------------------------------------------------------------------------
/teemo/output/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ATpiu/farmscan_domain/5b71eb316d7c146786eb140260cfc7e52c46b2dd/teemo/output/.gitignore
--------------------------------------------------------------------------------
/teemo/requirements.txt:
--------------------------------------------------------------------------------
1 | argparse
2 | dnspython
3 | requests
4 | shodan
5 | win_unicode_console
6 | colorama
7 | netaddr
8 | gevent
--------------------------------------------------------------------------------
/teemo/searchengine/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'bit4'
2 |
--------------------------------------------------------------------------------
/teemo/searchengine/search_ask.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 | from lib import myparser
6 | from lib.log import logger
7 | import re
8 | from lib import myrequests
9 | req = myrequests
10 |
11 | #核心方法之一,没有请求限制,只是需要代理
12 |
13 | class search_ask():
14 |
15 | def __init__(self, word, limit, proxy=None):
16 | self.engine_name = "Ask"
17 | self.word = word.replace(' ', '%20')
18 | self.results = "" #本页搜索结果
19 | self.totalresults = "" #所有搜索结果
20 | self.server = "www.ask.com"
21 | #self.quantity = "100" #useless
22 | self.limit = int(limit) #item number?
23 | self.counter = 0 #page number ---> page 参数
24 | self.proxies = proxy
25 | self.print_banner()
26 | return
27 |
28 | def print_banner(self):
29 | logger.info("Searching now in {0}..".format(self.engine_name))
30 | return
31 |
32 | def do_search(self):
33 | try:
34 | url = "http://{0}/web?q={1}&pu=100&page={2}".format(self.server, self.word,self.counter) # %40=@ 搜索内容如:@meizu.com;在关键词前加@有何效果呢?,测试未发现不同
35 | r = req.get(url, proxies = self.proxies)
36 | #如果不指定header, agent的值将如下 : User-Agent: python-requests/2.18.1 这对有请求限制的搜索引擎很关键,比如google
37 | #采用随机user agent的话,
38 | self.results = r.content
39 | self.totalresults += self.results
40 | return True
41 | except Exception,e:
42 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
43 | return False
44 |
45 | def check_next(self):
46 | renext = re.compile('>Next<') #
47 | nextres = renext.findall(self.results)
48 | if nextres != []:
49 | nexty = "1"
50 | else:
51 | nexty = "0"
52 | return nexty
53 |
54 | def get_people(self):
55 | rawres = myparser.parser(self.totalresults, self.word)
56 | return rawres.people_jigsaw()
57 |
58 | def process(self):
59 | while (self.counter < self.limit/100): #limit = item number; counter= page number ... 100 items per page
60 | if self.do_search():
61 | more = self.check_next()
62 | if more == "1":
63 | self.counter += 1
64 | continue
65 | else:
66 | break
67 | else:
68 | break
69 |
70 | def get_emails(self):
71 | rawres = myparser.parser(self.totalresults, self.word)
72 | return rawres.emails()
73 |
74 | def get_hostnames(self):
75 | rawres = myparser.parser(self.totalresults, self.word)
76 | return rawres.hostnames()
77 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
78 | self.process()
79 | self.d = self.get_hostnames()
80 | self.e = self.get_emails()
81 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
82 | return self.d, self.e
83 |
84 | if __name__ == "__main__":
85 | proxy = {"http":"http://127.0.0.1:9988"}
86 | useragent = "(Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
87 | search = search_ask("meizu.com", '1000')
88 | search.process()
89 | emails = search.get_emails()
90 | hosts = search.get_hostnames()
91 | print emails
92 | print hosts #test successed
--------------------------------------------------------------------------------
/teemo/searchengine/search_baidu.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | from lib import myparser
7 | from lib.log import logger
8 | import time
9 | from lib import myrequests
10 | req = myrequests
11 |
12 | class search_baidu:
13 |
14 | def __init__(self, word, limit, proxy=None):
15 | self.engine_name ="Baidu"
16 | self.word = word
17 | self.limit = int(limit)
18 | self.results = ""
19 | self.totalresults = ""
20 | self.proxies = proxy
21 | self.server = "www.baidu.com"
22 | self.counter = 0 #
23 | self.print_banner()
24 | return
25 |
26 | def print_banner(self):
27 | logger.info("Searching now in {0}..".format(self.engine_name))
28 | return
29 |
30 | def do_search(self):
31 | try:
32 | url = "http://{0}/s?wd={1}&pn={2}".format(self.server,self.word,self.counter)# 这里的pn参数是条目数
33 | r = req.get(url, proxies = self.proxies)
34 | self.results = r.content
35 | self.totalresults += self.results
36 | return True
37 | except Exception, e:
38 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
39 | return False
40 |
41 | def process(self):
42 | while self.counter <= self.limit and self.counter <= 1000:
43 | if self.do_search():
44 | time.sleep(1)
45 | #print "\tSearching " + str(self.counter) + " results..."
46 | self.counter += 10
47 | continue
48 | else:
49 | break
50 |
51 | def get_emails(self):
52 | rawres = myparser.parser(self.totalresults, self.word)
53 | #print "%s email(s) found in Baidu" %len(rawres.emails())
54 | return rawres.emails()
55 |
56 | def get_hostnames(self):
57 | rawres = myparser.parser(self.totalresults, self.word)
58 | #print "%s domain(s) found in Baidu" %len(rawres.hostnames())
59 | return rawres.hostnames()
60 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
61 | self.process()
62 | self.d = self.get_hostnames()
63 | self.e = self.get_emails()
64 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
65 | return self.d, self.e
66 |
67 |
68 | if __name__ == "__main__":
69 | useragent = "(Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
70 | proxy = {"http":"http://127.0.0.1:8080"}
71 | search = search_baidu("meizu.com", '100',proxy)
72 | search.process()
73 | all_emails = search.get_emails()
74 | all_hosts = search.get_hostnames()
75 | print all_hosts
76 | print all_emails#test successed
77 |
--------------------------------------------------------------------------------
/teemo/searchengine/search_bing.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 | import httplib
6 | from lib import myparser
7 | from lib.log import logger
8 | import time
9 | import requests
10 |
11 | class search_bing:
12 |
13 | def __init__(self, word, limit, proxy=None):
14 | self.engine_name = "Bing"
15 | self.word = word.replace(' ', '%20')
16 | self.results = ""
17 | self.totalresults = ""
18 | self.server = "cn.bing.com"
19 | self.limit = int(limit)
20 | self.counter = 0
21 | self.headers = {"Cookie":"SRCHHPGUSR=ADLT=DEMOTE&NRSLT=50","Accept-Language":"'en-us,en"}
22 | self.proxies = proxy
23 | self.print_banner()
24 | return
25 |
26 | def print_banner(self):
27 | logger.info("Searching now in {0}..".format(self.engine_name))
28 | return
29 |
30 | def do_search(self):
31 | try:
32 | url = "http://{0}/search?q={1}&count=50&first={2}".format(self.server,self.word,self.counter)# 这里的pn参数是条目数
33 | r = requests.get(url, headers = self.headers, proxies = self.proxies)
34 | self.results = r.content
35 | self.totalresults += self.results
36 | return True
37 | except Exception, e:
38 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1], e))
39 | return False
40 |
41 | def do_search_vhost(self):
42 | h = httplib.HTTP(self.server)
43 | h.putrequest('GET', "/search?q=ip:" + self.word +
44 | "&go=&count=50&FORM=QBHL&qs=n&first=" + str(self.counter))
45 | h.putheader('Host', self.hostname)
46 | h.putheader(
47 | 'Cookie', 'mkt=en-US;ui=en-US;SRCHHPGUSR=NEWWND=0&ADLT=DEMOTE&NRSLT=50')
48 | h.putheader('Accept-Language', 'en-us,en')
49 | h.putheader('User-agent', self.userAgent)
50 | h.endheaders()
51 | returncode, returnmsg, headers = h.getreply()
52 | self.results = h.getfile().read()
53 | #print self.results
54 | self.totalresults += self.results
55 |
56 | def get_emails(self):
57 | rawres = myparser.parser(self.totalresults, self.word)
58 | return rawres.emails()
59 |
60 | def get_hostnames(self):
61 | rawres = myparser.parser(self.totalresults, self.word)
62 | return rawres.hostnames()
63 |
64 | def get_allhostnames(self):
65 | rawres = myparser.parser(self.totalresults, self.word)
66 | return rawres.hostnames_all()
67 |
68 | def process(self):
69 | while (self.counter < self.limit):
70 | if self.do_search():
71 | #self.do_search_vhost()
72 | time.sleep(1)
73 | self.counter += 50
74 | continue
75 | else:
76 | break
77 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
78 | self.process()
79 | self.d = self.get_hostnames()
80 | self.e = self.get_emails()
81 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
82 | return self.d, self.e
83 |
84 | if __name__ == "__main__":
85 | print "[-] Searching in Bing:"
86 | useragent = "(Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
87 | search = search_bing("meizu.com", '10', useragent)
88 | search.process()
89 | all_emails = search.get_emails()
90 | all_hosts = search.get_hostnames()
91 | print all_emails
92 | print all_hosts # test pass
--------------------------------------------------------------------------------
/teemo/searchengine/search_bing_api.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | from lib.log import logger
7 | from lib import myparser
8 | import time
9 | import config
10 | from lib import myrequests
11 | req = myrequests
12 |
13 | #https://azure.microsoft.com/zh-cn/try/cognitive-services/my-apis/
14 | #https://api.cognitive.microsoft.com/bing/v5.0/search
15 |
16 | #https://docs.microsoft.com/en-us/azure/cognitive-services/bing-web-search/quick-start
17 |
18 | #https://api.cognitive.microsoft.com/bing/v5.0/search[?q][&count][&offset][&mkt][&safesearch]
19 | #https://dev.cognitive.microsoft.com/docs/services/56b43eeccf5ff8098cef3807/operations/56b4447dcf5ff8098cef380d
20 |
21 |
22 | class search_bing_api:
23 |
24 | def __init__(self, word, limit, proxy=None):
25 | self.engine_name = "BingAPI"
26 | self.word = word.replace(' ', '%20')
27 | self.results = ""
28 | self.totalresults = ""
29 | self.server = "api.cognitive.microsoft.com"
30 | self.headers = {"Ocp-Apim-Subscription-Key":config.Bing_API_Key,}
31 | self.limit = int(limit)
32 | try:
33 | self.bingApikey = config.Bing_API_Key
34 | except:
35 | logger.warning("No Bing API Key,Exit")
36 | exit(0)
37 | self.counter = 0
38 | self.proxies = proxy
39 | self.print_banner()
40 | return
41 |
42 | def print_banner(self):
43 | logger.info("Searching now in {0}..".format(self.engine_name))
44 | return
45 |
46 | def do_search(self):
47 | try:
48 | url = "http://api.cognitive.microsoft.com/bing/v7.0/search?q={0}&mkt=en-us".format(self.word,self.counter)# 这里的pn参数是条目数
49 | r = req.get(url, headers = self.headers, proxies = self.proxies)
50 | self.results = r.content
51 | self.totalresults += self.results
52 | return True
53 | except Exception, e:
54 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
55 | return False
56 |
57 | def get_emails(self):
58 | rawres = myparser.parser(self.totalresults, self.word)
59 | return rawres.emails()
60 |
61 | def get_hostnames(self):
62 | rawres = myparser.parser(self.totalresults, self.word)
63 | return rawres.hostnames()
64 |
65 | def get_allhostnames(self):
66 | rawres = myparser.parser(self.totalresults, self.word)
67 | return rawres.hostnames_all()
68 |
69 | def process(self):
70 | while (self.counter < self.limit):
71 | if self.do_search():
72 | time.sleep(0.3)
73 | self.counter += 50
74 | continue
75 | else:
76 | break
77 |
78 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
79 | self.process()
80 | self.d = self.get_hostnames()
81 | self.e = self.get_emails()
82 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name, len(self.d), len(self.e)))
83 | return self.d, self.e
84 |
85 | if __name__ == "__main__":
86 | print "[-] Searching in Bing API:"
87 | useragent = "Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
88 | proxy = {"http": "http://127.0.0.1:8080"}
89 | search = search_bing_api("meizu.com", '100', useragent, proxy)
90 | search.process()
91 | all_emails = search.get_emails()
92 | all_hosts = search.get_hostnames()
93 | print all_emails
94 | print all_hosts # officcal service stopped ?
--------------------------------------------------------------------------------
/teemo/searchengine/search_dogpile.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | from lib import myparser
7 | from lib.log import logger
8 | import time
9 | from lib import myrequests
10 | req = myrequests
11 |
12 | class search_dogpile:
13 |
14 | def __init__(self, word, limit, proxy=None):
15 | self.engine_name = "DogPile"
16 | self.word = word
17 | self.total_results = ""
18 | self.results =""
19 | self.server = "www.dogpile.com"
20 | self.limit = int(limit)
21 | self.counter = 0
22 | self.proxies = proxy
23 | self.print_banner()
24 | return
25 |
26 | def print_banner(self):
27 | logger.info("Searching now in {0}..".format(self.engine_name))
28 | return
29 | def do_search(self):
30 | try:
31 | url = "http://{0}/search/web?qsi={1}&q={2}".format(self.server,self.counter,self.word)
32 | r = req.get(url, proxies = self.proxies)
33 | self.results = r.content
34 | self.total_results += self.results
35 | return True
36 | except Exception, e:
37 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
38 | return False
39 |
40 |
41 | def process(self):
42 | while self.counter <= self.limit and self.counter <= 1000:
43 | if self.do_search():
44 | time.sleep(1)
45 | #print "\tSearching " + str(self.counter) + " results..."
46 | self.counter += 20
47 | continue
48 | else:
49 | break
50 |
51 | def get_emails(self):
52 | rawres = myparser.parser(self.total_results, self.word)
53 | return rawres.emails()
54 |
55 | def get_hostnames(self):
56 | rawres = myparser.parser(self.total_results, self.word)
57 | return rawres.hostnames()
58 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
59 | self.process()
60 | self.d = self.get_hostnames()
61 | self.e = self.get_emails()
62 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
63 | return self.d, self.e
64 |
65 | if __name__ == "__main__":
66 | print "[-] Searching in dogpilesearch:"
67 | useragent = "Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6" #他会检查useragent,之前多了一个( 导致504
68 | proxy = {"http": "http://127.0.0.1:9988"}
69 | search = search_dogpile("meizu.com", '100',proxy)
70 | search.process()
71 | all_emails = search.get_emails()
72 | all_hosts = search.get_hostnames()
73 | print all_emails
74 | print all_hosts # test pass
--------------------------------------------------------------------------------
/teemo/searchengine/search_duckduckgo.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | from lib import myparser
7 | from lib.log import logger
8 | import time
9 | import random
10 | from lib import myrequests
11 | req = myrequests
12 |
13 | class search_duckduckgo:
14 |
15 | def __init__(self, word, limit, proxy=None):
16 | self.engine_name = "DuckDuckGo"
17 | self.word = word
18 | self.total_results = ""
19 | self.results =""
20 | self.server = "duckduckgo.com" #must use https
21 | self.limit = int(limit)
22 | self.counter = 0
23 | self.proxies = proxy
24 | self.print_banner()
25 | return
26 |
27 | def print_banner(self):
28 | logger.info("Searching now in {0}..".format(self.engine_name))
29 | return
30 |
31 | def do_search(self):
32 | try:
33 | url = "https://{0}/?q={1}".format(self.server,self.word)
34 | r = req.get(url, proxies = self.proxies,verify=False)
35 | self.results = r.content
36 | self.total_results += self.results
37 | return True
38 | #must use https
39 | except Exception, e:
40 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
41 | return False
42 |
43 | def process(self):
44 | while self.counter <= self.limit and self.counter <= 1000:
45 | if self.do_search():
46 | time.sleep(random.randint(1,3))
47 | self.counter += 20
48 | continue
49 | else:
50 | break
51 |
52 | def get_emails(self):
53 | rawres = myparser.parser(self.total_results, self.word)
54 | return rawres.emails()
55 |
56 | def get_hostnames(self):
57 | rawres = myparser.parser(self.total_results, self.word)
58 | return rawres.hostnames()
59 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
60 | self.process()
61 | self.d = self.get_hostnames()
62 | self.e = self.get_emails()
63 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
64 | return self.d, self.e
65 |
66 | def dogpile(keyword, limit, useragent,proxy): #define this function to use in threading.Thread(),becuase the arg need to be a function
67 | search = search_duckduckgo(keyword, limit,useragent,proxy)
68 | search.process()
69 | print search.get_emails()
70 | return search.get_emails(), search.get_hostnames()
71 |
72 |
73 | if __name__ == "__main__":
74 | print "[-] Searching in duckduckgo:"
75 | useragent = "Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6" #他会检查useragent,之前多了一个( 导致504
76 | proxy = {"https": "https://127.0.0.1:9988"}
77 | search = search_duckduckgo("meizu.com", '100',useragent)
78 | search.process()
79 | all_emails = search.get_emails()
80 | all_hosts = search.get_hostnames()
81 | print all_emails
82 | print all_hosts # test pass
--------------------------------------------------------------------------------
/teemo/searchengine/search_exalead.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | from lib import myparser
7 | from lib.log import logger
8 | import re
9 | import time
10 | import random
11 | from lib import myrequests
12 | req = myrequests
13 |
14 | class search_exalead:
15 |
16 | def __init__(self, word, limit,proxy=None):
17 | self.engine_name = "Exalead"
18 | self.word = word
19 | self.files = "pdf"
20 | self.results = ""
21 | self.totalresults = ""
22 | self.server = "www.exalead.com"
23 | self.referer = "http://{0}/search/web/results/?q={1}".format(self.server,self.word)
24 | self.headers = {
25 | 'Referer': self.referer,
26 | }
27 | self.limit = int(limit)
28 | self.counter = 0
29 | self.proxies = proxy
30 | self.print_banner()
31 | return
32 |
33 | def print_banner(self):
34 | logger.info("Searching now in {0}..".format(self.engine_name))
35 | return
36 |
37 | def do_search(self):
38 | try:
39 | url = "http://{0}/search/web/results/?q={1}&elements_per_page=50&start_index={2}".format(self.server,self.word,self.counter)# 这里的pn参数是条目数
40 | r = req.get(url, headers=self.headers, proxies = self.proxies)
41 | if "We are sorry, but your request has been blocked" in r.content:
42 | logger.warning("Exalead blocked our request")
43 | return False
44 | else:
45 | self.results = r.content
46 | self.totalresults += self.results
47 | return True
48 | except Exception, e:
49 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
50 | return False
51 |
52 | def do_search_files(self):
53 | try:
54 | url = "http://{0}/search/web/results/?q={1}filetype:{2}&elements_per_page=50&start_index={3}".format(self.server,self.word,self.files,self.counter)# 这里的pn参数是条目数
55 | r = req.get(url, headers = self.headers, proxies = self.proxies)
56 | self.results = r.content
57 | self.totalresults += self.results
58 | except Exception, e:
59 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
60 |
61 | def check_next(self): #for search file
62 | renext = re.compile('topNextUrl')
63 | nextres = renext.findall(self.results)
64 | if nextres != []:
65 | nexty = "1"
66 | #print str(self.counter)
67 | else:
68 | nexty = "0"
69 | return nexty
70 |
71 | def get_emails(self):
72 | rawres = myparser.parser(self.totalresults, self.word)
73 | return rawres.emails()
74 |
75 | def get_hostnames(self):
76 | rawres = myparser.parser(self.totalresults, self.word)
77 | return rawres.hostnames()
78 |
79 | def get_files(self):
80 | rawres = myparser.parser(self.totalresults, self.word)
81 | return rawres.fileurls(self.files)
82 |
83 | def process(self):
84 | while self.counter <= self.limit:
85 | if self.do_search():
86 | self.counter +=50
87 | time.sleep(random.randint(1,3))
88 | continue
89 | else:
90 | break
91 |
92 | def process_files(self):
93 | while self.counter < self.limit:
94 | self.do_search_files(self.files)
95 | time.sleep(1)
96 | more = self.check_next()
97 | if more == "1":
98 | self.counter += 50
99 | else:
100 | break
101 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
102 | self.process()
103 | self.d = self.get_hostnames()
104 | self.e = self.get_emails()
105 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
106 | return self.d, self.e
107 |
108 | if __name__ == "__main__":
109 | print "[-] Searching in exalead:"
110 | useragent = "Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6" #他会检查useragent,之前多了一个( 导致504
111 | proxy = {"http": "http://127.0.0.1:8080"}
112 | search = search_exalead("meizu.com", 100, useragent)
113 | search.process()
114 | all_emails = search.get_emails()
115 | all_hosts = search.get_hostnames()
116 | print all_emails
117 | print all_hosts # blocked
--------------------------------------------------------------------------------
/teemo/searchengine/search_fofa.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | import base64
7 | import config
8 | from lib import myparser
9 | from lib.log import logger
10 | from lib import myrequests
11 | req = myrequests
12 |
13 | class search_fofa:
14 | def __init__(self, word, limit,proxy=None):
15 | self.engine_name = "Fofa"
16 | try:
17 | self.email = config.FOFA_USER_EMAIL
18 | self.key = config.FOFA_API_KEY
19 | except:
20 | logger.warning("No Fofa Config,Exit")
21 | exit(0)
22 | self.word = word
23 | self.results = ""
24 | self.totalresults = ""
25 | self.server = "fofa.so"
26 | self.limit = int(limit)
27 | self.counter = 0 #useless
28 | self.proxies = proxy
29 | self.print_banner()
30 | return
31 |
32 | def print_banner(self):
33 | logger.info("Searching now in {0}..".format(self.engine_name))
34 | return
35 | def do_search(self):
36 | try:
37 | auth_url = "https://fofa.so/api/v1/info/my?email={0}&key={1}".format(self.email, self.key)
38 | auth = req.get(auth_url)
39 | query = base64.b64encode("domain="+self.word)
40 | url = "https://fofa.so/api/v1/search/all?email={0}&key={1}&qbase64={2}".format(self.email, self.key,
41 | query)
42 | r = req.get(url, proxies=self.proxies)
43 | self.results = r.content
44 | self.totalresults += self.results
45 | return True
46 | except Exception, e:
47 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
48 | return False
49 | def get_emails(self):
50 | rawres = myparser.parser(self.totalresults, self.word)
51 | return rawres.emails()
52 |
53 | def get_hostnames(self):
54 | rawres = myparser.parser(self.totalresults, self.word)
55 | return rawres.hostnames()
56 | def process(self):
57 | self.do_search()
58 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
59 | self.process()
60 | self.d = self.get_hostnames()
61 | self.e = self.get_emails()
62 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
63 | return self.d, self.e
64 |
65 | if __name__ == "__main__":
66 | print "[-] Searching in fofa:"
67 | useragent = "Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6" #他会检查useragent,之前多了一个( 导致504
68 | proxy = {"http": "http://127.0.0.1:8080"}
69 | search = search_fofa("meizu.com", 100, useragent)
70 | search.process()
71 | all_emails = search.get_emails()
72 | all_hosts = search.get_hostnames()
73 | print all_emails
74 | print all_hosts
--------------------------------------------------------------------------------
/teemo/searchengine/search_google.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | from lib import myparser
7 | from lib.log import logger
8 | import time
9 | import random
10 | from lib import myrequests
11 | req = myrequests
12 |
13 | class search_google():
14 |
15 | def __init__(self, word, limit, proxy=None):
16 | self.engine_name = "Google"
17 | self.word = word
18 | self.results = ""
19 | self.totalresults = ""
20 | self.files = "pdf"
21 | self.server = "www.google.com"
22 | self.quantity = "100"
23 | self.limit = int(limit)
24 | self.counter = 0
25 | self.proxies = proxy
26 | self.print_banner()
27 | return
28 |
29 | def print_banner(self):
30 | logger.info("Searching now in {0}..".format(self.engine_name))
31 | return
32 |
33 | def do_search(self):
34 | try:
35 | url = "https://{0}/search?num={1}&start={2}&hl=en&meta=&q={3}".format(self.server,self.quantity,self.counter,self.word)
36 | r = req.get(url, proxies=self.proxies)
37 | if "and not a robot" in r.content:
38 | logger.warning("Google has blocked your visit")
39 | return False
40 | else:
41 | self.results = r.content
42 | self.totalresults += self.results
43 | return True
44 | except Exception, e:
45 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
46 | return False
47 |
48 | def do_search_profiles(self):
49 | try:
50 | urly="https://" + self.server + "/search?num=" + self.quantity + "&start=" + str(self.counter) + "&hl=en&meta=&q=site:www.google.com%20intitle:\"Google%20Profile\"%20\"Companies%20I%27ve%20worked%20for\"%20\"at%20" + self.word + "\""
51 | r = req.get(urly, proxies=self.proxies)
52 | self.results = r.content
53 | self.totalresults += self.results
54 | except Exception, e:
55 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
56 |
57 |
58 | def get_emails(self):
59 | rawres = myparser.parser(self.totalresults, self.word)
60 | return rawres.emails()
61 |
62 | def get_hostnames(self):
63 | rawres = myparser.parser(self.totalresults, self.word)
64 | return rawres.hostnames()
65 |
66 | def get_files(self):
67 | rawres = myparser.parser(self.totalresults, self.word)
68 | return rawres.fileurls(self.files)
69 |
70 | def get_profiles(self):
71 | rawres = myparser.parser(self.totalresults, self.word)
72 | return rawres.profiles()
73 |
74 | def process(self):
75 | while self.counter <= self.limit and self.counter <= 1000:
76 | if self.do_search():
77 | time.sleep(random.randint(1, 5)) # should to sleep random time and use random user-agent to prevent block
78 | self.counter += 100
79 | else:
80 | break
81 |
82 | def process_profiles(self):
83 | while self.counter < self.limit:
84 | self.do_search_profiles()
85 | time.sleep(0.3)
86 | self.counter += 100
87 | #print "\tSearching " + str(self.counter) + " results..."
88 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
89 | self.process()
90 | self.d = self.get_hostnames()
91 | self.e = self.get_emails()
92 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
93 | return self.d, self.e
94 |
95 | if __name__ == "__main__":
96 | print "[-] Searching in Google:"
97 | proxy = {"https":"https://127.0.0.1:9988"}
98 | useragent = "Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6" # 他会检查useragent,之前多了一个( 导致504
99 | search = search_google("meizu.com", 100, proxy)
100 | print search.run()
--------------------------------------------------------------------------------
/teemo/searchengine/search_google_cse.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | import sys
7 | from lib.myparser import parser
8 | from lib.log import logger
9 | import time
10 | import config
11 | from lib import myrequests
12 | req = myrequests
13 |
14 | #创建自定义的搜索引擎(CSE)https://cse.google.com/cse/all
15 | #申请API Key: https://developers.google.com/custom-search/json-api/v1/overview
16 | class search_google_cse:
17 | def __init__(self, word, limit, proxy=None):
18 | self.engine_name = "Google_CSE"
19 | self.word = word
20 | self.files = "pdf"
21 | self.results = ""
22 | self.totalresults = ""
23 | self.server = "www.googleapis.com"
24 | self.quantity = "10"
25 | self.limit = int(limit)
26 | self.counter = 1 #不能是0
27 | self.timeout = 20
28 | try:
29 | self.api_key = config.Google_CSE_API_Key
30 | self.cse_id = config.Google_CSE_ID
31 | except:
32 | logger.error("No Google CSE API Key,Exit..")
33 | exit(0)
34 | self.lowRange = 0
35 | self.highRange = 100
36 | self.proxies = proxy
37 | self.print_banner()
38 | return
39 |
40 | def print_banner(self):
41 | logger.info("Searching now in {0}..".format(self.engine_name))
42 | return
43 |
44 | def do_search(self):
45 | try:
46 | url = "https://{0}/customsearch/v1?key={1}&highRange={2}&lowRange={3}&cx={4}&start={5}&q={6}".format(self.server,self.api_key,self.highRange,self.lowRange,self.cse_id,self.counter,self.word)
47 | r = req.get(url, proxies=self.proxies, timeout=self.timeout,verify =False)
48 | if r.status_code != 200:
49 | return False
50 | else:
51 | self.results = r.content
52 | self.totalresults += self.results
53 | return True
54 | except Exception, e:
55 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
56 | return False
57 |
58 | def do_search_files(self):
59 | try:
60 | query = "filetype:"+self.files+"%20site:"+self.word
61 | url = "https://{0}/customsearch/v1?key={1}&highRange={2}&lowRange={3}&cx={4}&start={5}&q={6}".format(self.server,self.api_key,self.highRange,self.lowRange,self.cse_id,self.counter,query)
62 | r = req.get(url,proxies=self.proxies)
63 | if "and not a robot" in r.content:
64 | logger.warning("google has blocked your visit")
65 | return -1
66 | else:
67 | self.results = r.content
68 | self.totalresults += self.results
69 | return 1
70 | except Exception, e:
71 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
72 | return -1
73 |
74 | def get_emails(self):
75 | rawres = parser(self.totalresults, self.word)
76 | return rawres.emails()
77 |
78 | def get_hostnames(self):
79 | rawres = parser(self.totalresults, self.word)
80 | return rawres.hostnames()
81 |
82 | def get_files(self):
83 | rawres = parser(self.totalresults, self.word)
84 | return rawres.fileurls(self.files)
85 |
86 | def process(self):
87 | tracker = self.counter + self.lowRange
88 | while tracker <= self.limit:
89 | if self.do_search():
90 | time.sleep(1)
91 | ESC = chr(27)
92 | sys.stdout.write(ESC + '[2K' + ESC + '[G')
93 | sys.stdout.write("\r\t" + "Searching " + str(self.counter + self.lowRange) + " results ...")
94 | sys.stdout.flush()
95 | # print "\tSearching " + str(self.counter+self.lowRange) + " results...\t\t\t\t\t\r"
96 | if self.counter == 101:
97 | self.counter = 1
98 | self.lowRange += 100
99 | self.highRange += 100
100 | else:
101 | self.counter += 10
102 | tracker = self.counter + self.lowRange
103 | else:
104 | break
105 |
106 | def store_results(self):
107 | filename = "debug_results.txt"
108 | file = open(filename, 'w')
109 | file.write(self.totalresults)
110 |
111 | def process_files(self, files):
112 | while self.counter <= self.limit:
113 | self.do_search_files(files)
114 | time.sleep(1)
115 | self.counter += 100
116 | #print "\tSearching " + str(self.counter) + " results..."
117 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
118 | self.process()
119 | self.d = self.get_hostnames()
120 | self.e = self.get_emails()
121 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
122 | return self.d, self.e
123 |
124 | if __name__ == "__main__":
125 | proxy = {"http": "http://127.0.0.1:9988"}
126 | useragent = "Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6" # 他会检查useragent,之前多了一个( 导致504
127 | x = search_google_cse("meizu.com",100,proxy)
128 | print x.run()
--------------------------------------------------------------------------------
/teemo/searchengine/search_shodan.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 |
7 | import shodan
8 | import config
9 | from lib import myparser
10 | from lib.log import logger
11 | #
12 | class search_shodan:
13 | def __init__(self, word, limit, useragent, proxy=None):
14 | self.engine_name = "Shodan"
15 | self.word = word.replace(' ', '%20')
16 | self.results = "" # 本页搜索结果
17 | self.totalresults = "" # 所有搜索结果
18 | self.server = "shodan.io"
19 | self.headers = {
20 | 'User-Agent': useragent}
21 | self.limit = int(limit)
22 | self.counter = 0
23 | self.proxies = proxy
24 | try:
25 | self.apikey = config.SHODAN_API_KEY
26 | except:
27 | print "No Shodan API Key,Exit"
28 | exit(0)
29 | self.print_banner()
30 | return
31 |
32 | def print_banner(self):
33 | logger.info("Searching now in {0}..".format(self.engine_name))
34 | return
35 |
36 | def do_search(self):
37 | try:
38 | api = shodan.Shodan(self.apikey)
39 | self.results = api.search(self.word)
40 | self.totalresults +=str(self.results)
41 | return True
42 | except shodan.APIError, e:
43 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
44 | return False
45 | def get_emails(self):
46 | rawres = myparser.parser(self.totalresults, self.word)
47 | return rawres.emails()
48 |
49 | def get_hostnames(self):
50 | rawres = myparser.parser(self.totalresults, self.word)
51 | return rawres.hostnames()
52 | def process(self):
53 | self.do_search()
54 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
55 | self.process()
56 | self.d = self.get_hostnames()
57 | self.e = self.get_emails()
58 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
59 | return self.d, self.e
60 |
61 | if __name__ == "__main__":
62 | proxy = {"http": "http://127.0.0.1:8080"}
63 | useragent = "(Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
64 | search = search_shodan("meizu.com",100, useragent)
65 | search.process()
66 | emails = search.get_emails()
67 | hosts = search.get_hostnames()
68 | print emails
69 | print hosts # test successed
--------------------------------------------------------------------------------
/teemo/searchengine/search_so.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 | from lib import myparser
6 | import re
7 | from lib.log import logger
8 | from lib import myrequests
9 | req = myrequests
10 | #核心方法之一,没有请求限制,无需要代理
11 |
12 |
13 | class search_so():
14 |
15 | def __init__(self, word, limit, proxy=None):
16 | self.engine_name = "360SO"
17 | self.word = word.replace(' ', '%20')
18 | self.results = "" #本页搜索结果
19 | self.totalresults = "" #所有搜索结果
20 | self.server = "www.so.com"
21 | self.limit = int(limit)
22 | self.counter = 1 #page number ---> page 参数
23 | self.proxies = proxy
24 | self.print_banner()
25 | return
26 |
27 | def print_banner(self):
28 | logger.info("Searching now in {0}..".format(self.engine_name))
29 | return
30 |
31 | def do_search(self):
32 | try:#https://www.so.com/s?q={query}&pn={page_no}
33 | url = "https://{0}/s?q={1}&pn={2}".format(self.server,self.word,self.counter) # %40=@ 搜索内容如:@meizu.com;在关键词前加@有何效果呢?,测试未发现不同
34 | r = req.get(url, proxies = self.proxies,verify=False)
35 | self.results = r.content
36 | self.totalresults += self.results
37 | return True
38 | except Exception, e:
39 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
40 | return False
41 |
42 | def check_next(self):
43 | renext = re.compile('snext')
44 | nextres = renext.findall(self.results)
45 | if nextres != []:
46 | return True
47 | else:
48 | return False
49 |
50 | def process(self):
51 | while (self.counter < self.limit/10): #limit = item number; counter= page number ... 10 items per page
52 | if self.do_search():
53 | if self.check_next():
54 | self.counter += 1
55 | continue
56 | else:
57 | break
58 | else:
59 | break
60 | def get_emails(self):
61 | rawres = myparser.parser(self.totalresults, self.word)
62 | return rawres.emails()
63 |
64 | def get_hostnames(self):
65 | rawres = myparser.parser(self.totalresults, self.word)
66 | return rawres.hostnames()
67 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
68 | self.process()
69 | self.d = self.get_hostnames()
70 | self.e = self.get_emails()
71 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
72 | return self.d, self.e
73 |
74 |
75 | if __name__ == "__main__":
76 | proxy = {"http":"http://127.0.0.1:8080"}
77 | useragent = "(Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
78 | search = search_so("meizu.com", '100',proxy)
79 | print search.run()
--------------------------------------------------------------------------------
/teemo/searchengine/search_yahoo.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | from lib import myparser
7 | from lib.log import logger
8 | import time
9 | from lib import myrequests
10 | req = myrequests
11 |
12 | class search_yahoo:
13 |
14 | def __init__(self, word, limit, proxy=None):
15 | self.engine_name = "Yahoo"
16 | self.word = word
17 | self.total_results = ""
18 | self.server = "search.yahoo.com"
19 | self.hostname = "search.yahoo.com"
20 | self.limit = int(limit)
21 | self.proxies = proxy
22 | self.counter = 1
23 | self.print_banner()
24 | return
25 |
26 | def print_banner(self):
27 | logger.info("Searching now in {0}..".format(self.engine_name))
28 | return
29 |
30 | def do_search(self):
31 | try:
32 | url = "http://{0}/search?q={1}&b={2}&pz=10".format(self.server,self.word,self.counter) # %40=@ 搜索内容如:@meizu.com;在关键词前加@有何效果呢?,测试未发现不同
33 | r = req.get(url, proxies = self.proxies)
34 | self.results = r.content
35 | self.total_results += self.results
36 | return True
37 | except Exception, e:
38 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
39 | return False
40 |
41 | def process(self):
42 | while self.counter <= self.limit and self.counter <= 200:
43 | if self.do_search():
44 | time.sleep(1)
45 | self.counter += 10
46 | continue
47 | else:
48 | break
49 |
50 | def get_emails(self):
51 | rawres = myparser.parser(self.total_results, self.word)
52 | return rawres.emails()
53 |
54 | def get_hostnames(self):
55 | rawres = myparser.parser(self.total_results, self.word)
56 | return rawres.hostnames()
57 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
58 | self.process()
59 | self.d = self.get_hostnames()
60 | self.e = self.get_emails()
61 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
62 | return self.d, self.e
63 |
64 | if __name__ == "__main__":
65 | useragent = "(Mozilla/5.0 (Windows; U; Windows NT 6.0;en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
66 | search = search_yahoo("meizu.com", '100')
67 | print search.run()
--------------------------------------------------------------------------------
/teemo/searchengine/search_yandex.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | from lib import myparser
7 | from lib.log import logger
8 | import re
9 | import time
10 | import random
11 | from lib import myrequests
12 | req = myrequests
13 |
14 | class search_yandex:
15 |
16 | def __init__(self, word, limit, proxy=None):
17 | self.engine_name = "Yandex"
18 | self.word = word
19 | self.results = ""
20 | self.totalresults = ""
21 | self.server = "yandex.com"
22 | self.limit = int(limit)
23 | self.counter = 0
24 | self.proxies = proxy
25 | self.print_banner()
26 | return
27 |
28 | def print_banner(self):
29 | logger.info("Searching now in {0}..".format(self.engine_name))
30 | return
31 |
32 | def do_search(self):
33 | try:
34 | url = "http://{0}/search?text={1}&numdoc=50&lr=10590&pn={2}".format(self.server,self.word,self.counter) # %40=@ 搜索内容如:@meizu.com;在关键词前加@有何效果呢?,测试未发现不同
35 | r = req.get(url, proxies=self.proxies)
36 | if "automated requests" in r.content:
37 | logger.warning("Yandex blocked our request")
38 | return False
39 | else:
40 | self.results = r.content
41 | self.totalresults += self.results
42 | return True
43 | except Exception, e:
44 | logger.error("Error in {0}: {1}".format(__file__.split('/')[-1],e))
45 | return False
46 |
47 | def do_search_files(self, files): # TODO
48 | url = "http://{0}/search?text=%40{1}&numdoc=50&lr={2}".format(self.server,self.word,self.counter)
49 | req.get(url)
50 |
51 | def check_next(self):
52 | renext = re.compile('topNextUrl')
53 | nextres = renext.findall(self.results)
54 | if nextres != []:
55 | return True
56 | else:
57 | return False
58 |
59 | def get_emails(self):
60 | rawres = myparser.parser(self.totalresults, self.word)
61 | return rawres.emails()
62 |
63 | def get_hostnames(self):
64 | rawres = myparser.parser(self.totalresults, self.word)
65 | return rawres.hostnames()
66 |
67 | def get_files(self):
68 | rawres = myparser.parser(self.totalresults, self.word)
69 | return rawres.fileurls(self.files)
70 |
71 | def process(self):
72 | while self.counter <= self.limit and self.counter<500:
73 | if self.do_search():
74 | if self.check_next():
75 | time.sleep(random.randint(1, 5))
76 | self.counter += 1
77 | continue
78 | else:
79 | break
80 | else:
81 | break
82 |
83 | def process_files(self, files):
84 | while self.counter < self.limit and self.counter<500:
85 | self.do_search_files(files)
86 | time.sleep(0.3)
87 | self.counter += 50
88 | def run(self): # define this function,use for threading, define here or define in child-class both should be OK
89 | self.process()
90 | self.d = self.get_hostnames()
91 | self.e = self.get_emails()
92 | logger.info("{0} found {1} domain(s) and {2} email(s)".format(self.engine_name,len(self.d),len(self.e)))
93 | return self.d, self.e
94 |
95 | if __name__ == "__main__":
96 | print "[-] Searching in Bing:"
97 | useragent = "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52"
98 | proxy = {"http": "http://127.0.0.1:9988"}
99 | search = search_yandex("meizu.com", 500, proxy)
100 | search.process()
101 | all_emails = search.get_emails()
102 | all_hosts = search.get_hostnames()
103 | print all_emails
104 | print all_hosts
--------------------------------------------------------------------------------
/teemo/teemo.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | __author__ = 'bit4'
4 | __github__ = 'https://github.com/bit4woo'
5 |
6 | import argparse
7 | import datetime
8 | import os
9 | import threading
10 | import Queue
11 |
12 | from brute.subDomainsBrute import SubNameBrute
13 |
14 | from domainsites.Alexa import Alexa
15 | from domainsites.Chaxunla import Chaxunla
16 | from domainsites.CrtSearch import CrtSearch
17 | from domainsites.DNSdumpster import DNSdumpster
18 | from domainsites.Googlect import Googlect
19 | from domainsites.Ilink import Ilink
20 | from domainsites.Netcraft import Netcraft
21 | from domainsites.PassiveDNS import PassiveDNS
22 | from domainsites.Pgpsearch import Pgpsearch
23 | from domainsites.Sitedossier import Sitedossier
24 | from domainsites.ThreatCrowd import ThreatCrowd
25 | from domainsites.Threatminer import Threatminer
26 | from domainsites.Virustotal import Virustotal
27 | from lib.common import *
28 | from lib.domain2ip import domains2ips,iprange
29 | from lib.colorlog import *
30 | from lib.zonetransfer import zonetransfer
31 | from searchengine.search_ask import search_ask
32 | from searchengine.search_baidu import search_baidu
33 | from searchengine.search_bing import search_bing
34 | from searchengine.search_bing_api import search_bing_api
35 | from searchengine.search_dogpile import search_dogpile
36 | from searchengine.search_duckduckgo import search_duckduckgo
37 | from searchengine.search_exalead import search_exalead
38 | from searchengine.search_fofa import search_fofa
39 | from searchengine.search_google import search_google
40 | from searchengine.search_google_cse import search_google_cse
41 | from searchengine.search_shodan import search_shodan
42 | from searchengine.search_so import search_so
43 | from searchengine.search_yahoo import search_yahoo
44 | from searchengine.search_yandex import search_yandex
45 |
46 | reload(sys)
47 | sys.setdefaultencoding('utf-8')
48 | sys.dont_write_bytecode = True
49 |
50 |
51 | #In case you cannot install some of the required development packages, there's also an option to disable the SSL warning:
52 | try:
53 | import requests.packages.urllib3
54 | requests.packages.urllib3.disable_warnings()
55 | except:
56 | pass
57 |
58 |
59 | def parser_error(errmsg):
60 | banner()
61 | print ("Usage: python "+sys.argv[0]+" [Options] use -h for help")
62 | logger.error("Error: "+errmsg)
63 | sys.exit()
64 |
65 | def parse_args(): #optparse模块从2.7开始废弃,建议使用argparse
66 | parser = argparse.ArgumentParser(epilog = '\tExample: \r\npython '+sys.argv[0]+" -d google.com")
67 | parser.error = parser_error
68 | parser._optionals.title = "OPTIONS"
69 | parser.add_argument('-d', '--domain', help="Domain name to enumrate it's subdomains", required=True)
70 | parser.add_argument('-b', '--bruteforce', help='Enable the subbrute bruteforce module',nargs='?', default=False)
71 | parser.add_argument('-o', '--output', help='Save the results to text file')
72 | parser.add_argument('-x', '--proxy', help='The http proxy to visit google,eg: http://127.0.0.1:8080 ')
73 | return parser.parse_args()
74 |
75 | def adjust_args():
76 | args = parse_args()
77 | # Validate domain
78 | if not is_domain(args.domain):
79 | logger.error("Please enter a valid domain!!!")
80 | sys.exit()
81 |
82 | if not args.output:
83 | now = datetime.datetime.now()
84 | timestr = now.strftime("-%Y-%m-%d-%H-%M")
85 | args.output = args.domain + timestr + ".txt"
86 | args.output = os.path.join(os.path.dirname(__file__), "output", args.output)
87 |
88 | if args.proxy != None:
89 | proxy = {args.proxy.split(":")[0]: args.proxy}
90 | elif default_proxies != None and (proxy_switch == 2 or proxy_switch == 1): # config.py
91 | proxy = default_proxies
92 | else:
93 | proxy = {}
94 |
95 | args.proxy = proxy_verify(proxy)
96 | if len(args.proxy) !=0:
97 | logger.info("Vailid Proxy: {0}".format(args.proxy))
98 | else:
99 | logger.info("Caution! No valid proxy detected. No proxy will be used in this run.")
100 | return args
101 |
102 | def callengines_thread(engine, key_word, q_domains, q_emails, proxy=None,limit=1000):
103 | x = engine(key_word, limit, proxy)
104 | domains,emails = x.run()
105 | if domains: # domains maybe None
106 | for domain in domains:
107 | q_domains.put(domain)
108 | if emails:
109 | for email in emails:
110 | q_emails.put(email)
111 |
112 | def callsites_thread(engine, key_word, q_domains, q_emails, proxy=None):
113 | enum = engine(key_word,proxy)
114 | domains,similar_domains,emails = enum.run()
115 | if domains:
116 | for domain in domains:
117 | q_domains.put(domain)
118 | if similar_domains:
119 | for item in similar_domains:
120 | q_domains.put(item) #put both domain and similar in domain set
121 | if emails:
122 | for item in emails:
123 | q_emails.put(item)
124 | #return list(set(final_domains))
125 |
126 | def main():
127 | try:
128 | banner()
129 | args = adjust_args()
130 | subdomains = []
131 | print "[-] Enumerating subdomains now for %s" % args.domain
132 |
133 | #doing zone transfer checking
134 | zonetransfer(args.domain).check()
135 |
136 | Threadlist = []
137 | q_domains = Queue.Queue() #to recevie return values,use it to ensure thread safe.
138 | q_emails = Queue.Queue()
139 |
140 |
141 | for engine in [Alexa, Chaxunla, CrtSearch, DNSdumpster, Googlect, Ilink, Netcraft, PassiveDNS, Pgpsearch, Sitedossier, ThreatCrowd, Threatminer,Virustotal]:
142 | #print callsites_thread(engine,domain,proxy)
143 | if proxy_switch == 1 and engine in proxy_default_enabled:
144 | pass
145 | else:
146 | proxy ={}
147 | t = threading.Thread(target=callsites_thread, args=(engine, args.domain, q_domains, q_emails, args.proxy))
148 | Threadlist.append(t)
149 |
150 | for engine in [search_ask,search_baidu,search_bing,search_bing_api,search_dogpile,search_duckduckgo,search_exalead,search_fofa,search_google,search_google_cse,
151 | search_shodan,search_so,search_yahoo,search_yandex]:
152 | if proxy_switch == 1 and engine in proxy_default_enabled:
153 | pass
154 | else:
155 | proxy ={}
156 | t = threading.Thread(target=callengines_thread, args=(engine, args.domain, q_domains, q_emails, proxy, 500))
157 | t.setDaemon(True) #变成守护进程,独立于主进程。这里好像不需要
158 | Threadlist.append(t)
159 |
160 | #for t in Threadlist:
161 | # print t
162 | for t in Threadlist: # use start() not run()
163 | t.start()
164 | for t in Threadlist: #为什么需要2次循环,不能在一次循环中完成?
165 | t.join() #主线程将等待这个线程,直到这个线程运行结束
166 |
167 | while not q_domains.empty():
168 | subdomains.append(q_domains.get())
169 | emails = []
170 | while not q_emails.empty():
171 | emails.append(q_emails.get())
172 |
173 |
174 | if args.bruteforce:
175 | print G+"[-] Starting bruteforce using subDomainsBrute.."+W
176 | d = SubNameBrute(target=args.domain)
177 | d.run()
178 | brute_lines = d.result_lines
179 | brute_domains = d.result_domains
180 | brute_ips = d.result_ips
181 | else:
182 | brute_ips = []
183 | brute_lines = []
184 | brute_domains = []
185 |
186 |
187 | if subdomains is not None: #prepaire output
188 | IP_list, lines = domains2ips(subdomains) #query domains that got from website and search engine
189 |
190 | IP_list.extend(brute_ips)
191 | IPrange_list = iprange(IP_list)
192 |
193 | subdomains.extend(brute_domains)
194 | subdomains = sorted(list(set(subdomains)))
195 | subdomain_number = len(subdomains)
196 |
197 | lines.extend(brute_lines)
198 | lines = list(set(lines))
199 |
200 | emails = sorted(list(set(emails)))
201 |
202 | subdomains.extend(emails) #this function return value is NoneType ,can't use in function directly
203 | subdomains.extend(IPrange_list)
204 | #print type(subdomains)
205 | for subdomain in subdomains:
206 | print G+subdomain+W
207 |
208 | subdomains.extend(lines)
209 | fp = open(args.output,"wb")
210 | #fp.writelines("\n".join(subdomains).decode("utf-8"))
211 | fp.writelines("\n".join(subdomains).encode("utf-8"))
212 |
213 |
214 | print "[+] {0} domains found in total".format(subdomain_number)
215 | print "[+] {0} emails found in total".format(len(emails))
216 | print "[+] Results saved to {0}".format(args.output)
217 | except KeyboardInterrupt as e:
218 | logger.info("Exit. Due To KeyboardInterrupt")
219 |
220 |
221 | if __name__=="__main__":
222 | main()
223 |
--------------------------------------------------------------------------------
/teemo/thirdparty/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ATpiu/farmscan_domain/5b71eb316d7c146786eb140260cfc7e52c46b2dd/teemo/thirdparty/__init__.py
--------------------------------------------------------------------------------
/teemo/thirdparty/ansistrm/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ATpiu/farmscan_domain/5b71eb316d7c146786eb140260cfc7e52c46b2dd/teemo/thirdparty/ansistrm/__init__.py
--------------------------------------------------------------------------------
/teemo/thirdparty/ansistrm/ansistrm.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (C) 2010-2012 Vinay Sajip. All rights reserved. Licensed under the new BSD license.
3 | #
4 | import logging
5 | import re
6 | import subprocess
7 |
8 |
9 | from lib.core.convert import stdoutencode
10 |
11 | if subprocess.mswindows:
12 | import ctypes
13 | import ctypes.wintypes
14 |
15 | # Reference: https://gist.github.com/vsajip/758430
16 | # https://github.com/ipython/ipython/issues/4252
17 | # https://msdn.microsoft.com/en-us/library/windows/desktop/ms686047%28v=vs.85%29.aspx
18 | ctypes.windll.kernel32.SetConsoleTextAttribute.argtypes = [ctypes.wintypes.HANDLE, ctypes.wintypes.WORD]
19 | ctypes.windll.kernel32.SetConsoleTextAttribute.restype = ctypes.wintypes.BOOL
20 |
21 |
22 | class ColorizingStreamHandler(logging.StreamHandler):
23 | # color names to indices
24 | color_map = {
25 | 'black': 0,
26 | 'red': 1,
27 | 'green': 2,
28 | 'yellow': 3,
29 | 'blue': 4,
30 | 'magenta': 5,
31 | 'cyan': 6,
32 | 'white': 7,
33 | }
34 |
35 | # levels to (background, foreground, bold/intense)
36 | level_map = {
37 | logging.DEBUG: (None, 'blue', False),
38 | logging.INFO: (None, 'green', False),
39 | logging.WARNING: (None, 'yellow', False),
40 | logging.ERROR: (None, 'red', False),
41 | logging.CRITICAL: ('red', 'white', False)
42 | }
43 | csi = '\x1b['
44 | reset = '\x1b[0m'
45 | disable_coloring = False
46 |
47 | @property
48 | def is_tty(self):
49 | isatty = getattr(self.stream, 'isatty', None)
50 | return isatty and isatty() and not self.disable_coloring
51 |
52 | def emit(self, record):
53 | try:
54 | message = stdoutencode(self.format(record))
55 | stream = self.stream
56 |
57 | if not self.is_tty:
58 | if message and message[0] == "\r":
59 | message = message[1:]
60 | stream.write(message)
61 | else:
62 | self.output_colorized(message)
63 | stream.write(getattr(self, 'terminator', '\n'))
64 |
65 | self.flush()
66 | except (KeyboardInterrupt, SystemExit):
67 | raise
68 | except IOError:
69 | raise
70 | pass
71 | except:
72 | self.handleError(record)
73 |
74 | if not subprocess.mswindows:
75 | def output_colorized(self, message):
76 | self.stream.write(message)
77 | else:
78 | ansi_esc = re.compile(r'\x1b\[((?:\d+)(?:;(?:\d+))*)m')
79 |
80 | nt_color_map = {
81 | 0: 0x00, # black
82 | 1: 0x04, # red
83 | 2: 0x02, # green
84 | 3: 0x06, # yellow
85 | 4: 0x01, # blue
86 | 5: 0x05, # magenta
87 | 6: 0x03, # cyan
88 | 7: 0x07, # white
89 | }
90 |
91 | def output_colorized(self, message):
92 | parts = self.ansi_esc.split(message)
93 | write = self.stream.write
94 | h = None
95 | fd = getattr(self.stream, 'fileno', None)
96 |
97 | if fd is not None:
98 | fd = fd()
99 |
100 | if fd in (1, 2): # stdout or stderr
101 | h = ctypes.windll.kernel32.GetStdHandle(-10 - fd)
102 |
103 | while parts:
104 | text = parts.pop(0)
105 |
106 | if text:
107 | write(text)
108 |
109 | if parts:
110 | params = parts.pop(0)
111 |
112 | if h is not None:
113 | params = [int(p) for p in params.split(';')]
114 | color = 0
115 |
116 | for p in params:
117 | if 40 <= p <= 47:
118 | color |= self.nt_color_map[p - 40] << 4
119 | elif 30 <= p <= 37:
120 | color |= self.nt_color_map[p - 30]
121 | elif p == 1:
122 | color |= 0x08 # foreground intensity on
123 | elif p == 0: # reset to default color
124 | color = 0x07
125 | else:
126 | pass # error condition ignored
127 |
128 | ctypes.windll.kernel32.SetConsoleTextAttribute(h, color)
129 |
130 | def colorize(self, message, record):
131 | if record.levelno in self.level_map and self.is_tty:
132 | bg, fg, bold = self.level_map[record.levelno]
133 | params = []
134 |
135 | if bg in self.color_map:
136 | params.append(str(self.color_map[bg] + 40))
137 |
138 | if fg in self.color_map:
139 | params.append(str(self.color_map[fg] + 30))
140 |
141 | if bold:
142 | params.append('1')
143 |
144 | if params and message:
145 | if message.lstrip() != message:
146 | prefix = re.search(r"\s+", message).group(0)
147 | message = message[len(prefix):]
148 | else:
149 | prefix = ""
150 |
151 | message = "%s%s" % (prefix, ''.join((self.csi, ';'.join(params),
152 | 'm', message, self.reset)))
153 |
154 | return message
155 |
156 | def format(self, record):
157 | message = logging.StreamHandler.format(self, record)
158 | return self.colorize(message, record)
159 |
--------------------------------------------------------------------------------
|