Bu yazılım, Python ile geliştirilmiş gelişmiş bir domain varyasyon ve durum kontrol aracıdır. Kullanıcı tarafından girilen domain adının olası varyasyonlarını (tipografi hataları, leetspeak dönüşümleri vb.) otomatik olarak üretir, ardından DNS, WHOIS, SSL sertifika kontrolleri, ve Selenium destekli ekran görüntüsü alma gibi kapsamlı kontroller gerçekleştirir. Çoklu iş parçacığı (multithreading) desteği ve hata yönetimi sayesinde hızlı, güvenilir sonuçlar elde edilir. Sonuçlar CSV, JSON ve HTML formatlarında raporlanır. Hem komut satırı argümanlarıyla hem de etkileşimli modda çalışabilen bu araç, domain araştırmaları ve siber güvenlik uygulamalarında pratik ve etkili bir çözüm sunar. import socket
import whois
import pyfiglet
import csv
import json
import ssl
import time
import argparse
import os
from concurrent.futures import ThreadPoolExecutor
from tenacity import retry, stop_after_attempt
from tqdm import tqdm
from colorama import init, Fore
import dns.resolver
import asyncio
import aiohttp
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
init(autoreset=True)
socket.setdefaulttimeout(10)
LEET_MAP = {
'o': '0',
'i': '1',
'l': '1',
's': '5'
}
TLD_LIST = ['.com.tr', '.com', '.net', '.tr']
dns_cache = {}
whois_cache = {}
def load_common_typos(file_path="common_typos.txt"):
typos = set()
if os.path.exists(file_path):
with open(file_path, "r") as f:
for line in f:
typo = line.strip()
if typo:
typos.add(typo)
return typos
def apply_leetspeak(domain):
for tld in TLD_LIST:
if domain.endswith(tld):
name = domain[:-len(tld)]
ext = tld
break
else:
name = domain
ext = ""
new_name = name
for char, replacement in LEET_MAP.items():
new_name = new_name.replace(char, replacement)
return new_name + ext
def generate_variations(domain):
variations = set()
variations.add(domain)
if '.' in domain:
name, tld = domain.rsplit('.', 1)
base_tld = '.' + tld
else:
name = domain
base_tld = ''
if len(name) > 1:
variations.add(name[1:] + base_tld)
variations.add(name[:-1] + base_tld)
for i in range(1, len(name)):
lst = list(name)
lst[i - 1], lst[i] = lst[i], lst[i - 1]
variations.add("".join(lst) + base_tld)
if len(name) > 3:
mid = len(name) // 2
variations.add(name[:mid] + '-' + name[mid:] + base_tld)
common_typos = load_common_typos()
for typo in common_typos:
if name in typo or typo in name:
variations.add(typo + base_tld)
for tld_variant in TLD_LIST:
variations.add(name + tld_variant)
leet_variations = set()
for var in list(variations):
leet_var = apply_leetspeak(var)
if leet_var != var:
leet_variations.add(leet_var)
variations.update(leet_variations)
return list(variations)
@retry(stop=stop_after_attempt(3))
def check_whois(domain):
if domain in whois_cache:
return whois_cache[domain]
try:
w = whois.whois(domain)
whois_cache[domain] = w
return w
except Exception:
whois_cache[domain] = None
return None
@retry(stop=stop_after_attempt(3))
def check_dns(domain):
if domain in dns_cache:
return dns_cache[domain]
result = {}
try:
ip = socket.gethostbyname(domain)
result['A'] = ip
except Exception:
result['A'] = None
try:
answers = dns.resolver.resolve(domain, 'MX')
result['MX'] = [r.exchange.to_text() for r in answers]
except Exception:
result['MX'] = []
try:
answers = dns.resolver.resolve(domain, 'NS')
result['NS'] = [r.target.to_text() for r in answers]
except Exception:
result['NS'] = []
try:
answers = dns.resolver.resolve(domain, 'TXT')
result['TXT'] = [r.to_text() for r in answers]
except Exception:
result['TXT'] = []
dns_cache[domain] = result
return result
def check_ssl_certificate(domain):
context = ssl.create_default_context()
try:
with socket.create_connection((domain, 443)) as sock:
with context.wrap_socket(sock, server_hostname=domain) as ssock:
cert = ssock.getpeercert()
return cert.get('notAfter', None)
except Exception:
return None
def take_screenshot(domain):
try:
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=chrome_options)
url = "http://" + domain
driver.get(url)
screenshot_path = f"{domain.replace('.', '_')}.png"
driver.save_screenshot(screenshot_path)
driver.quit()
return screenshot_path
except Exception:
return None
def check_phishing(domain):
return False
def check_domain(domain):
time.sleep(1)
result = {"domain": domain}
dns_result = check_dns(domain)
result['dns'] = dns_result
whois_result = check_whois(domain)
result['whois'] = whois_result
result['ssl'] = check_ssl_certificate(domain)
result['phishing'] = check_phishing(domain)
result['screenshot'] = take_screenshot(domain)
is_taken = False
if dns_result.get('A'):
is_taken = True
elif whois_result and (
(isinstance(whois_result, dict) and whois_result.get('domain_name')) or
(hasattr(whois_result, 'domain_name') and whois_result.domain_name)
):
is_taken = True
result['taken'] = is_taken
return result
def export_to_csv(results, filename="results.csv"):
with open(filename, "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["Domain", "Taken", "IP", "MX", "NS", "TXT", "SSL Expiry", "Phishing", "Screenshot"])
for res in results:
writer.writerow([
res['domain'],
res['taken'],
res['dns'].get('A'),
";".join(res['dns'].get('MX', [])),
";".join(res['dns'].get('NS', [])),
";".join(res['dns'].get('TXT', [])),
res['ssl'],
res['phishing'],
res['screenshot'] if res['screenshot'] else ""
])
def export_to_json(results, filename="results.json"):
with open(filename, "w") as f:
json.dump(results, f, indent=4, default=str)
def export_to_html(results, filename="report.html"):
try:
from jinja2 import Template
except ImportError:
print("Jinja2 yüklü değil. HTML raporu oluşturulamıyor.")
return
template_str = """
<html>
<head>
<title>Domain Check Report</title>
<meta charset="utf-8">
</head>
<body>
<h1>Domain Check Report</h1>
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<th>Domain</th><th>Taken</th><th>IP</th><th>MX</th><th>NS</th><th>TXT</th><th>SSL Expiry</th><th>Phishing</th><th>Screenshot</th>
</tr>
{% for res in results %}
<tr>
<td>{{ res.domain }}</td>
<td>{{ res.taken }}</td>
<td>{{ res.dns.A }}</td>
<td>{{ res.dns.MX|join('; ') }}</td>
<td>{{ res.dns.NS|join('; ') }}</td>
<td>{{ res.dns.TXT|join('; ') }}</td>
<td>{{ res.ssl }}</td>
<td>{{ res.phishing }}</td>
<td>{% if res.screenshot %}<a href="{{ res.screenshot }}">View</a>{% endif %}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
"""
template = Template(template_str)
html_content = template.render(results=results)
with open(filename, "w") as f:
f.write(html_content)
def interactive_mode():
banner = pyfiglet.figlet_format("Mariently", font="ansi_shadow")
print(Fore.GREEN + banner)
print(Fore.YELLOW + "Hoşgeldiniz! Domain varyasyon ve durum kontrol aracına hoşgeldiniz.\n")
mode = input("Domain girişi için 'd', dosya yüklemek için 'f' giriniz: ").strip().lower()
domains = []
if mode == 'f':
file_path = input("Dosya yolunu giriniz: ").strip()
if os.path.exists(file_path):
with open(file_path, "r") as f:
for line in f:
domain_line = line.strip()
if domain_line:
domains.append(domain_line)
else:
print("Dosya bulunamadı. Çıkılıyor.")
return
else:
domain_input = input("Varyasyonlarını oluşturmak istediğiniz domaini giriniz (örn: ornek.com): ").strip()
domains = generate_variations(domain_input)
results = []
print("\nKontroller başlatılıyor...\n")
with ThreadPoolExecutor(max_workers=10) as executor:
for res in tqdm(executor.map(check_domain, domains), total=len(domains)):
results.append(res)
for res in results:
print(Fore.BLUE + f"Kontrol ediliyor: {res['domain']}")
if res['taken']:
print(Fore.RED + "Sonuç: Bu domain dolu!")
else:
print(Fore.WHITE + "Sonuç: Bu domain uygun!")
print("-" * 50)
export_to_csv(results)
export_to_json(results)
export_to_html(results)
print("Sonuçlar 'results.csv', 'results.json' ve 'report.html' dosyalarına kaydedildi.")
def main():
parser = argparse.ArgumentParser(description="Gelişmiş Domain Varyasyon ve Durum Kontrol Aracı")
parser.add_argument("--file", help="Domain listesinin bulunduğu dosya yolu", default=None)
parser.add_argument("--domain", help="Tek bir domain (örn: ornek.com)", default=None)
args = parser.parse_args()
if args.file:
domains = []
file_path = args.file
if os.path.exists(file_path):
with open(file_path, "r") as f:
for line in f:
domain_line = line.strip()
if domain_line:
domains.append(domain_line)
else:
print("Dosya bulunamadı. Çıkılıyor.")
return
elif args.domain:
domains = generate_variations(args.domain)
else:
interactive_mode()
return
results = []
print("\nKontroller başlatılıyor...\n")
with ThreadPoolExecutor(max_workers=10) as executor:
for res in tqdm(executor.map(check_domain, domains), total=len(domains)):
results.append(res)
for res in results:
print(Fore.BLUE + f"Kontrol ediliyor: {res['domain']}")
if res['taken']:
print(Fore.RED + "Sonuç: Bu domain dolu!")
else:
print(Fore.WHITE + "Sonuç: Bu domain uygun!")
print("-" * 50)
export_to_csv(results)
export_to_json(results)
export_to_html(results)
print("Sonuçlar 'results.csv', 'results.json' ve 'report.html' dosyalarına kaydedildi.")
if __name__ == "__main__":
main()