├── ips.txt ├── domains.txt ├── screenshot.png ├── README.md └── hosts_boom.py /ips.txt: -------------------------------------------------------------------------------- 1 | 1.1.1.1 2 | -------------------------------------------------------------------------------- /domains.txt: -------------------------------------------------------------------------------- 1 | b.example.com 2 | c.example.com 3 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YoungRichOG/Hosts_Boom/HEAD/screenshot.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hosts_Boom 2 | 3 | > 通过hosts碰撞发现目标内部系统,扩大攻击面。 4 | 5 | ## :bulb:描述 6 | 为什么想做这个? 7 | 8 | 感觉别人的用起来不舒服 9 | 10 | ## 功能 11 | - [x] 通过标题发现 12 | - [x] 通过长度发现 13 | - [x] 通过状态码发现 14 | 15 | ## 如何使用 16 | 17 | 友情提示:请确保IP可访问,否则会有很多timeout影响效率 18 | 19 | 将整理好的IP和HOST分别放入ips.txt、domains.txt,最终输出程序根目录boom.txt 20 | 21 | ```text 22 | python3 hosts_boom.py 23 | ``` 24 | 25 | ## 运行截图 26 | 27 | ![screenshot](screenshot.png) 28 | 29 | ## 思考 30 | 31 | 做出来在告诉你 :-0 32 | 33 | ## TODO 34 | 35 | ~~进度条~~ 36 | 37 | 重定向 38 | 39 | 其他优化 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /hosts_boom.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | # -*-coding:utf-8 -*- 3 | 4 | 5 | ''' 6 | Author:YoungRichOG 7 | Hacking Everything :-) 8 | 2021/8/7 9 | ''' 10 | 11 | import requests,urllib3,re 12 | import concurrent.futures 13 | import itertools 14 | from bs4 import BeautifulSoup 15 | from requests.packages import chardet 16 | from tqdm import tqdm 17 | 18 | def _crateboomlist(): 19 | protocols = ['http://','https://'] 20 | _domainlist = open('domains.txt').read().splitlines() 21 | _iplist = open('ips.txt').read().splitlines() 22 | _xx = list(itertools.product(protocols,_iplist)) 23 | _iplist = [i[0]+i[1] for i in _xx] 24 | _boomlist = list(itertools.product(_iplist,_domainlist)) 25 | 26 | return _boomlist 27 | 28 | 29 | def _boom(url): 30 | try: 31 | 32 | headers = { 33 | 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36' 34 | } 35 | r1 = requests.get(url[0],headers=headers,verify=False,timeout=5) 36 | charset = chardet.detect(r1.content)["encoding"] 37 | r1.encoding = charset 38 | soup1 = BeautifulSoup(r1.text, 'lxml') 39 | 40 | headers = { 41 | 'Host': url[1], 42 | 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36' 43 | } 44 | 45 | r2 = requests.get(url[0],headers=headers,verify=False,timeout=5) 46 | charset = chardet.detect(r2.content)["encoding"] 47 | r2.encoding = charset 48 | soup2 = BeautifulSoup(r2.text, 'lxml') 49 | 50 | _data = url[0]+','+url[1] 51 | _data += ',原始标题:'+soup1.title.text+',原始长度:'+str(len(r1.content))+',变化长度:'+str(len(r2.content)) 52 | _data += ',变化标题:'+soup2.title.text+',原始状态码:'+str(r1.status_code)+',变化状态码:'+str(r2.status_code) 53 | 54 | 55 | if soup2.title.text in _title_trigger: 56 | _title_trigger[soup2.title.text] += 1 57 | if _title_trigger[soup2.title.text] < 5 and url not in boooooom and soup1.title.text!= soup2.title.text: 58 | boooooom.append(_data) 59 | else: 60 | _title_trigger[soup2.title.text] = 0 61 | 62 | 63 | if len(r2.content) in _length_trigger: 64 | _length_trigger[len(r2.content)] +=1 65 | if _length_trigger[len(r2.content)] < 5 and url not in boooooom and len(r1.content)!= len(r2.content): 66 | boooooom.append(_data) 67 | else: 68 | _length_trigger[len(r2.content)] = 0 69 | 70 | 71 | if r2.status_code in _statuscode_trigger: 72 | _statuscode_trigger[r2.status_code] +=1 73 | if _statuscode_trigger[r2.status_code] < 5 and url not in boooooom and r1.status_code!= r2.status_code: 74 | boooooom.append(_data) 75 | else: 76 | _statuscode_trigger[r2.status_code] = 0 77 | 78 | 79 | except Exception as e: 80 | pass 81 | 82 | if __name__ == '__main__': 83 | requests.packages.urllib3.disable_warnings() 84 | _title_trigger = {} 85 | _length_trigger = {} 86 | _statuscode_trigger = {} 87 | boooooom = [] 88 | 89 | urls = _crateboomlist() 90 | 91 | l = len(urls) 92 | with tqdm(total=l) as pbar: 93 | with concurrent.futures.ThreadPoolExecutor(max_workers=200) as executor: 94 | _todo = {executor.submit(_boom,url): url for url in urls} 95 | for future in concurrent.futures.as_completed(_todo): 96 | url = _todo[future] 97 | 98 | data = future.result() 99 | pbar.update(1) 100 | print('YoungRichOG https://youngrichog.github.io/') 101 | print('-'*60) 102 | print('[**] 长度结果:',_length_trigger) 103 | print('[**] 标题结果:',_title_trigger) 104 | print('[**] 状态码结果:',_statuscode_trigger) 105 | print('-'*60) 106 | for res in set(boooooom): 107 | print(res) 108 | with open('boom.txt','a+') as file: 109 | file.write(res.rstrip()+'\n') 110 | --------------------------------------------------------------------------------