Last active
August 7, 2023 09:11
-
-
Save yosignals/19e86eb1f2efdb5c4c333224ace93391 to your computer and use it in GitHub Desktop.
a script that takes an IP or Email address as a parental starting point and pulls out child data, if this IP was used by bad, what emails have been liked to it in breach data more on that here https://thecontractor.io/breachdatareachdata/ to use this script you'll need a rehashed.com api key and email address (for credentials) and find your swee…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import time | |
import json | |
import sys | |
api_endpoint = 'https://api.dehashed.com/search?query={}' | |
credentials = ('YOUREMAIL', 'YOURAPI') | |
headers = {'Accept': 'application/json'} | |
checked_items = {} | |
email_to_ips = {} # Maps each email to the set of associated IP addresses | |
ip_to_emails = {} # Maps each IP address to the set of associated emails | |
ip_limit = 10 # Limit for IP address queries | |
email_limit = 10 # Limit for email queries | |
raw_data = [] # List to store raw data | |
proxies = { | |
"http": "http://127.0.0.1:8080", | |
"https": "http://127.0.0.1:8080", | |
} | |
def make_request(query, query_type): | |
try: | |
time.sleep(0.33) | |
if query in checked_items.get(query_type, {}): | |
return None | |
else: | |
if len(checked_items.get(query_type, {})) >= (ip_limit if query_type == 'ip' else email_limit): | |
print(f'Skipped request for {query_type} {query} due to limit') | |
return None | |
checked_items.setdefault(query_type, set()).add(query) | |
response = requests.get(api_endpoint.format(query), auth=credentials, headers=headers, proxies=proxies, verify=False) | |
response.raise_for_status() | |
return response.json() | |
except requests.exceptions.RequestException as e: | |
print(f'Request error: {e}') | |
except json.JSONDecodeError as e: | |
print(f'JSON decode error: {e}') | |
except Exception as e: | |
print(f'Unexpected error: {e}') | |
def process_response(data, parent=None): | |
if 'entries' in data: | |
raw_data.extend(data['entries']) # Add the entries to the raw_data list | |
for entry in data['entries']: | |
entry['parent'] = parent # Keep track of parent | |
email = entry.get('email') | |
ip_address = entry.get('ip_address') | |
if email and ip_address: | |
email_to_ips.setdefault(email, set()).add(ip_address) | |
ip_to_emails.setdefault(ip_address, set()).add(email) | |
for field in ['email', 'ip_address']: | |
value = entry.get(field) | |
if value and (value not in checked_items.get(field, {})): | |
data = make_request(value, 'email' if field == 'email' else 'ip') | |
if data is not None: | |
process_response(data, parent=entry) | |
# Validate command line arguments | |
if len(sys.argv) < 2: | |
print('Usage: python lifesabreach.py <start>') | |
print('<start> must be an IP address or an email address') | |
sys.exit(1) | |
start = sys.argv[1] | |
query_type = 'email' if '@' in start else 'ip' | |
# Sample usage | |
data = make_request(start, query_type) | |
if data is not None: | |
process_response(data) | |
# Open a file to append the summary | |
with open('summary.txt', 'a') as f: | |
for email, ips in email_to_ips.items(): | |
f.write(f'Email {email} is associated with IP addresses {ips}\n') | |
for ip_address, emails in ip_to_emails.items(): | |
f.write(f'IP address {ip_address} is associated with emails {emails}\n') | |
# Save to JSON files | |
summary = { | |
'checked_items': {k: list(v) for k, v in checked_items.items()}, | |
'email_to_ips': {k: list(v) for k, v in email_to_ips.items()}, | |
'ip_to_emails': {k: list(v) for k, v in ip_to_emails.items()}, | |
} | |
with open('output.json', 'w') as f: | |
json.dump(summary, f) | |
with open('raw.json', 'w') as f: | |
json.dump(raw_data, f) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment