eris- Elasticsearch Recon Ingestion Scripts (ERIS) 🔎 |
git clone git://git.acid.vegas/-c.git |
Log | Files | Refs | Archive | README | LICENSE |
ingest_masscan.py (4826B)
1 #!/usr/bin/env python 2 # Elasticsearch Recon Ingestion Scripts (ERIS) - Developed by Acidvegas (https://git.acid.vegas/eris) 3 # ingest_masscan.py 4 5 ''' 6 apt-get install iptables masscan libpcap-dev screen 7 setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' /bin/masscan 8 /sbin/iptables -A INPUT -p tcp --dport 61010 -j DROP 9 printf "0.0.0.0/8\n10.0.0.0/8\n100.64.0.0/10\n127.0.0.0/8\n169.254.0.0/16\n172.16.0.0/12\n192.0.0.0/24\n192.0.2.0/24\n192.31.196.0/24\n192.52.193.0/24\n192.88.99.0/24\n192.168.0.0/16\n192.175.48.0/24\n198.18.0.0/15\n198.51.100.0/24\n203.0.113.0/24\n224.0.0.0/3\n255.255.255.255/32" > exclude.conf 10 screen -S scan 11 masscan 0.0.0.0/0 -p21,22,23 --banners --http-user-agent "USER_AGENT" --source-port 61010 --open-only --rate 30000 --excludefile exclude.conf -oJ output.json 12 masscan 0.0.0.0/0 -p21,22,23 --banners --http-user-agent "USER_AGENT" --source-port 61000-65503 --open-only --rate 30000 --excludefile exclude.conf -oJ output_new.json --shard $i/$TOTAL 13 14 Note: The above iptables rule is not persistent and will be removed on reboot. 15 ''' 16 17 import json 18 import logging 19 import re 20 import time 21 22 default_index = 'masscan-logs' 23 24 def construct_map() -> dict: 25 '''Construct the Elasticsearch index mapping for Masscan records.''' 26 27 keyword_mapping = { 'type': 'text', 'fields': { 'keyword': { 'type': 'keyword', 'ignore_above': 256 } } } 28 29 mapping = { 30 'mappings': { 31 'properties': { 32 'ip': { 'type': 'ip' }, 33 'port': { 'type': 'integer' }, 34 'proto': { 'type': 'keyword' }, 35 'service': { 'type': 'keyword' }, 36 'banner': keyword_mapping, 37 'ref_id': { 'type': 'keyword' }, 38 'seen': { 'type': 'date' } 39 #'geoip': { 40 # 'properties': { 41 # 'city_name': keyword_mapping, 42 # 'continent_name': keyword_mapping, 43 # 'country_iso_code': keyword_mapping, 44 # 'country_name': keyword_mapping, 45 # 'location': { 'type': 'geo_point' }, 46 # 'region_iso_code': keyword_mapping, 47 # 'region_name': keyword_mapping, 48 # } 49 #} 50 } 51 } 52 } 53 54 return mapping 55 56 57 def process_file(file_path: str): 58 ''' 59 Read and process Masscan records from the log file. 60 61 :param file_path: Path to the Masscan log file 62 ''' 63 64 with open(file_path, 'r') as file: 65 for line in file: 66 line = line.strip() 67 68 if not line or not line.startswith('{'): 69 continue 70 71 if line.endswith(','): 72 line = line[:-1] 73 74 try: 75 record = json.loads(line) 76 except json.decoder.JSONDecodeError: 77 logging.error(f'Failed to parse JSON record! ({line})') 78 input('Press Enter to continue...') # Debugging 79 continue 80 81 for port_info in record['ports']: 82 struct = { 83 'ip': record['ip'], 84 'port': port_info['port'], 85 'proto': port_info['proto'], 86 'seen': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(int(record['timestamp']))), 87 } 88 89 if 'service' in port_info: 90 if 'name' in port_info['service']: 91 if port_info['service']['name'] != 'unknown': 92 struct['service'] = port_info['service']['name'] 93 94 if 'banner' in port_info['service']: 95 banner = ' '.join(port_info['service']['banner'].split()) # Remove extra whitespace 96 if banner: 97 match = re.search(r'\(Ref\.Id: (.*?)\)', banner) 98 if match: 99 struct['ref_id'] = match.group(1) 100 else: 101 struct['banner'] = banner 102 103 yield struct 104 105 return None # EOF 106 107 108 109 ''' 110 Example record: 111 { 112 "ip": "43.134.51.142", 113 "timestamp": "1705255468", # Convert to ZULU BABY 114 "ports": [ # We will create a record for each port opened 115 { 116 "port": 22, 117 "proto": "tcp", 118 "service": { # This field is optional 119 "name": "ssh", 120 "banner": "SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.4" 121 } 122 } 123 ] 124 } 125 126 Will be indexed as: 127 { 128 "ip": "43.134.51.142", 129 "port": 22, 130 "proto": "tcp", 131 "service": "ssh", 132 "banner": "SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.4", 133 "seen": "2021-10-08T02:04:28Z", 134 "ref_id": "?sKfOvsC4M4a2W8PaC4zF?" # TCP RST Payload (Do we need this?) 135 } 136 '''