引言
被动信息收集是指不与目标主机进行直接交互,通常根据搜索引擎或者社交等方式间接获取目标主机的信息。
被动信息收集主要通过搜索引擎或者社交等方式对目标资产信息进行提取,通常包括IP查询、Whois查询、子域名收集等。进行被动信息收集时不与目标产生交互,可以在不接触到目标系统的情况下挖掘目标信息。主要方法包括DNS解析、子域名挖掘、邮件爬取等。
IP查询
IP查询是通过当前获取到的URL去查询对应IP地址的过程
Whois查询
Whois是用来查询域名的IP以及所有者信息的传输协议,简单来说就是一个数据库,用来查询域名是否已经被注册,以及注册域名的详细信息,如域名所有人、域名注册商等。
子域名挖掘
域名可以分为顶级域名、一级域名、二级域名。在测试过程中,测试目标主站时如果未发现任何相关漏洞,此时通常会考虑挖掘目标系统的子域名。子域名挖掘的方法有很多,如搜索引擎、子域名破解、字典查询等。
目前使用的工具中,我最喜欢的是Layer子域名挖掘机
邮件爬取
在针对目标系统进行渗透的过程中,如果目标服务器安全性很高,通过服务器很难获取目标权限时,通常会采用社工的方式对目标服务器进行进一步攻击。邮件钓鱼就是常见的攻击方式之一。针对搜索页面的相关邮件信息进行爬取、处理等操作后,利用获得的邮箱账号批量发送钓鱼邮件,诱骗、欺诈用户或者管理员进行账号登录或者点击执行,进而获取系统权限。
要用到的相关函数库
import sys
import getopt
import requests
from bs4 import BeautifulSoup
import re
主程序入口,sys.argv[0]表示代码本身的路径,sys.argv[1:]表示除路径外后面的所有参数,返回一个列表的形式
if __name__ == '__main__':
#定义异常
try:
start(sys.argv[1:])
except KeyboardInterrupt:
print("interrupted by user,killing all threads...")
编写主程序中的start函数,这里最重要的理解getopt.getopt()这个函数,这个函数的作用主要是切割命令行参数,返回一个两元组列表,分别通过'-'
和'--'
进行切割
#主函数,传入用户输入的参数
def start(argv):
url = ""
pages = ""
if len(sys.argv) < 2:
print("-h 帮助信息;\n")
sys.exit()
#定义异常处理
try:
banner()
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 = arg
elif opt == "-p":
pages = arg
elif opt == "-h":
print(usage())
launcher(url,pages)
opts为分析出的格式信息。args为不属于格式信息的剩余的命令行参数,即不是按照getopt()里面定义的长或短选项字符和附加参数以外的信息。for循环中的opt是元组中的第一个参数(即用户输入的参数),arg则是元组的第二个参数(即用户输入的参数值)。
输出帮助信息,增加代码工具的可读性和易用性
#banner信息
def banner():
print('\033[1;34m########################################################################################\033[0m\n'
'\033[1;34m######################################\033[1;32mpython安全实战\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()
接下来就是函数的主体了,也是核心部分,首先编写漏洞回调函数,增强代码的健壮性和可扩展性
#漏洞回调函数
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和Baidu都有反爬防护,可以通过限定referer、cookie等信息来绕过搜索引擎的防爬防护
#bingSearch
def bing_search(url,page,key_word):
referer = "http://cn.bing.com/search?q=email+site%3abaidu.com&qs=n&sp=-1&pq=emailsite%3abaidu.com&first=1&FORM=PERE1"
conn = requests.session()
bing_url = "https://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)+"&FORM=PERE1"
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
#baiduSearch
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?wd="+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.text, 'lxml')
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.text)
except Exception as e:
pass
for email in emails:
email_list.append(email)
return email_list
通过正则表达式获取邮箱号码,这里附上可选标志修饰符来控制匹配的模式。
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 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36',
'Accept': '*/*',
'Accept-Language':'en-US,en;q=0.5',
'Accept-Encoding':'gzip,deflate',
'Referer':referer}
return headers
修饰符 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
最后附上完整的代码
import sys
import getopt
import requests
from bs4 import BeautifulSoup
import re
#主函数,传入用户输入的参数
def start(argv):
url = ""
pages = ""
if len(sys.argv) < 2:
print("-h 帮助信息;\n")
sys.exit()
#定义异常处理
try:
banner()
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 = arg
elif opt == "-p":
pages = arg
elif opt == "-h":
print(usage())
launcher(url,pages)
#banner信息
def banner():
print('\033[1;34m########################################################################################\033[0m\n'
'\033[1;34m######################################\033[1;32mpython安全实战\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()
#漏洞回调函数
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)
#bingSearch
def bing_search(url,page,key_word):
referer = "http://cn.bing.com/search?q=email+site%3abaidu.com&qs=n&sp=-1&pq=emailsite%3abaidu.com&first=1&FORM=PERE1"
conn = requests.session()
bing_url = "https://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)+"&FORM=PERE1"
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
#baiduSearch
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?wd="+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.text, 'lxml')
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.text)
except Exception as e:
pass
for email in emails:
email_list.append(email)
return email_list
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 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36',
'Accept': '*/*',
'Accept-Language':'en-US,en;q=0.5',
'Accept-Encoding':'gzip,deflate',
'Referer':referer}
return headers
if __name__ == '__main__':
#定义异常
try:
start(sys.argv[1:])
except KeyboardInterrupt:
print("interrupted by user,killing all threads...")
代码效果图