信息收集通常可以分为被动信息收集 和 ** 主动信息收集,** 被动信息收集是指不与目标主机进行直接交互,通常根据搜索引擎或者社交等方式间接获取目标主机的信息;主动信息收集是指与目标主机进行直接交互,从而获取所需要的目标信息
攻击者比较关注目标主机的所有信息,比如:子域名、IP 地址、旁站、C 段查询、用户邮箱 CMS 类型、敏感目录、端口信息、服务器版本以及中间件等
被动信息收集主要是通过一些收集引擎例如 fofa、鹰图等等进行收集、或者通过一些社交方式来获得一些信息。该方法是不与目标机子产生交互的,可以不接触目标的情况下挖掘目标信息。主要方法包括:DNS 解析、子域名挖掘、邮件爬取等等
DNS 解析
DNS 是一种分布式网络目录服务,主要用于域名与 ip 地址的相互转换,能够使用户更方便地访问互联网,TCP/IP 中的 IP 地址是由四段以 "." 分开地数字组成,记起来总是不如名字那么方便,所以采用了域名系统来管理名字和 IP 地对应关系
IP 查询
IP 查询是通过当前所获取到的 URL 去查询对应 IP 地址的过程。可以应用 Socket 库函数中的 gethostbyname () 获取域名所对应的 IP 值
例:查询域名 www.baidu.com 所对应的 IP 值
1 2 3 import socket ip = socket.gethostbyname('www.baidu.com') print(ip)
输出结果:
Whois 查询
Whois 是用来查询域名的 IP 以及所有者信息的传输协议。简单地说,Whois 就是一个数据库,用来查询域名是否已经被注册,以及注册域名的详细信息(如域 - 名所有人、域名注册商等)。Python 中的 python-whois 模块可以用于 Whois 的查询
先通过 pip 安装 python-whois 模块:
1 pip install python-whois·
通过自带的 whois 模块查询域名 www.baidu.com 的注册信息
1 2 3 from whois import whois data = whois('www.baidu.com') print(data)
输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 { "domain_name": [ "BAIDU.COM", "baidu.com" ], "registrar": "MarkMonitor, Inc.", "whois_server": "whois.markmonitor.com", "referral_url": null, "updated_date": [ "2022-09-01 03:54:43", "2022-09-01 03:29:31" ], "creation_date": "1999-10-11 11:05:17", "expiration_date": [ "2026-10-11 11:05:17", "2026-10-11 07:00:00" ], "name_servers": [ "NS1.BAIDU.COM", "NS2.BAIDU.COM", "NS3.BAIDU.COM", "NS4.BAIDU.COM", "NS7.BAIDU.COM", "ns7.baidu.com", "ns4.baidu.com", "ns1.baidu.com", "ns2.baidu.com", "ns3.baidu.com" ], "status": [ "clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited", "clientTransferProhibited https://icann.org/epp#clientTransferProhibited", "clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited", "serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited", "serverTransferProhibited https://icann.org/epp#serverTransferProhibited", "serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited", "clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)", "clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)", "clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)", "serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)", "serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)", "serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)" ], "emails": [ "abusecomplaints@markmonitor.com", "whoisrequest@markmonitor.com" ], "dnssec": "unsigned", "name": null, "org": "Beijing Baidu Netcom Science Technology Co., Ltd.", "address": null, "city": null, "state": "Beijing", "registrant_postal_code": null, "country": "CN" }
子域名挖掘
域名可以分为顶级域名、一级域名、二级域名。子域名是顶级域名(一级域名或父域名)的下一级,例如 mail.example.com 和 calendar.example.com 是 example.com 的两个子域而 example.com 则是顶级域.com 的子域。在测试过程中,测试目标主站时如果未发现任何相关漏洞,此时通常会考虑挖掘目标系统的子域名。子域名的挖掘方式有很多种,例如:搜索引擎、子域名破解、字典查询等等
这里用 python 写一个子域名的挖掘工具(通过 Bing 搜索引擎进行子域名搜集):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #! /usr/bin/env python # _*_ coding:utf-8_*_ import requests from bs4 import BeautifulSoup from urllib.parse import urlparse import sys def bing_search(site,pages): Sudbomain = [] headers = { 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64; rv:68.0)Gecko/20100101 Firefox/68.0' 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Referer':"https://cn.bing.com", 'Cookie':"MUID=3B16E5B***********782&t=6" #填写相应的Cookie值 } for i in range(1,int(pages)+1): url = "https://cn.bing.com/search?q=site%3a"+site+"&go=Search&ds&first="+ str((int(i)-1)*10) +"&FROM=PERE" html = requests.get(url,headers=headers) soup = BeautifulSoup(html.content,'html.parser') job_bt = soup.findAll('h2') for i in job_bt: link = i.a.get('href') domain = str(urlparse(link).scheme + "://" + urlparse(link).netloc) if domain in Subdomain: pass else: Subdomain.append(domain) print(domain) if __name__ == '_main_': if len(sys.argv) == 3: site = sys.argv[1] page = sys.argv[2] else: print("usage: %s baidu.com 10"% sys.argv[0]) #输出帮助信息 sys.exit(-1) Subdomain = bing_search(site,page)
邮件爬取
在针对目标系统进行渗透的过程中,如果目标服务器安全性很高,通过服务器很难获取目标权限时,通常会采用社工的方式对目标服务进行进一步的攻击。邮件钓鱼攻击是常见的攻击方式之一。在进行钓鱼之前,需要针对目标相关人员的邮件信息进行全面采集。 此处邮件采集工具主要通过国内常见的搜索引擎(百度、Bing 等进行搜集)。针对搜索界面的相关邮件信息进行爬取、处理等操作之后。利用获得的邮箱账号批量发送钓鱼邮件,等待目标用户或者管理员点击之后执行,进而获得目标的权限 邮件采集工具所用到的库如下所示
1 2 3 4 5 import sys import getopt import request from bs4 import BeautifulSoup import re
在程序的起始部分,在执行过程中没有发生异常时,则执行定义的 start () 函数。通过 sys.argv [] 实现外部指令的接受。其中,sys.argv [0] 表示代码本身的文件路径,sys.argv [1:] 表示从第一个命令行参数到输入的最后一个命令行参数,存储形式为 list 类型:
1 2 3 4 5 6 if __name__ == '__main__' #定义异常 try: start(sys.argv[1:]) except KeyboardInterrupt: print("interrupted by user, killing all threads...")
编写命令行参数处理功能。此处主要应用 getopt.getopt () 函数处理命令行参数,该函数目前有短选项和长选项两种格式。短选项格式为 "-" 加上单个字母选项;长选项格式为 "--" 加上一个单词选项。opts 为一个两元组列表,每个元素形式为 "(选项串,附加参数)"。当没有附加参数时,则为空串。之后通过 for 语句循环输出 opts 列表中的数值并赋值给自定义变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 def start(argv): url = " " pages = " " if len(sys.argv) < 2: print("-h 帮助信息 ;\n") sys.exit() #定义异常处理 try: bannner() opts,args = getopt.getopt(argv,"-u;-p;-h") except getopt.GetoptError: print('Error an argument!') sys.exit() for opt,arg in opts: if opt == "-u": url = args elif opt == "-p": pages = arg elif opt == "-h": print(usage()) launcher(url,pages)
输出帮助信息,增加代码工具的可读性和易用性。为了使输出信息更加美观简洁,可以通过转译字符设置输出字体颜色,从而实现需要的效果,开头部分包含三个参数:显示方式、前景色、背景色。这三个参数是可选的,可以只写其中的某一参数。结尾部分可以省略,但是为了书写规范,建议以 "\033 [0m" 结尾
1 2 开头:\033[显示方式;前景色;背景色m] 结尾部分:\033[0m
示例代码:
1 2 print('\033[0;30;41m 你好 \033[0m') print('\033[0;30;47m 你好 \033[0m')
输出显示:
先以图案形式输出脚本出自 MS08067 实验室,然后输出有关脚本使用的帮助信息,即可执行参数执行以及对应的功能简介
1 2 3 4 5 6 7 8 9 10 #banner信息 def banner(): print('\033[1;34m###############################################################################################\033[0m\n''\033[1;34m#############################################\033[1;32mMS08067实验室\033[1;34m#############################################\033[0m\n''\033[1;34m##########################################################################################################\033[0m\n') #使用规则 def usage(): print('-h: --help 帮助;') print('-u: --url 域名;') print('-p: --pages 页数;') print('eg:python -u "www.baidu.com" -p 100'+'\n') sys.exit()
同时也可以根据自己的喜好设置输出不同类型的字体颜色或者图案 确定搜索邮件的关键字,并调用 bing_search () 和 baidu_search () 两个函数,返回 Bing 与百度两大搜索引擎的查询结果,由获取到的结果进行列表合并,去重之后循环输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #漏洞回调函数 def launcher(url,pages): email_num = [] key_words = ['email','mail','mailbox','邮件','邮箱','postbox'] for page in range(1,int(pages)+1): for key_word in key_words: bing_emails = bing_search(url,page,key_word) baidu_emails = baidu_search(url,page,key_word) sum_emails = bing_emails + baidu_emails for email in sum_emails: if email in email_num: pass else: print(email) with open('data.txt','a+') as f: f.write(email + '\n') email_num.append(email)
用 Bing 搜索引擎进行邮件爬取。Bing 引擎具有反爬系统,会通过限定 referer、cookie 等信息来确定是否是网页爬取操作。可以通过指定 referer 与 request.session () 函数自动获取 cookie 信息,绕过 Bing 搜索引擎的防爬防护
1 2 3 4 5 6 7 8 def bing_search(url,page,key_word): referer = "http://cn.bing.com/search?q=email+site%3abaidu.com&qs=n&sp=-1&pq=emailsite%3baidu.com&first=1&FROM=PERE1" conn = requests.session() bing_url = "http://cn.bing.com/search?q=" + key_word + "+site%3a" + url + "&qs=n&sp=-1&pq=" + key_word + "site%3a" + url + "&first=" +str((page-1)*10) + "&FROM=FEERE1" conn.get('http://cn.bing.com',headers=headers(referer)) r = conn.get(bing_url,stream=True,headers=headers(referer),timeout=8) emails = search_email(r.text) return emails
用百度搜索引擎进行邮件爬取。同样的,百度搜索引擎也做了反爬防护,相对于 Bing 来说,百度不仅对 referer 和 cookie 进行校验,也同时在页面中通过 JavaScript 语句进行动态请求链接,从而导致不能动态获取页面中的信息。可以通过对链接的提取,再进行 request 请求,从而绕过百度搜索引擎的反爬设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def baidu_search(url,page,key_word): email_list = [] emails = [] referer = "https://www.baidu.com/s?wd=email+site%3Abaidu.com&pn=1" baidu_url = "https://www.baidu.com/s?wa="+key_word+"+site%3A"+url+"&pn="+str((page-1)*10) conn = requests.session conn.get(referer,headers=headers(referer)) r = conn.get(baidu_url,headers=headers(referer)) soup = BeautifulSoup(r.txt,'html') tagh3 = soup.find_all('h3') for h3 in tagh3: href = h3.find('a').get('href') try: r = requests.get(href,headers=headers(referer),timeout=8) emails = search_email(r.txt) except Exception as e: pass for email in emails: email_list.append(email) return email_list
接下来通过正则表达式获取邮箱号码,此处也可换成目标企业邮箱的正则表达式:
1 2 3 4 5 6 7 8 9 10 11 def search_email(html): emails = re.findall(r"[a-z0-9\.\-+_]+@[a-z0-9\.\-+_]+\.[a-z]+",html,re.I) return emails def headers(referer): headers = {'User-Agent':'Mozilla/5.0(X11;Linux x86_64;rv:60.0) Gecko/20100101 Firefoc/60.0', 'Accept':'*/*' 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip,deflate', 'Referer':referer } return headers
用 python3 执行脚本,-u 参数指定域名,-p 参数指定搜索引擎的页数,如:
1 python3 ce.py -u "baidu.com" -p 1