mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-20 06:20:58 +03:00
- Fix 25 shell=True subprocess calls with list-based commands - Fix 49 verify=False in defensive skills (env-var override) - Add timeout to 231 HTTP/subprocess/socket calls - Fix 6 SQL injection patterns with whitelist validation - Replace 8 __import__() with standard imports - Remove 701 unused imports across 442 files - Add authorized-testing disclaimers to all offensive skills - Complete 11 incomplete skill directories - Expand 10 stub SKILL.md files with full content - Fix 2 YAML parse errors in frontmatter - Fix 5 pre-existing syntax errors - Convert 22 hardcoded paths/ports to environment variables - Back up 21 redundant skill pairs to .bak - Fix 2 global declaration errors - 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE) - 0 compile errors across all 724 agent.py files
97 lines
3.5 KiB
Python
97 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Typosquatting domain detection agent using dnstwist concepts."""
|
|
|
|
import os, sys, json, socket
|
|
from datetime import datetime
|
|
|
|
try:
|
|
import dnstwist as dnstwist_lib
|
|
HAS_DNSTWIST = True
|
|
except ImportError:
|
|
HAS_DNSTWIST = False
|
|
|
|
KEYBOARD_NEIGHBORS = {
|
|
'q': 'wa', 'w': 'qeas', 'e': 'wrds', 'r': 'etfd', 't': 'rygf',
|
|
'y': 'tuhg', 'u': 'yijh', 'i': 'uokj', 'o': 'iplk', 'p': 'ol',
|
|
'a': 'qwsz', 's': 'wedxza', 'd': 'erfcxs', 'f': 'rtgvcd',
|
|
'g': 'tyhbvf', 'h': 'yujnbg', 'j': 'uikmnh', 'k': 'iolmj',
|
|
'l': 'opk', 'z': 'asx', 'x': 'zsdc', 'c': 'xdfv', 'v': 'cfgb',
|
|
'b': 'vghn', 'n': 'bhjm', 'm': 'njk',
|
|
}
|
|
|
|
def generate_permutations(domain):
|
|
name = domain.split('.')[0]
|
|
tld = '.'.join(domain.split('.')[1:]) or 'com'
|
|
results = set()
|
|
for i in range(len(name)):
|
|
results.add(name[:i] + name[i+1:] + '.' + tld)
|
|
for i in range(len(name) - 1):
|
|
s = list(name)
|
|
s[i], s[i+1] = s[i+1], s[i]
|
|
results.add(''.join(s) + '.' + tld)
|
|
for i in range(len(name)):
|
|
if name[i] in KEYBOARD_NEIGHBORS:
|
|
for c in KEYBOARD_NEIGHBORS[name[i]]:
|
|
results.add(name[:i] + c + name[i+1:] + '.' + tld)
|
|
homoglyphs = {'o': '0', 'l': '1', 'i': '1', 's': '5', 'a': '4', 'e': '3'}
|
|
for i in range(len(name)):
|
|
if name[i] in homoglyphs:
|
|
results.add(name[:i] + homoglyphs[name[i]] + name[i+1:] + '.' + tld)
|
|
for i in range(1, len(name)):
|
|
results.add(name[:i] + '-' + name[i:] + '.' + tld)
|
|
results.discard(domain)
|
|
return sorted(results)
|
|
|
|
def resolve_domain(domain):
|
|
try:
|
|
ips = socket.getaddrinfo(domain, None, socket.AF_INET)
|
|
return list(set(ip[4][0] for ip in ips))
|
|
except socket.gaierror:
|
|
return []
|
|
|
|
def check_domains(permutations, max_check=200):
|
|
results = []
|
|
for domain in permutations[:max_check]:
|
|
ips = resolve_domain(domain)
|
|
if ips:
|
|
results.append({'domain': domain, 'ips': ips, 'registered': True})
|
|
return results
|
|
|
|
def run_dnstwist_cli(domain):
|
|
import subprocess
|
|
try:
|
|
result = subprocess.run(['dnstwist', '-r', '-f', 'json', domain],
|
|
capture_output=True, text=True, timeout=120)
|
|
if result.returncode == 0:
|
|
return json.loads(result.stdout)
|
|
except (FileNotFoundError, subprocess.TimeoutExpired, json.JSONDecodeError):
|
|
pass
|
|
return None
|
|
|
|
if __name__ == '__main__':
|
|
print('=' * 60)
|
|
print('Typosquatting Domain Detection Agent (dnstwist)')
|
|
print('Permutation generation, DNS resolution, risk scoring')
|
|
print('=' * 60)
|
|
domain = sys.argv[1] if len(sys.argv) > 1 else None
|
|
if not domain:
|
|
print('\n[DEMO] Usage: python agent.py <domain.com>')
|
|
sys.exit(0)
|
|
print(f'\n[*] Target: {domain}')
|
|
dnstwist_results = run_dnstwist_cli(domain)
|
|
if dnstwist_results:
|
|
print(f'[*] dnstwist found {len(dnstwist_results)} permutations')
|
|
for r in dnstwist_results[:10]:
|
|
a = r.get('dns_a', [''])[0] if r.get('dns_a') else ''
|
|
print(f' {r.get("domain", "?"):40s} {a}')
|
|
else:
|
|
perms = generate_permutations(domain)
|
|
print(f'[*] Generated {len(perms)} permutations')
|
|
print('[*] Resolving domains...')
|
|
resolved = check_domains(perms)
|
|
print(f'[*] Active typosquats: {len(resolved)}')
|
|
for r in resolved[:15]:
|
|
print(f' {r["domain"]:40s} {", ".join(r["ips"])}')
|
|
risk = 'HIGH' if len(resolved) > 20 else 'MEDIUM' if len(resolved) > 5 else 'LOW'
|
|
print(f'\n[*] Risk: {risk}')
|