* 사업 등 관련 문의: T) 02-322-4688, F) 02-322-4646, E) info@wikisecurity.net

간단한 E-mail Address 수집기(python)

* 이메일 주소를 왜 수집하지?
- 악성코드, 바이러스 등을 이메일로 유포하기 위해서 공격자는 이메일 주소를 얻을 필요가 있어
- 제일 간단하게 이메일 주소를 얻을 수 있는 방법은 검색을 이용하는 것이지
- 이 스크립트는 검색엔진에서 검색한 결과에서 이메일 주소를 파싱해서 출력해줘
- kitploit에 게시된 infoga를 일부 수정하여 만들었어

* 이용하는 검색엔진
- google, bing, yahoo, pgp 검색엔진을 이용하여 이메일 주소를 수집해

* 설치방법
- 이 스크립트를 실행하는데 필요한 패키지와 모듈을 먼저 설치하고

 $ sudo apt-get install libffi-dev
 $ sudo apt-get install libssl-dev
 $ pip install -r requires.txt


* 실행방법
- 이 스크립트를 다운받은 폴더로 이동해서 실행해야해

 ex) python infoga.py -t naver.com -s google -o s
 ex) python infoga.py -i aaa@naver.com


- 예제의 입력인자에 대해 설명을 하자면

-t : 수집할 이메일의 도메인
-s : 검색 엔진 (google, bing, yahoo,pgp, all)
-o : 출력 옵션 (s : 이메일 주소만 출력 / a : 이메일 주소와 메일서버의 정보 출력)
-i : 입력한 이메일주소의 메일서버 정보를 출력


