eris- Elasticsearch Recon Ingestion Scripts (ERIS) 🔎 |
git clone git://git.acid.vegas/-c.git |
Log | Files | Refs | Archive | README | LICENSE |
ingest_certs.py (4656B)
1 #!/usr/bin/env python 2 # Elasticsearch Recon Ingestion Scripts (ERIS) - Developed by Acidvegas (https://git.acid.vegas/eris) 3 # ingest_certs.py 4 5 import asyncio 6 import json 7 import logging 8 import time 9 10 try: 11 import websockets 12 except ImportError: 13 raise ImportError('Missing required \'websockets\' library. (pip install websockets)') 14 15 16 # Set a default elasticsearch index if one is not provided 17 default_index = 'cert-stream' 18 19 20 def construct_map() -> dict: 21 '''Construct the Elasticsearch index mapping for Certstream records.''' 22 23 # Match on exact value or full text search 24 keyword_mapping = { 'type': 'text', 'fields': { 'keyword': { 'type': 'keyword', 'ignore_above': 256 } } } 25 26 # Construct the index mapping 27 mapping = { 28 'mappings': { 29 'properties' : { 30 'domain' : keyword_mapping, 31 'seen' : { 'type': 'date' } 32 } 33 } 34 } 35 36 return mapping 37 38 39 async def process_data(place_holder: str = None): 40 ''' 41 Read and process Certsream records live from the Websocket stream. 42 43 :param place_holder: Placeholder parameter to match the process_data function signature of other ingestors. 44 ''' 45 46 while True: 47 try: 48 async with websockets.connect('wss://certstream.calidog.io') as websocket: 49 while True: 50 # Read a line from the websocket 51 line = await websocket.recv() 52 53 # Parse the JSON record 54 try: 55 record = json.loads(line) 56 except json.decoder.JSONDecodeError: 57 logging.error(f'Invalid line from the websocket: {line}') 58 continue 59 60 # Grab the unique domains from the record (excluding wildcards) 61 domains = record['data']['leaf_cert']['all_domains'] 62 domains = set([domain[2:] if domain.startswith('*.') else domain for domain in domains]) 63 64 # Construct the document 65 for domain in domains: 66 struct = { 67 'domain' : domain, 68 'seen' : time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) 69 } 70 71 yield {'_id': id, '_index': default_index, '_source': struct} 72 73 except websockets.ConnectionClosed: 74 logging.error('Connection to Certstream was closed. Attempting to reconnect...') 75 await asyncio.sleep(15) 76 77 except Exception as e: 78 logging.error(f'An error occurred while processing Certstream records! ({e})') 79 break 80 81 82 async def test(): 83 '''Test the ingestion process.''' 84 85 async for document in process_data(): 86 print(document) 87 88 89 90 if __name__ == '__main__': 91 import asyncio 92 93 asyncio.run(test()) 94 95 96 97 ''' 98 Output: 99 { 100 "data": { 101 "cert_index": 43061646, 102 "cert_link": "https://yeti2025.ct.digicert.com/log/ct/v1/get-entries?start=43061646&end=43061646", 103 "leaf_cert": { 104 "all_domains": [ 105 "*.d7zdnegbre53n.amplifyapp.com", 106 "d7zdnegbre53n.amplifyapp.com" 107 ], 108 "extensions": { 109 "authorityInfoAccess" : "CA Issuers - URI:http://crt.r2m02.amazontrust.com/r2m02.cer\nOCSP - URI:http://ocsp.r2m02.amazontrust.com\n", 110 "authorityKeyIdentifier" : "keyid:C0:31:52:CD:5A:50:C3:82:7C:74:71:CE:CB:E9:9C:F9:7A:EB:82:E2\n", 111 "basicConstraints" : "CA:FALSE", 112 "certificatePolicies" : "Policy: 2.23.140.1.2.1", 113 "crlDistributionPoints" : "Full Name:\n URI:http://crl.r2m02.amazontrust.com/r2m02.crl", 114 "ctlPoisonByte" : true, 115 "extendedKeyUsage" : "TLS Web server authentication, TLS Web client authentication", 116 "keyUsage" : "Digital Signature, Key Encipherment", 117 "subjectAltName" : "DNS:d7zdnegbre53n.amplifyapp.com, DNS:*.d7zdnegbre53n.amplifyapp.com", 118 "subjectKeyIdentifier" : "59:32:78:2A:11:03:62:55:BB:3B:B9:80:24:76:28:90:2E:D1:A4:56" 119 }, 120 "fingerprint": "D9:05:A3:D5:AA:F9:68:BC:0C:0A:15:69:C9:5E:11:92:32:67:4F:FA", 121 "issuer": { 122 "C" : "US", 123 "CN" : "Amazon RSA 2048 M02", 124 "L" : null, 125 "O" : "Amazon", 126 "OU" : null, 127 "ST" : null, 128 "aggregated" : "/C=US/CN=Amazon RSA 2048 M02/O=Amazon", 129 "emailAddress" : null 130 }, 131 "not_after" : 1743811199, 132 "not_before" : 1709596800, 133 "serial_number" : "FDB450C1942E3D30A18737063449E62", 134 "signature_algorithm" : "sha256, rsa", 135 "subject": { 136 "C" : null, 137 "CN" : "*.d7zdnegbre53n.amplifyapp.com", 138 "L" : null, 139 "O" : null, 140 "OU" : null, 141 "ST" : null, 142 "aggregated" : "/CN=*.d7zdnegbre53n.amplifyapp.com", 143 "emailAddress" : null 144 } 145 }, 146 "seen": 1709651773.594684, 147 "source": { 148 "name" : "DigiCert Yeti2025 Log", 149 "url" : "https://yeti2025.ct.digicert.com/log/" 150 }, 151 "update_type": "PrecertLogEntry" 152 }, 153 "message_type": "certificate_update" 154 } 155 '''