-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
115 lines (89 loc) · 3.44 KB
/
main.py
File metadata and controls
115 lines (89 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import argparse
import json
from domain_analyzer import extract_domains, resolve_dns
def process_input(urls):
"""
Processes a list of URLs to extract domains, subdomains, and optionally resolve public IPs.
Args:
urls (list): List of URL strings to analyze.
Returns:
list: A list of dictionaries with keys: domain, subdomain(s), and IP address(es).
"""
aggregated = {}
for url in urls:
domain, subdomain = extract_domains(url)
if domain is None:
continue # Skip invalid URLs or IP addresses
ips = resolve_dns(domain) or []
# Initialize data structure for this domain if not already present
if domain not in aggregated:
aggregated[domain] = {
"subdomains": set(),
"ip_addresses": set()
}
# Add subdomain (empty string if none)
aggregated[domain]["subdomains"].add(subdomain or "")
# Add resolved IPs
for ip in ips:
aggregated[domain]["ip_addresses"].add(ip)
# Format the results for output
results = []
for domain, data in aggregated.items():
results.append({
"domain": domain,
"subdomain": ", ".join(sorted(data["subdomains"])),
"ip_addresses": sorted(data["ip_addresses"])
})
return results
def print_results(results):
"""
Display the processed domain results in a formatted table.
Args:
results (list): List of dictionaries with keys 'domain', 'subdomain', and 'ip_addresses'.
"""
header = "{:<25} | {:<30} | {:<40}".format("Domain", "Sub-domains", "IP Addresses")
separator = "=" * len(header)
print(header)
print(separator)
for entry in results:
domain = entry.get("domain", "N/A")
subdomains = entry.get("subdomain", "N/A")
ip_addresses = entry.get("ip_addresses", [])
if ip_addresses:
ip_str = ", ".join(ip_addresses)
else:
ip_str = "N/A"
print("{:<25} | {:<30} | {:<40}".format(domain, subdomains, ip_str))
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Extract domain info from URLs")
parser.add_argument("-u", "--url", nargs="+", help="One or more URLs to process")
parser.add_argument("-f", "--file", type=str, help="Path to file containing URLs (one per line)")
parser.add_argument("-o", "--output", type=str, help="Output results to JSON file")
args = parser.parse_args()
urls = []
# Populate URL list from CLI or file
if args.url:
urls.extend(args.url)
elif args.file:
try:
with open(args.file, 'r') as f:
urls.extend(line.strip() for line in f if line.strip())
except FileNotFoundError:
print(f"[!] File not found : {args.file}")
exit(1)
else:
print("[!] Please provide -u/--url or -f/--file.")
parser.print_help()
exit(1)
# Process the URLs
results = process_input(urls)
if not results:
print("[!] No valid domain found.")
exit(0)
# Output results to JSON file or terminal
if args.output:
with open(args.output, 'w') as out_file:
json.dump(results, out_file, indent=4)
print(f"[+] Results saved to : {args.output}")
else:
print_results(results)