* infoga.py 소스코드

 # infoga.py
 #
 
 from lib import Net 
 from lib import Parser
 from lib import Colors 
 from lib import Info 
 from lib import Printer 
 from lxml.html import fromstring
 from recon import *
 from requests.packages.urllib3.exceptions import InsecureRequestWarning
 import urllib3.contrib.pyopenssl
 import certifi
 import json
 import os 
 import sys
 import getopt 
 import socket
 import re
 import urllib3
 import urlparse
 import requests 
 
 class Infoga(object):
         ### Infoga Main ###
   def __init__(self,argv):
           self.argv = argv
	   self.c = Colors.MyColors()
	   self.i =  Info.MyInfo()
	   self.AllEmails = []
	   self.Option =""
 
   def Usage(self):
	   path = ((os.path.basename(sys.argv[0])))
	   print "Usage: %s -t [target] -s [source] -o [detail option]\n"%(path)
	   print "\t-t --target\tDomain to search"
	   print "\t-s --source\tData source: [all,google,bing,yahoo,pgp]"
	   print "\t-o --option\tDetail option : [s: only email address ,a: add mailsever infomation]"
	   print "\t-i --info\tGet email informations"
	   print "\t--version\tShow version"
	   print "\t--help\t\tShow this help and exit\n"
	   print "Examples:"
	   print "\t %s --target site.com --source all --option [a,s]"%(path)
	   print "\t %s --target site.com --source [google,bing,...] --option [a,s]"%(path)
	   print "\t %s --info emailtest@site.com"%(path)
	   print "";sys.exit()
 
   def GetInfo(self):
	
	   if self.Option == 's':
		   for x in range(len(self.AllEmails)):
			   Printer.MyPrinter().mprint("Email: %s"%(self.AllEmails[x]))
	
	   elif self.Option == "a":
		   for x in range(len(self.AllEmails)):
		
			   Printer.MyPrinter().mprint("Email: %s"%(self.AllEmails[x]))
			   data = {'lang':'en'}
			   data['email'] = self.AllEmails[x]
			   req = requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
			   req = requests.post("http://mailtester.com/testmail.php",data=data)
			   regex = re.compile("[0-9]+(?:\.[0-9]+){3}")
			   ip = regex.findall(req.content)
			   new = []
			   for e in ip:
				   if e not in new:
					   new.append(e)
			   for s in range(len(new)):
				   urllib3.contrib.pyopenssl.inject_into_urllib3()
				   net = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',ca_certs=certifi.where())
				   res = net.request("GET","https://api.shodan.io/shodan/host/"+new[s]+"?key=UNmOjxeFS2mPA3kmzm1sZwC0XjaTTksy")
				   jso = json.loads(res.data)
				   try:
					   self.sock = socket.gethostbyaddr(new[s])[0]
				   except socket.herror,err:
					   try:
						   self.sock = jso["hostnames"][0]
					   except KeyError,err:
						   pass
				   if "country_code" and "country_name" in jso:
					   print "\t\t|_ %s (%s)"%(new[s],self.sock)
					   print "\t\t\t|"
					   print "\t\t\t|__ Country: %s(%s) - City: %s (%s)"%(jso["country_code"],jso["country_name"],jso["city"],jso["region_code"])
					   print "\t\t\t|__ ASN: %s - ISP: %s"%(jso["asn"],jso["isp"])
					   print "\t\t\t|__ Latitude: %s - Longitude: %s"%(jso["latitude"],jso["longitude"])
					   print "\t\t\t|__ Hostname: %s - Organization: %s"%(jso["hostnames"][0],jso["org"])
					   try:
						   print "\t\t\t|__ Vulns: %s - Ports: %s"%(jso["vulns"][0],jso["ports"][0])
					   except KeyError,err:
						   pass
					   print ""
				   elif "No information available for that IP." or "error" in jso:
					   print "\t\t|_ %s %s"%(new[s],self.sock)
					   print "\t\t\t|__ No information available for that IP!!"
					   print ""
				   else:
					   print "\t\t|__ %s (%s)"%(new[s],self.sock)
 
   def Google(self):
	   Printer.MyPrinter().nprint("Searching \"%s\" in Google..."%(self.CheckUrl(self.Keyword)))
	   Search = GoogleSearch.Googlesearch(self.CheckUrl(self.Keyword))
	   Search.Process()
	   Emails = Search.GetEmail()
	   self.AllEmails.extend(Emails)
   def Bing(self):
	   Printer.MyPrinter().nprint("Searching \"%s\" in Bing..."%(self.CheckUrl(self.Keyword)))
	   Search = BingSearch.Bingsearch(self.CheckUrl(self.Keyword))
	   Search.Process()
	   Emails = Search.GetEmail()
	   self.AllEmails.extend(Emails)
   def Yahoo(self):
	   Printer.MyPrinter().nprint("Searching \"%s\" in Yahoo..."%(self.CheckUrl(self.Keyword)))
	   Search = YahooSearch.Yahoosearch(self.CheckUrl(self.Keyword))
	   Search.Process()
	   Emails = Search.GetEmail()
	   self.AllEmails.extend(Emails)
   def Pgp(self):
	   Printer.MyPrinter().nprint("Searching \"%s\" in Pgp..."%(self.CheckUrl(self.Keyword)))
	   Search = PgpSearch.Pgpsearch(self.CheckUrl(self.Keyword))
	   Search.Process()
	   Emails = Search.GetEmail()
	   self.AllEmails.extend(Emails)
   def All(self):
	   self.Google()
	   self.Bing()
	   self.Yahoo()
	   self.Pgp()
 
   def CheckUrl(self,url):
	   o = urlparse.urlsplit(url)
	   scheme = o.scheme 
	   netloc = o.netloc
	   path = o.path
	   if scheme not in ["http","https",""]:
		   sys.exit(Printer.MyPrinter().eprint("Scheme %s not supported!"%(scheme)))
	   if netloc == "":
		   if path.startswith("www."):
			   return path.split("www.")[1]
		   else:
			   return path
	   else:
		   if netloc.startswith("www."):
			   return netloc.split("www.")[1]
		   else:
			   return netloc
 
   def Getinfo(self,email):
	   Printer.MyPrinter().mprint("Email: %s"%(email))
	   data = {'lang':'en'}
	   data['email'] = email
	   req = requests.post("http://mailtester.com/testmail.php",data=data)
	   regex = re.compile("[0-9]+(?:\.[0-9]+){3}")
	   ip = regex.findall(req.content)
	   new = []
	   for e in ip:
		   if e not in new:
			   new.append(e)
	   for s in range(len(new)):
		   net = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',ca_certs=certifi.where())
		   res = net.request("GET","https://api.shodan.io/shodan/host/"+new[s]+"?key=UNmOjxeFS2mPA3kmzm1sZwC0XjaTTksy")
		   jso = json.loads(res.data)
		   try:
			   self.sock = socket.gethostbyaddr(new[s])[0]
		   except socket.herror,err:
			   try:
				   self.sock = (jso["hostnames"][0])
			   except KeyError,err:
				   pass
		   if "country_code" and "country_name" in jso:
			   print "\t\t|_ %s (%s)"%(new[s],self.sock)
			   print "\t\t\t|"
			   print "\t\t\t|__ Country: %s(%s) - City: %s (%s)"%(jso["country_code"],jso["country_name"],jso["city"],jso["region_code"])
			   print "\t\t\t|__ ASN: %s - ISP: %s"%(jso["asn"],jso["isp"])
			   print "\t\t\t|__ Latitude: %s - Longitude: %s"%(jso["latitude"],jso["longitude"])
			   print "\t\t\t|__ Hostname: %s - Organization: %s"%(jso["hostnames"][0],jso["org"])
			   try:
				   print "\t\t\t|__ Vulns: %s - Ports: %s"%(jso["vulns"][0],jso["ports"][0])
			   except KeyError,err:
				   pass
			   print ""
		   elif "No information available for that IP." or "error" in jso:
			   print "\t\t|_ %s (%s)"%(new[s],self.sock)
			   print "\t\t\t|__ No information available for that IP!!"
			   print ""
		   else:
			   print "\t\t|__ %s (%s)"%(new[s],self.sock)
	   sys.exit()
 
   def CheckEmail(self,email):
	   if "@" not in email:
		   sys.exit(Printer.MyPrinter().eprint("Invalid email!! Check your email"))
	   self.Getinfo(email)
 
   def CheckVersion(self):
	   sys.exit(self.i.Vers())
 
   def Start(self):
	   if len(sys.argv) < 2:
		   self.Usage()
	   try:
		   opts,args = getopt.getopt(self.argv,"t:s:o:i:",["target=","source=","info=","option","update","version","help"])
	   except getopt.GetoptError:
		   self.Usage()
	   for opt,arg in opts:
		   if opt in ("-t","--target"):
			   self.Keyword = arg
			   self.CheckUrl(self.Keyword)
		   elif opt in ("-s","--source"):
			   self.engine = arg 
			   if self.engine not in ("all","google","bing","yahoo","pgp"):
				   sys.exit(Printer.MyPrinter().eprint("Invalid search engine!! Try with: all,google, bing, yahoo or pgp"))
		   elif opt in ("-o","--option"):
			   self.Option = arg
		   elif opt in ("-i","--info"):
			   print arg
			   self.email = arg 
			   self.CheckEmail(self.email)
		   elif opt == "--help":
			   self.Usage()
		   elif opt == "--version":
			   self.CheckVersion()
 
	   Netcraft.netcraft(self.CheckUrl(self.Keyword)).Run()
	   if self.engine == "google":
		   self.Google()
	   if self.engine == "bing":
		   self.Bing()
	   if self.engine == "yahoo":
		   self.Yahoo()
	   if self.engine == "pgp":
		   self.Pgp()
	   if self.engine == "all":
		   self.All()
	   if self.AllEmails == []:
		   sys.exit(Printer.MyPrinter().eprint("Not found email!"))
	   else:
		   self.AllEmails = sorted(set(self.AllEmails))
		   Printer.MyPrinter().nprint("All email found: ")
		   self.GetInfo()
 
 if __name__ == "__main__":
   try:
	   Infoga(sys.argv[1:]).Start()
   except KeyboardInterrupt,err:
	   sys.exit(Printer.MyPrinter().eprint("Ctr+c...:("))

* infoga.py 실행화면
- 실행하면 얼마만큼 검색을 실시할것인지 입력을 받아


- 검색할 페이지 수를 입력을 하면 검색이 시작되고 검색이 완료되면 이메일 주소를 출력해준다

* infoga 소스파일
infoga.zip