Araçlara Dön

Kaynak Kod

arac.py — Siber Güvenlik / CTF Araç Seti

arac.py
  • import base64
  • import binascii
  • import codecs
  • import hashlib
  • import os
  • import re
  • import subprocess
  • import sys
  • import urllib.error
  • import urllib.parse
  • import urllib.request
  • import webbrowser
  • import zipfile
  • from concurrent.futures import ThreadPoolExecutor, as_completed
  • from datetime import date
  • def temizle():
  • """Terminal ekranını temizler."""
  • os.system("clear" if os.name == "posix" else "cls")
  • # =====================================================================
  • # UI YARDIMCILARI: RENK, BANNER, KUTULU MENÜ
  • # =====================================================================
  • class Renk:
  • RESET = "\033[0m"
  • BOLD = "\033[1m"
  • YESIL = "\033[92m"
  • KIRMIZI = "\033[91m"
  • SARI = "\033[93m"
  • MAVI = "\033[96m"
  • MOR = "\033[95m"
  • GRI = "\033[90m"
  • def _windows_ansi_etkinlestir():
  • """Eski Windows cmd.exe'de ANSI renk/kutu karakterlerini etkinleştirir (Windows 10+)."""
  • if os.name == "nt":
  • os.system("")
  • def basari(mesaj):
  • print(f"{Renk.YESIL}[+]{Renk.RESET} {mesaj}")
  • def hata(mesaj):
  • print(f"{Renk.KIRMIZI}[-]{Renk.RESET} {mesaj}")
  • def uyari(mesaj):
  • print(f"{Renk.SARI}[!]{Renk.RESET} {mesaj}")
  • def bilgi(mesaj):
  • print(f"{Renk.MAVI}[*]{Renk.RESET} {mesaj}")
  • def devam_et(mesaj="\nDevam etmek için Enter'a basın..."):
  • input(f"{Renk.GRI}{mesaj}{Renk.RESET}")
  • def kutu_menu(baslik, secenekler, min_genislik=45, maks_genislik=78):
  • """Başlık + (kod, açıklama) listesini kutu çizgileriyle çizer. Genişlik içeriğe göre otomatik ayarlanır.
  • ASCII (+, -, |) çizgiler kullanılır: Unicode kutu çizgi karakterleri Windows'un
  • Türkçe kod sayfasında (cp1254) bulunmadığı için UnicodeEncodeError'a yol açıyordu.
  • """
  • olasi_uzunluklar = [len(baslik) + 2] + [
  • len(f" {kod!s:<3}{aciklama}") for kod, aciklama in secenekler
  • ]
  • ic = min(max(min_genislik, max(olasi_uzunluklar) + 2), maks_genislik)
  • cizgi = "-" * ic
  • print(f"{Renk.MAVI}+{cizgi}+{Renk.RESET}")
  • print(f"{Renk.MAVI}|{Renk.RESET}{Renk.BOLD}{baslik.center(ic)}{Renk.RESET}{Renk.MAVI}|{Renk.RESET}")
  • print(f"{Renk.MAVI}+{cizgi}+{Renk.RESET}")
  • for kod, aciklama in secenekler:
  • satir = f" {kod!s:<3}{aciklama}"
  • satir = satir[:ic].ljust(ic)
  • print(f"{Renk.MAVI}|{Renk.RESET}{satir}{Renk.MAVI}|{Renk.RESET}")
  • print(f"{Renk.MAVI}+{cizgi}+{Renk.RESET}")
  • def baslik_kutusu(metin, min_genislik=45):
  • """Menü listesi olmayan (tek akışlı) ekranlar için sade bir başlık kutusu çizer."""
  • ic = max(min_genislik, len(metin) + 2)
  • cizgi = "-" * ic
  • print(f"{Renk.MAVI}+{cizgi}+{Renk.RESET}")
  • print(f"{Renk.MAVI}|{Renk.RESET}{Renk.BOLD}{metin.center(ic)}{Renk.RESET}{Renk.MAVI}|{Renk.RESET}")
  • print(f"{Renk.MAVI}+{cizgi}+{Renk.RESET}\n")
  • def banner_yazdir():
  • ic = 57
  • cizgi = "=" * ic
  • print(f"{Renk.MOR}{Renk.BOLD}")
  • print(f"+{cizgi}+")
  • print("|" + "SİBER GÜVENLİK / CTF ARAÇ SETİ".center(ic) + "|")
  • print(f"+{cizgi}+{Renk.RESET}{Renk.MOR}")
  • print("|" + "Yalnızca yetkili pentest ve CTF kullanımı içindir".center(ic) + "|")
  • print(f"+{cizgi}+{Renk.RESET}\n")
  • def nmap_calistir(komut_listesi):
  • try:
  • print()
  • uyari("Tarama başlatıldı, lütfen bekleyin...\n")
  • process = subprocess.Popen(
  • komut_listesi, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
  • )
  • for line in process.stdout:
  • print(line, end="")
  • process.wait()
  • if process.returncode != 0:
  • hata(f"Bir hata oluştu: {process.stderr.read()}")
  • except FileNotFoundError:
  • hata("'nmap' kurulu görünmüyor. 'sudo apt install nmap' komutunu deneyin.")
  • except KeyboardInterrupt:
  • hata("Tarama kullanıcı tarafından iptal edildi.")
  • def nmap_menusu():
  • temizle()
  • kutu_menu("NMAP PORT TARAMA MENÜSÜ", [
  • (1, "Genel Hızlı Port Taraması"),
  • (2, "Detaylı Port Taraması (Tüm Portlar)"),
  • (3, "Versiyon Taraması"),
  • (0, "Geri Dön"),
  • ])
  • secim = input("\nSeçiminiz: ")
  • if secim == "0":
  • return
  • hedef = input("\nHedef IP/Domain: ").strip()
  • if not hedef:
  • hata("Hedef boş bırakılamaz!")
  • devam_et()
  • return
  • if secim == "1":
  • komut = ["nmap", "-F", hedef]
  • elif secim == "2":
  • komut = ["nmap", "-p-", "-v", hedef]
  • elif secim == "3":
  • komut = ["nmap", "-sV", hedef]
  • else:
  • return
  • nmap_calistir(komut)
  • devam_et()
  • # =====================================================================
  • # GÜNCELLENDİ: THREAD'Lİ DİZİN TARAMA MODÜLÜ
  • # =====================================================================
  • def dizin_tara_tek(url, dizin):
  • """Tek bir dizini test eder ve sonucu döndürür (print etmez)."""
  • test_url = f"{url}/{dizin}"
  • try:
  • istek = urllib.request.Request(
  • test_url, headers={"User-Agent": "Mozilla/5.0"}
  • )
  • with urllib.request.urlopen(istek, timeout=5) as cevap:
  • if cevap.getcode() == 200:
  • return (dizin, 200)
  • except urllib.error.HTTPError as e:
  • if e.code == 403:
  • return (dizin, 403)
  • except urllib.error.URLError:
  • return ("__BAGLANTI_HATASI__", None)
  • return None
  • def dizin_tarama_menusu():
  • temizle()
  • baslik_kutusu("WEB DİZİN TARAMA MENÜSÜ")
  • url = input("Hedef URL (Örn: http://site.com): ").strip()
  • if not url:
  • hata("Hata: URL boş bırakılamaz!")
  • devam_et()
  • return
  • if url.endswith("/"):
  • url = url[:-1]
  • wordlist_yolu = (
  • input("Wordlist Yolu (Varsayılan: wordlist.txt): ").strip() or "wordlist.txt"
  • )
  • if not os.path.exists(wordlist_yolu):
  • hata("Wordlist bulunamadı!")
  • devam_et()
  • return
  • try:
  • eszamanli = input(
  • "Eşzamanlı istek sayısı (Varsayılan: 20): "
  • ).strip()
  • eszamanli = int(eszamanli) if eszamanli else 20
  • except ValueError:
  • eszamanli = 20
  • kayit_dosyasi = input(
  • "Sonuçları kaydetmek istersen dosya adı gir (boş bırakırsan kaydetmez): "
  • ).strip()
  • with open(wordlist_yolu, "r", encoding="utf-8", errors="ignore") as f:
  • dizinler = [
  • satir.strip()
  • for satir in f
  • if satir.strip() and not satir.startswith("#")
  • ]
  • if not dizinler:
  • hata("Wordlist boş görünüyor!")
  • devam_et()
  • return
  • toplam = len(dizinler)
  • tamamlanan = 0
  • bulunanlar = []
  • baglanti_hatasi_bildirildi = False
  • print()
  • basari(f"Tarama başlatılıyor... ({toplam} kelime, {eszamanli} eşzamanlı istek)\n")
  • try:
  • with ThreadPoolExecutor(max_workers=eszamanli) as executor:
  • futures = {
  • executor.submit(dizin_tara_tek, url, dizin): dizin for dizin in dizinler
  • }
  • for future in as_completed(futures):
  • tamamlanan += 1
  • sonuc = future.result()
  • # İlerleme çubuğunu aynı satırda güncelle
  • yuzde = (tamamlanan / toplam) * 100
  • print(f"\r{Renk.MAVI}[*]{Renk.RESET} İlerleme: {tamamlanan}/{toplam} (%{yuzde:.1f}) ", end="", flush=True)
  • if sonuc is None:
  • continue
  • dizin, kod = sonuc
  • if dizin == "__BAGLANTI_HATASI__":
  • if not baglanti_hatasi_bildirildi:
  • print()
  • hata("Hedefe bağlanılamıyor, taramayı durduruyorum...")
  • baglanti_hatasi_bildirildi = True
  • executor.shutdown(wait=False, cancel_futures=True)
  • break
  • continue
  • renk = Renk.YESIL if kod == 200 else Renk.SARI
  • etiket = "200 OK" if kod == 200 else "403 Forbidden"
  • print(f"\n/{dizin:<29} | {renk}{etiket}{Renk.RESET}")
  • bulunanlar.append((dizin, kod))
  • except KeyboardInterrupt:
  • print()
  • hata("Tarama kullanıcı tarafından durduruldu.")
  • print()
  • basari(f"Tarama tamamlandı. {len(bulunanlar)} sonuç bulundu.")
  • if kayit_dosyasi and bulunanlar:
  • try:
  • with open(kayit_dosyasi, "w", encoding="utf-8") as f:
  • for dizin, kod in sorted(bulunanlar):
  • f.write(f"/{dizin} - {kod}\n")
  • basari(f"Sonuçlar '{kayit_dosyasi}' dosyasına kaydedildi.")
  • except OSError as e:
  • hata(f"Sonuçlar kaydedilirken hata oluştu: {e}")
  • devam_et()
  • def guvenli_extractall(z, cikis_klasoru):
  • """extractall'ın güvenli hâli: zip içindeki dosya yolları hedef klasörün dışına
  • çıkamaz (bkz. 'zip slip' - path traversal). Normal/iyi huylu zip dosyalarının
  • çıkarılma şeklini değiştirmez, yalnızca dizin dışına çıkan girdileri atlar."""
  • hedef_klasor = os.path.abspath(cikis_klasoru)
  • for uye in z.namelist():
  • hedef_yol = os.path.abspath(os.path.join(hedef_klasor, uye))
  • if hedef_yol != hedef_klasor and not hedef_yol.startswith(hedef_klasor + os.sep):
  • uyari(f"Güvenlik: '{uye}' hedef klasörün dışına çıkan bir yol içerdiği için atlandı.")
  • continue
  • z.extract(uye, hedef_klasor)
  • def normal_unzip(zip_yolu, cikis_klasoru):
  • try:
  • with zipfile.ZipFile(zip_yolu, "r") as z:
  • guvenli_extractall(z, cikis_klasoru)
  • basari(f"Başarılı: '{zip_yolu}' dosyası '{cikis_klasoru}' klasörüne çıkartıldı.")
  • except zipfile.BadZipFile:
  • hata("Hata: Bu geçerli bir zip dosyası değil!")
  • except FileNotFoundError:
  • hata("Hata: Belirtilen zip dosyası bulunamadı!")
  • def ice_ice_unzip(baslangic_zip_yolu, cikis_klasoru):
  • if not os.path.exists(baslangic_zip_yolu):
  • hata("Hata: Başlangıç zip dosyası bulunamadı!")
  • return
  • os.makedirs(cikis_klasoru, exist_ok=True)
  • mevcut_zip = baslangic_zip_yolu
  • katman_sayisi = 0
  • print()
  • basari("İç içe zip çözme işlemi başlatıldı...")
  • print(f"{Renk.GRI}{'-' * 50}{Renk.RESET}")
  • try:
  • while True:
  • if not zipfile.is_zipfile(mevcut_zip):
  • print(f"{Renk.GRI}{'-' * 50}{Renk.RESET}")
  • uyari(f"Bitti: Artık çözülecek zip kalmadı. Toplam {katman_sayisi} katman açıldı.")
  • basari(f"Son dosya konumu: {mevcut_zip}")
  • break
  • with zipfile.ZipFile(mevcut_zip, "r") as z:
  • dosya_listesi = z.namelist()
  • if not dosya_listesi:
  • hata("Boş zip dosyasıyla karşılaşıldı.")
  • break
  • guvenli_extractall(z, cikis_klasoru)
  • katman_sayisi += 1
  • bilgi(f"Katman {katman_sayisi}: {os.path.basename(mevcut_zip)} başarıyla açıldı.")
  • yeni_hedef_bulundu = False
  • for dosya in dosya_listesi:
  • tam_yol = os.path.join(cikis_klasoru, dosya)
  • if zipfile.is_zipfile(tam_yol):
  • if katman_sayisi > 1 and mevcut_zip.startswith(cikis_klasoru):
  • try:
  • os.remove(mevcut_zip)
  • except OSError:
  • pass
  • mevcut_zip = tam_yol
  • yeni_hedef_bulundu = True
  • break
  • if not yeni_hedef_bulundu:
  • print(f"{Renk.GRI}{'-' * 50}{Renk.RESET}")
  • basari(f"Sonuç: Son katman açıldı, içerisinden çıkan dosyalar '{cikis_klasoru}' altında.")
  • break
  • except Exception as e:
  • hata(f"İşlem sırasında bir hata oluştu: {e}")
  • except KeyboardInterrupt:
  • hata("Kullanıcı tarafından kesildi.")
  • def zip_menusu():
  • temizle()
  • kutu_menu("ZIP ARŞİV ÇÖZÜCÜ (CTF SPECIAL)", [
  • (1, "Standart Unzip (Tek bir arşivi aç)"),
  • (2, "Otomatik İç İçe Unzip (Matruşka Modu)"),
  • (0, "Geri Dön"),
  • ])
  • secim = input("\nSeçiminiz: ")
  • if secim == "0":
  • return
  • zip_dosyasi = input("\nÇözülecek zip dosyasının yolu (Örn: flag.zip): ").strip()
  • hedef_klasor = (
  • input("Çıkartılacak klasör adı (Varsayılan: ayıklananlar): ").strip()
  • or "ayıklananlar"
  • )
  • if secim == "1":
  • normal_unzip(zip_dosyasi, hedef_klasor)
  • elif secim == "2":
  • ice_ice_unzip(zip_dosyasi, hedef_klasor)
  • else:
  • hata("Geçersiz seçim!")
  • devam_et("\nAna menüye dönmek için Enter'a basın...")
  • def vpn_baslatici_menusu():
  • temizle()
  • baslik_kutusu("OPENVPN BAŞLATMA ARACI")
  • vpn_adi = input(
  • "VPN Dosyasının Adı (Örn: lab_baglantisi veya hackviser.ovpn): "
  • ).strip()
  • if not vpn_adi:
  • hata("Hata: Geçersiz dosya adı!")
  • devam_et()
  • return
  • if not vpn_adi.endswith(".ovpn"):
  • vpn_adi += ".ovpn"
  • vpn_klasoru = os.environ.get("VPN_KLASORU", os.path.expanduser("~/Downloads"))
  • vpn_yolu = os.path.join(vpn_klasoru, vpn_adi)
  • if not os.path.exists(vpn_yolu):
  • print()
  • hata(f"Hata: Dosya bulunamadı! Aranan yol: {vpn_yolu}")
  • uyari("Lütfen dosyanın doğru klasörde olduğundan emin olun (VPN_KLASORU ortam değişkeniyle değiştirilebilir).")
  • devam_et()
  • return
  • print()
  • basari(f"VPN Başlatılıyor: {vpn_yolu}")
  • uyari("Bağlantıyı kesmek için istediğiniz zaman CTRL + C tuşlarına basın.\n")
  • try:
  • process = subprocess.Popen(
  • ["openvpn", vpn_yolu], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
  • )
  • for line in process.stdout:
  • print(line, end="")
  • if "Initialization Sequence Completed" in line:
  • print(f"\n{Renk.YESIL}{Renk.BOLD}[+++] VPN BAĞLANTISI BAŞARIYLA SAĞLANDI! [+++]{Renk.RESET}\n")
  • process.wait()
  • except FileNotFoundError:
  • hata("Hata: Sistemde 'openvpn' kurulu görünmüyor.")
  • except KeyboardInterrupt:
  • print()
  • hata("VPN bağlantısı kullanıcı tarafından sonlandırıldı.")
  • if 'process' in locals():
  • process.terminate()
  • devam_et("\nAna menüye dönmek için Enter'a basın...")
  • def dosyada_ara(dosya_yolu, aranan_kelime):
  • if not os.path.isfile(dosya_yolu):
  • hata(f"Hata: '{dosya_yolu}' geçerli bir dosya değil!")
  • return
  • bulundu = False
  • try:
  • with open(dosya_yolu, "r", encoding="utf-8", errors="ignore") as f:
  • for satir_no, satir in enumerate(f, 1):
  • if aranan_kelime.lower() in satir.lower():
  • temiz_satir = satir.strip()
  • renkli_satir = re.sub(
  • f"({re.escape(aranan_kelime)})",
  • rf"{Renk.YESIL}\1{Renk.RESET}",
  • temiz_satir,
  • flags=re.IGNORECASE,
  • )
  • print(f"[{Renk.MAVI}Satır {satir_no}{Renk.RESET}] {renkli_satir}")
  • bulundu = True
  • if not bulundu:
  • hata("Eşleşen bir sonuç bulunamadı.")
  • except Exception as e:
  • hata(f"Dosya okunurken hata oluştu: {e}")
  • def klasorde_ara(klasor_yolu, aranan_kelime):
  • if not os.path.isdir(klasor_yolu):
  • hata(f"Hata: '{klasor_yolu}' geçerli bir klasör değil!")
  • return
  • print()
  • basari(f"'{klasor_yolu}' klasöründe '{aranan_kelime}' aranıyor...\n")
  • toplam_bulunan = 0
  • try:
  • for kök_dizin, alt_klasorler, dosyalar in os.walk(klasor_yolu):
  • for dosya in dosyalar:
  • tam_yol = os.path.join(kök_dizin, dosya)
  • if os.path.getsize(tam_yol) > 10 * 1024 * 1024:
  • continue
  • try:
  • with open(tam_yol, "r", encoding="utf-8", errors="ignore") as f:
  • for satir_no, satir in enumerate(f, 1):
  • if aranan_kelime.lower() in satir.lower():
  • temiz_satir = satir.strip()
  • renkli_satir = re.sub(
  • f"({re.escape(aranan_kelime)})",
  • rf"{Renk.YESIL}\1{Renk.RESET}",
  • temiz_satir,
  • flags=re.IGNORECASE,
  • )
  • print(f"{Renk.SARI}{tam_yol}{Renk.RESET} [{Renk.MAVI}S:{satir_no}{Renk.RESET}] -> {renkli_satir}")
  • toplam_bulunan += 1
  • except Exception:
  • continue
  • print(f"{Renk.GRI}{'-' * 50}{Renk.RESET}")
  • basari(f"Arama tamamlandı. Toplam {toplam_bulunan} eşleşme bulundu.")
  • except KeyboardInterrupt:
  • print()
  • hata("Arama kullanıcı tarafından durduruldu.")
  • def kelime_arama_menusu():
  • temizle()
  • kutu_menu("KELİME ARAMA ARACI (GREP MODU)", [
  • (1, "Klasör İçindeki Tüm Dosyalarda Ara"),
  • (2, "Sadece Belirli Bir Dosyada Ara"),
  • (0, "Geri Dön"),
  • ])
  • secim = input("\nSeçiminiz: ")
  • if secim == "0":
  • return
  • aranan = input("\nAranacak Kelime / İfade: ").strip()
  • if not aranan:
  • hata("Geçersiz kelime!")
  • devam_et()
  • return
  • if secim == "1":
  • klasor = input("Hedef Klasör Yolu: ").strip()
  • klasorde_ara(klasor, aranan)
  • elif secim == "2":
  • dosya = input("Hedef Dosya Yolu: ").strip()
  • dosyada_ara(dosya, aranan)
  • devam_et("\nAna menüye dönmek için Enter'a basın...")
  • # =====================================================================
  • # YENİ EKLEME: ENCODE / DECODE MODÜLÜ
  • # =====================================================================
  • def _base64_decode_dene(veri):
  • try:
  • return base64.b64decode(veri + "=" * (-len(veri) % 4)).decode("utf-8")
  • except Exception:
  • return None
  • def _base64_gibi_mi(veri):
  • """Bir sonraki katmanın hâlâ Base64 olup olmadığını tahmin eder (karakter seti kontrolü)."""
  • veri = veri.strip()
  • if len(veri) < 4:
  • return False
  • return bool(re.fullmatch(r"[A-Za-z0-9+/]+={0,2}", veri))
  • def coklu_base64_decode_dene(veri, maks_katman=10):
  • """CTF'lerde sık görülen üst üste (2-3-4-5 kat) Base64 encode'u otomatik soyar.
  • Her katmanda: decode et -> anlamlı/yazdırılabilir mi kontrol et -> hâlâ Base64'e
  • benziyorsa bir sonraki katmana geç. Sonuç, bulunan tüm ara katmanların listesidir
  • (son eleman en dıştaki encode'un çözülmüş hâli / muhtemel son metin)."""
  • katmanlar = []
  • mevcut = veri.strip()
  • for _ in range(maks_katman):
  • sonuc = _base64_decode_dene(mevcut)
  • if not sonuc:
  • break
  • yazdirilabilir = sum(1 for c in sonuc if c.isprintable()) / len(sonuc)
  • if yazdirilabilir < 0.85:
  • # Muhtemelen yanlış çözüldü (binary/anlamsız veri) - dur
  • break
  • katmanlar.append(sonuc)
  • if not _base64_gibi_mi(sonuc):
  • # Sonuç artık Base64'e benzemiyor -> muhtemelen son katmana ulaşıldı
  • break
  • mevcut = sonuc
  • return katmanlar
  • def _base32_gibi_mi(veri):
  • """Girdinin Base32 karakter setine (A-Z, 2-7, '=' padding) uyup uymadığını kontrol eder."""
  • veri = veri.strip()
  • if len(veri) < 4:
  • return False
  • return bool(re.fullmatch(r"[A-Z2-7]+={0,6}", veri))
  • def _base32_decode_dene(veri):
  • try:
  • temiz = veri.strip().upper()
  • temiz += "=" * (-len(temiz) % 8)
  • return base64.b32decode(temiz).decode("utf-8")
  • except Exception:
  • return None
  • def _hex_decode_dene(veri):
  • try:
  • temiz = veri.strip().replace(" ", "").replace("0x", "")
  • return bytes.fromhex(temiz).decode("utf-8")
  • except Exception:
  • return None
  • def _rot13_dene(veri):
  • try:
  • return codecs.decode(veri, "rot_13")
  • except Exception:
  • return None
  • def _url_decode_dene(veri):
  • try:
  • sonuc = urllib.parse.unquote(veri)
  • return sonuc if sonuc != veri else None
  • except Exception:
  • return None
  • def _binary_decode_dene(veri):
  • try:
  • temiz = veri.strip().replace(" ", "")
  • if not re.fullmatch(r"[01]+", temiz) or len(temiz) % 8 != 0:
  • return None
  • return "".join(
  • chr(int(temiz[i:i + 8], 2)) for i in range(0, len(temiz), 8)
  • )
  • except Exception:
  • return None
  • def otomatik_decode_dene(veri):
  • """Girdiyi sırasıyla farklı yöntemlerle çözmeye çalışır, anlamlı sonuçları gösterir."""
  • bulundu = False
  • # Base64: üst üste kaç kat encode edilmiş olursa olsun otomatik soyar
  • katmanlar = coklu_base64_decode_dene(veri)
  • if katmanlar:
  • bulundu = True
  • if len(katmanlar) == 1:
  • print(f"[{Renk.YESIL}Base64{Renk.RESET}] -> {katmanlar[0]}")
  • else:
  • print(f"[{Renk.YESIL}Base64 - {len(katmanlar)} kat üst üste çözüldü{Renk.RESET}]")
  • for i, katman in enumerate(katmanlar, 1):
  • etiket = " (son katman)" if i == len(katmanlar) else ""
  • print(f" Katman {i}{etiket}: {katman}")
  • denemeler = {
  • "Base32": _base32_decode_dene(veri),
  • "Hex": _hex_decode_dene(veri),
  • "ROT13": _rot13_dene(veri),
  • "URL Decode": _url_decode_dene(veri),
  • "Binary": _binary_decode_dene(veri),
  • }
  • for yontem, sonuc in denemeler.items():
  • if yontem == "ROT13" and (_base64_gibi_mi(veri) or _base32_gibi_mi(veri)):
  • # Girdi zaten Base64/Base32 karakter setine uyuyorsa ROT13 sonucu neredeyse
  • # her zaman anlamsız rastgele harflerden oluşur - göstermeye değmez.
  • continue
  • if sonuc and sonuc.strip() and sonuc != veri:
  • # Yazdırılabilir karakter oranı düşükse muhtemelen anlamsız/yanlış çözüm
  • yazdirilabilir = sum(1 for c in sonuc if c.isprintable())
  • oran = yazdirilabilir / len(sonuc)
  • gecerli = oran > 0.9
  • if yontem == "ROT13":
  • # ROT13 sadece harfleri kaydırır; rakam/'=' gibi karakterler değişmeden
  • # kalır. Girdide bunlardan çoksa (örn. Base64), sonuç muhtemelen anlamsızdır.
  • harf_orani = sum(1 for c in sonuc if c.isalpha()) / len(sonuc)
  • gecerli = gecerli and harf_orani > 0.75
  • if gecerli:
  • print(f"[{Renk.YESIL}{yontem}{Renk.RESET}] -> {sonuc}")
  • bulundu = True
  • if not bulundu:
  • hata("Hiçbir yöntemle anlamlı bir çözüm bulunamadı.")
  • uyari("Not: Veri birden fazla katman encode edilmiş olabilir (örn. Base64 -> Hex).")
  • print(" Çözülen sonucu tekrar bu menüye yapıştırarak bir sonraki katmanı deneyebilirsin.")
  • def encode_decode_menusu():
  • while True:
  • temizle()
  • kutu_menu("ENCODE / DECODE ARACI", [
  • (1, "Base64 Encode"), (2, "Base64 Decode"),
  • (3, "Base32 Encode"), (4, "Base32 Decode"),
  • (5, "Hex Encode"), (6, "Hex Decode"),
  • (7, "URL Encode"), (8, "URL Decode"),
  • (9, "ROT13 (Encode/Decode aynı işlem)"),
  • (10, "Otomatik Decode Dene (Üst Üste Base64 Dahil, Hepsini Test Et)"),
  • (0, "Geri Dön"),
  • ])
  • secim = input("\nSeçiminiz: ")
  • if secim == "0":
  • return
  • if secim not in [str(i) for i in range(1, 11)]:
  • hata("Geçersiz seçim!")
  • devam_et()
  • continue
  • veri = input("\nİşlenecek metin: ").strip()
  • if not veri:
  • hata("Boş metin girilemez!")
  • devam_et()
  • continue
  • print()
  • try:
  • if secim == "1":
  • basari(f"Sonuç: {base64.b64encode(veri.encode()).decode()}")
  • elif secim == "2":
  • sonuc = _base64_decode_dene(veri)
  • basari(f"Sonuç: {sonuc}") if sonuc else hata("Geçerli bir Base64 verisi değil.")
  • elif secim == "3":
  • basari(f"Sonuç: {base64.b32encode(veri.encode()).decode()}")
  • elif secim == "4":
  • sonuc = _base32_decode_dene(veri)
  • basari(f"Sonuç: {sonuc}") if sonuc else hata("Geçerli bir Base32 verisi değil.")
  • elif secim == "5":
  • basari(f"Sonuç: {veri.encode().hex()}")
  • elif secim == "6":
  • sonuc = _hex_decode_dene(veri)
  • basari(f"Sonuç: {sonuc}") if sonuc else hata("Geçerli bir hex verisi değil.")
  • elif secim == "7":
  • basari(f"Sonuç: {urllib.parse.quote(veri)}")
  • elif secim == "8":
  • basari(f"Sonuç: {urllib.parse.unquote(veri)}")
  • elif secim == "9":
  • basari(f"Sonuç: {codecs.decode(veri, 'rot_13')}")
  • elif secim == "10":
  • otomatik_decode_dene(veri)
  • except (binascii.Error, ValueError, UnicodeDecodeError) as e:
  • hata(f"Dönüştürme hatası: {e}")
  • devam_et()
  • # =====================================================================
  • # YENİ EKLEME: HASH TANIMA MODÜLÜ
  • # =====================================================================
  • # (uzunluk_hex_karakter, olası hash türleri) - en yaygın hash uzunlukları
  • HASH_UZUNLUKLARI = {
  • 32: ["MD5", "NTLM", "MD4"],
  • 40: ["SHA1", "MySQL5"],
  • 56: ["SHA224"],
  • 64: ["SHA256", "SHA3-256"],
  • 96: ["SHA384"],
  • 128: ["SHA512", "SHA3-512"],
  • }
  • def hash_tanima_dene(deger):
  • deger = deger.strip()
  • sonuclar = []
  • if re.fullmatch(r"\$2[aby]\$.+", deger):
  • sonuclar.append("bcrypt")
  • elif re.fullmatch(r"\$1\$.+", deger):
  • sonuclar.append("MD5 Crypt (Unix)")
  • elif re.fullmatch(r"\$6\$.+", deger):
  • sonuclar.append("SHA512 Crypt (Unix)")
  • elif re.fullmatch(r"[a-fA-F0-9]+", deger):
  • olasilar = HASH_UZUNLUKLARI.get(len(deger))
  • if olasilar:
  • sonuclar.extend(olasilar)
  • return sonuclar
  • def hash_kirma_komutu_uret(hash_turu, hash_degeri):
  • """Kırma işlemini kendisi yapmaz — hazır bir hashcat/john komutu üretir."""
  • hashcat_modlari = {
  • "MD5": "0",
  • "SHA1": "100",
  • "SHA256": "1400",
  • "SHA512": "1700",
  • "NTLM": "1000",
  • "bcrypt": "3200",
  • "MD5 Crypt (Unix)": "500",
  • "SHA512 Crypt (Unix)": "1800",
  • }
  • mod = hashcat_modlari.get(hash_turu)
  • print()
  • bilgi(f"{hash_turu} için örnek komutlar:")
  • if mod:
  • print(f" hashcat -m {mod} -a 0 '{hash_degeri}' wordlist.txt")
  • print(f" john --format=raw-{hash_turu.lower().split()[0]} --wordlist=wordlist.txt hash.txt")
  • uyari("Bu komutlar sadece hazırlanır, kırma işlemi wordlist boyutuna göre uzun sürebilir.")
  • def hash_menusu():
  • temizle()
  • baslik_kutusu("HASH TANIMA ARACI")
  • uyari("Bu araç hash'i KIRMAZ, sadece türünü tahmin edip komut önerir.\n")
  • deger = input("Tanınacak hash değeri: ").strip()
  • if not deger:
  • hata("Boş değer girilemez!")
  • devam_et()
  • return
  • olasilar = hash_tanima_dene(deger)
  • if not olasilar:
  • print()
  • hata("Bilinen bir hash formatına uymuyor.")
  • uyari("Uzunluk veya format tanınamadı — özel/az bilinen bir algoritma olabilir.")
  • else:
  • print()
  • basari(f"Olası hash türü/türleri ({len(deger)} karakter):")
  • for tur in olasilar:
  • print(f" {Renk.MAVI}-{Renk.RESET} {tur}")
  • if len(olasilar) == 1:
  • komut_uret = input("\nKırma komutu önerisi görmek ister misin? (e/h): ").strip().lower()
  • if komut_uret == "e":
  • hash_kirma_komutu_uret(olasilar[0], deger)
  • else:
  • print()
  • uyari("Birden fazla olasılık var, kesin tür bilgisi olmadan komut üretmiyorum.")
  • devam_et()
  • # =====================================================================
  • # YENİ EKLEME: GOOGLE DORK ARACI
  • # =====================================================================
  • # Her şablon: (açıklama, dork formatı - {site} hedef domain ile değiştirilir)
  • DORK_SABLONLARI = {
  • "1": ("Açık dizin listeleme (index of)", 'site:{site} intitle:"index of"'),
  • "2": ("Login / admin panel arama", 'site:{site} (inurl:login OR inurl:admin OR inurl:panel)'),
  • "3": ("Hassas dosya türleri (env, sql, config, log)",
  • 'site:{site} (filetype:env OR filetype:sql OR filetype:log OR filetype:config OR filetype:bak)'),
  • "4": ("SQL / veritabanı hata mesajları", 'site:{site} intext:"sql syntax" OR intext:"mysql_fetch" OR intext:"ORA-01756"'),
  • "5": ("Erişilebilir yönetim/backup dosyaları", 'site:{site} (inurl:backup OR inurl:.git OR inurl:.env)'),
  • "6": ("PDF / Word / Excel belgeleri", 'site:{site} (filetype:pdf OR filetype:docx OR filetype:xlsx)'),
  • "7": ("robots.txt ile gizlenmiş yollar", 'site:{site} inurl:robots.txt'),
  • }
  • # KRİTİK: doğrudan kimlik bilgisi / gizli anahtar / hassas veri sızıntısı hedefleyen yüksek riskli sorgular.
  • # Her değer sadece sorgunun GÖVDESİdir ("site:{site}" kısmı kullanım anında otomatik eklenir),
  • # böylece hepsi tek bir birleşik payload'da da OR'lanarak kullanılabilir.
  • DORK_KRITIK_SABLONLARI = {
  • "1": ("Açığa çıkmış API anahtarı / secret (js, json, env dosyalarında)",
  • '(filetype:js OR filetype:json OR filetype:env OR filetype:yml) '
  • '(intext:"api_key" OR intext:"apikey" OR intext:"secret_key" OR intext:"aws_access_key_id" OR intext:"authorization: bearer")'),
  • "2": (".env dosyasında veritabanı/mail şifresi",
  • 'filetype:env (intext:"DB_PASSWORD" OR intext:"MAIL_PASSWORD" OR intext:"SECRET_KEY")'),
  • "3": ("Veritabanı dump / SQL yedek dosyası sızıntısı",
  • '(filetype:sql OR filetype:dump OR filetype:db) (intext:"INSERT INTO" OR intext:"password")'),
  • "4": ("Açığa çıkmış .git deposu / commit içinde kimlik bilgisi",
  • 'inurl:".git" (intext:"password" OR intext:"credentials" OR intext:"config")'),
  • "5": ("WordPress wp-config.php şifre sızıntısı",
  • 'inurl:"wp-config.php" intext:"DB_PASSWORD"'),
  • "6": ("Açık Jenkins / CI-CD yönetim paneli",
  • '(inurl:"/jenkins" OR intitle:"Dashboard [Jenkins]")'),
  • "7": ("Açık phpinfo() sayfası (sunucu/ortam değişkeni sızıntısı)",
  • 'intitle:"phpinfo()" "PHP Version"'),
  • "8": ("Açık Elasticsearch / Kibana / MongoDB paneli",
  • '(intitle:"Kibana" OR inurl:"_search?q=" OR inurl:":9200" OR inurl:":27017")'),
  • "9": ("Açık S3 bucket / bulut depolama listelemesi",
  • '(inurl:"s3.amazonaws.com" OR inurl:"storage.googleapis.com") intitle:"index of"'),
  • "10": ("Kimlik bilgisi içeren log / txt dosyaları",
  • '(filetype:txt OR filetype:log) (intext:"username" AND intext:"password")'),
  • "11": ("Açık Swagger / API dokümantasyonu (endpoint keşfi)",
  • '(inurl:"swagger-ui.html" OR inurl:"api-docs" OR inurl:"v2/api-docs")'),
  • }
  • def _dork_sablon_sec(site, sablonlar, baslik):
  • """Verilen şablon sözlüğünden kullanıcıya seçim yaptırır, (açıklama, sorgu) döner; iptal/geçersizse (None, None)."""
  • temizle()
  • bilgi(f"Hedef: {site}\n")
  • secenekler = [(anahtar, aciklama) for anahtar, (aciklama, _) in sablonlar.items()]
  • secenekler.append(("0", "Geri Dön"))
  • kutu_menu(f"GOOGLE DORK - {baslik}", secenekler)
  • secim = input("\nSeçiminiz: ").strip()
  • if secim == "0" or secim not in sablonlar:
  • if secim != "0":
  • hata("Geçersiz seçim!")
  • devam_et()
  • return None, None
  • aciklama, sablon = sablonlar[secim]
  • return aciklama, sablon.format(site=site)
  • def _dork_sonucu_isle(aciklama, sorgu):
  • google_url = "https://www.google.com/search?q=" + urllib.parse.quote(sorgu)
  • print()
  • bilgi(f"Kategori: {aciklama}")
  • basari(f"Oluşturulan dork (payload): {sorgu}")
  • basari(f"Google URL: {google_url}")
  • ac = input("\nBu sorguyu varsayılan tarayıcında açmak ister misin? (e/h): ").strip().lower()
  • if ac == "e":
  • try:
  • webbrowser.open(google_url)
  • basari("Tarayıcıda açıldı.")
  • except Exception as e:
  • hata(f"Tarayıcı açılırken hata oluştu: {e}")
  • kaydet = input("Bu sorguyu bir dosyaya kaydetmek ister misin? (e/h): ").strip().lower()
  • if kaydet == "e":
  • dosya_adi = input("Dosya adı (Varsayılan: dorklar.txt): ").strip() or "dorklar.txt"
  • try:
  • with open(dosya_adi, "a", encoding="utf-8") as f:
  • f.write(f"[{aciklama}] {sorgu}\n")
  • basari(f"'{dosya_adi}' dosyasına eklendi.")
  • except OSError as e:
  • hata(f"Dosyaya yazılırken hata oluştu: {e}")
  • devam_et()
  • def _kritik_birlesik_payload_uret(site):
  • """Tüm kritik dork gövdelerini tek bir OR'lu payload'da birleştirir."""
  • govdeler = [govde for _, govde in DORK_KRITIK_SABLONLARI.values()]
  • return f"site:{site} (" + " OR ".join(f"({govde})" for govde in govdeler) + ")"
  • def kritik_dork_menusu(site):
  • temizle()
  • bilgi(f"Hedef: {site}")
  • uyari("Bu sorgular kimlik bilgisi / API anahtarı / açık panel gibi doğrudan hassas")
  • uyari("veri sızıntısı arar. Sadece YETKİLİ olduğun hedeflerde kullan; bulunan")
  • uyari("veriyi izinsiz kullanmak/yaymak suçtur.\n")
  • secenekler = [("0", "TÜMÜNÜ TEK PAYLOAD'DA BİRLEŞTİR (hepsi bir arada, tek arama)")]
  • secenekler += [(anahtar, aciklama) for anahtar, (aciklama, _) in DORK_KRITIK_SABLONLARI.items()]
  • geri_no = str(len(DORK_KRITIK_SABLONLARI) + 1)
  • secenekler.append((geri_no, "Geri Dön"))
  • kutu_menu("GOOGLE DORK - KRİTİK / YÜKSEK RİSK", secenekler)
  • secim = input("\nSeçiminiz: ").strip()
  • if secim == geri_no:
  • return
  • if secim == "0":
  • aciklama = "KRİTİK - Tüm sızıntı türleri (birleşik payload)"
  • sorgu = _kritik_birlesik_payload_uret(site)
  • elif secim in DORK_KRITIK_SABLONLARI:
  • aciklama, govde = DORK_KRITIK_SABLONLARI[secim]
  • sorgu = f"site:{site} {govde}"
  • else:
  • hata("Geçersiz seçim!")
  • devam_et()
  • return
  • _dork_sonucu_isle(aciklama, sorgu)
  • def google_dork_menusu():
  • temizle()
  • baslik_kutusu("GOOGLE DORK ARACI")
  • uyari("Bu araç Google'a otomatik istek atmaz (ToS ihlali ve IP ban riski olur).")
  • uyari("Sadece doğru dork sorgusunu senin için oluşturur, sonucu sen tarayıcında görürsün.\n")
  • site = input("Hedef site/domain (Örn: example.com): ").strip()
  • if not site:
  • hata("Hata: Site boş bırakılamaz!")
  • devam_et()
  • return
  • # Kullanıcı yanlışlıkla http:// veya www. eklerse temizle
  • site = re.sub(r"^https?://", "", site).strip("/").removeprefix("www.")
  • temizle()
  • bilgi(f"Hedef: {site}")
  • kutu_menu("GOOGLE DORK ARACI", [
  • (1, "Genel Dorklar (index, login, dosya türleri vb.)"),
  • (2, "KRİTİK Dorklar (API key, .env, git leak, db dump, açık panel vb.)"),
  • (3, "Özel dork yaz (kendi sorgunu gir)"),
  • (0, "Geri Dön"),
  • ])
  • secim = input("\nSeçiminiz: ").strip()
  • if secim == "0":
  • return
  • if secim == "1":
  • aciklama, sorgu = _dork_sablon_sec(site, DORK_SABLONLARI, "GENEL")
  • if aciklama is None:
  • return
  • elif secim == "2":
  • kritik_dork_menusu(site)
  • return
  • elif secim == "3":
  • ozel_dork = input("Dork sorgunu gir (site: otomatik eklenmez, istersen ekle): ").strip()
  • if not ozel_dork:
  • hata("Hata: Dork boş bırakılamaz!")
  • devam_et()
  • return
  • sorgu = ozel_dork
  • aciklama = "Özel dork"
  • else:
  • hata("Geçersiz seçim!")
  • devam_et()
  • return
  • _dork_sonucu_isle(aciklama, sorgu)
  • def ssh_baglanti_menusu():
  • temizle()
  • baslik_kutusu("SSH BAĞLANTI ARACI")
  • kullanici = input("Kullanıcı Adı (Örn: rock, root): ").strip()
  • ip_adresi = input("Hedef IP Adresi (Örn: 172.20.5.141): ").strip()
  • if not kullanici or not ip_adresi:
  • hata("Hata: Kullanıcı adı ve IP boş bırakılamaz!")
  • devam_et()
  • return
  • print()
  • basari(f"{kullanici}@{ip_adresi} adresine SSH bağlantısı başlatılıyor...")
  • uyari("İlk kez bağlanıyorsanız 'yes' yazıp onaylamanız gerekebilir.")
  • uyari("Bağlantı sağlandığında hedef makinenin şifresini girin.\n")
  • try:
  • subprocess.run(["ssh", f"{kullanici}@{ip_adresi}"], check=True)
  • except FileNotFoundError:
  • hata("Hata: Sistemde 'ssh' istemcisi kurulu görünmüyor.")
  • except subprocess.CalledProcessError:
  • hata("Hata: SSH bağlantısı sonlandırıldı veya bir hata oluştu (Yanlış şifre / Ağ hatası).")
  • except KeyboardInterrupt:
  • hata("İşlem kullanıcı tarafından iptal edildi.")
  • devam_et("\nAna menüye dönmek için Enter'a basın...")
  • # =====================================================================
  • # YENİ EKLEME: KİŞİYE ÖZEL WORDLIST ÜRETİCİ (CUPP TARZI)
  • # =====================================================================
  • LEET_HARITASI = {
  • "a": ["4", "@"],
  • "e": ["3"],
  • "i": ["1", "!"],
  • "o": ["0"],
  • "s": ["5", "$"],
  • "t": ["7"],
  • }
  • YAYGIN_EKLER = ["", "1", "12", "123", "1234", "!", "!!", "007", "01", "02", "99"]
  • AY_ISIMLERI = {
  • 1: "Ocak", 2: "Şubat", 3: "Mart", 4: "Nisan", 5: "Mayıs", 6: "Haziran",
  • 7: "Temmuz", 8: "Ağustos", 9: "Eylül", 10: "Ekim", 11: "Kasım", 12: "Aralık",
  • }
  • _TR_ASCII_TABLOSU = str.maketrans("çÇğĞıİöÖşŞüÜ", "cCgGiIoOsSuU")
  • def _ay_adi_varyasyonlari(ay_no):
  • """Ay numarasından Türkçe ay adının farklı yazım (Türkçe/ASCII, büyük/küçük) varyasyonlarını üretir."""
  • isim = AY_ISIMLERI.get(ay_no)
  • if not isim:
  • return []
  • ascii_isim = isim.translate(_TR_ASCII_TABLOSU)
  • varyantlar = {isim, isim.lower(), isim.upper(), ascii_isim, ascii_isim.lower(), ascii_isim.upper()}
  • return list(varyantlar)
  • def _leet_varyasyonlari_uret(kelime, maks=6):
  • """Kelimenin harf->rakam (leet) karışımlarını üretir; patlamayı önlemek için sınırlı sayıda döner."""
  • varyasyonlar = {kelime}
  • for harf, yerine_gecenler in LEET_HARITASI.items():
  • if harf not in kelime.lower():
  • continue
  • yeni_varyasyonlar = set()
  • for mevcut in varyasyonlar:
  • for yerine in yerine_gecenler:
  • yeni_varyasyonlar.add(re.sub(harf, yerine, mevcut, flags=re.IGNORECASE))
  • varyasyonlar |= yeni_varyasyonlar
  • if len(varyasyonlar) >= maks:
  • break
  • return list(varyasyonlar)[:maks]
  • def _kelime_varyasyonlari_uret(kelime):
  • """Bir kelimeden büyük/küçük harf ve leet varyasyonlarının kümesini üretir."""
  • if not kelime:
  • return []
  • temel = {kelime, kelime.lower(), kelime.upper(), kelime.capitalize()}
  • tum_varyasyonlar = set(temel)
  • for k in temel:
  • tum_varyasyonlar |= set(_leet_varyasyonlari_uret(k))
  • return list(tum_varyasyonlar)
  • def wordlist_bilgi_topla():
  • print("[!] Bilgi girmek istemediğin alanları boş bırakıp Enter'a basabilirsin.\n")
  • alanlar = {
  • "isim": input("İsim: ").strip(),
  • "soyisim": input("Soyisim: ").strip(),
  • "lakap": input("Lakap / Takma ad: ").strip(),
  • "dogum_gunu": input("Doğum günü (1-31, örn: 15): ").strip(),
  • "dogum_ayi": input("Doğum ayı (1-12, örn: 5 -> Mayıs): ").strip(),
  • "dogum_yili": input("Doğum yılı (Örn: 1998): ").strip(),
  • "esi_sevgilisi": input("Eş/Sevgili adı: ").strip(),
  • "cocuk_adi": input("Çocuk adı: ").strip(),
  • "evcil_hayvan": input("Evcil hayvan adı: ").strip(),
  • "sirket_takim": input("Şirket / Takım / Okul adı: ").strip(),
  • "ozel_kelime": input("Özel kelime (favori şey, şehir vb.): ").strip(),
  • "ozel_sayi": input("Özel sayı (telefon son 4 hane, plaka vb.): ").strip(),
  • }
  • return {k: v for k, v in alanlar.items() if v}
  • def wordlist_uret(bilgiler, maks_boyut=50000):
  • isim_alanlari = [
  • "isim", "soyisim", "lakap", "esi_sevgilisi", "cocuk_adi",
  • "evcil_hayvan", "sirket_takim", "ozel_kelime",
  • ]
  • temel_kelimeler = {bilgiler[alan] for alan in isim_alanlari if bilgiler.get(alan)}
  • sayilar = {bilgiler[alan] for alan in ("dogum_yili", "ozel_sayi") if bilgiler.get(alan)}
  • sayilar.add(str(date.today().year))
  • gun = bilgiler.get("dogum_gunu", "")
  • ay = bilgiler.get("dogum_ayi", "")
  • yil = bilgiler.get("dogum_yili", "")
  • if gun.isdigit() and ay.isdigit():
  • gun2, ay2 = gun.zfill(2), ay.zfill(2)
  • sayilar |= {f"{gun2}{ay2}", f"{ay2}{gun2}", f"{gun}{ay}", f"{ay}{gun}"}
  • if ay.isdigit():
  • ay_adlari = _ay_adi_varyasyonlari(int(ay))
  • sayilar |= set(ay_adlari)
  • for ay_adi in ay_adlari:
  • if gun:
  • sayilar.add(f"{gun}{ay_adi}")
  • sayilar.add(f"{ay_adi}{gun}")
  • if yil:
  • sayilar.add(f"{ay_adi}{yil}")
  • sayilar.add(f"{yil}{ay_adi}")
  • kelime_havuzu = set()
  • for kelime in temel_kelimeler:
  • kelime_havuzu |= set(_kelime_varyasyonlari_uret(kelime))
  • sonuc = set()
  • for kelime in kelime_havuzu:
  • for ek in YAYGIN_EKLER:
  • sonuc.add(f"{kelime}{ek}")
  • for sayi in sayilar:
  • sonuc.add(f"{kelime}{sayi}")
  • sonuc.add(f"{sayi}{kelime}")
  • # Tarih/ay kombinasyonlarının kendisi de tek başına listeye girsin (örn. "Mayıs1998")
  • sonuc |= sayilar
  • temel_liste = list(temel_kelimeler)
  • for i, k1 in enumerate(temel_liste):
  • for k2 in temel_liste[i + 1:]:
  • for varyant in (f"{k1}{k2}", f"{k2}{k1}"):
  • sonuc.add(varyant)
  • for sayi in sayilar:
  • sonuc.add(f"{varyant}{sayi}")
  • if len(sonuc) > maks_boyut:
  • sonuc = set(list(sonuc)[:maks_boyut])
  • return sorted(sonuc, key=len)
  • def wordlist_uretici_menusu():
  • temizle()
  • baslik_kutusu("KİŞİYE ÖZEL WORDLIST ÜRETİCİ (CUPP Tarzı)")
  • uyari("Bu araç sadece YETKİLİ pentest/CTF senaryoları için kişiye özel")
  • uyari("şifre tahmin listesi üretir. Başkasının hesabına izinsiz erişim")
  • uyari("denemek suçtur — yalnızca kendi/izinli sistemlerinde kullan.\n")
  • bilgiler = wordlist_bilgi_topla()
  • if not bilgiler:
  • print()
  • hata("Hiç bilgi girilmedi, üretilecek bir şey yok.")
  • devam_et()
  • return
  • print()
  • bilgi("Wordlist üretiliyor...")
  • kelimeler = wordlist_uret(bilgiler)
  • basari(f"Toplam {len(kelimeler)} benzersiz şifre adayı üretildi.")
  • dosya_adi = (
  • input("\nKaydedilecek dosya adı (Varsayılan: ozel_wordlist.txt): ").strip()
  • or "ozel_wordlist.txt"
  • )
  • try:
  • with open(dosya_adi, "w", encoding="utf-8") as f:
  • for kelime in kelimeler:
  • f.write(kelime + "\n")
  • basari(f"'{dosya_adi}' dosyasına kaydedildi. Dizin tarama veya hashcat/john ile kullanabilirsin.")
  • except OSError as e:
  • hata(f"Dosya kaydedilirken hata oluştu: {e}")
  • devam_et("\nAna menüye dönmek için Enter'a basın...")
  • # =====================================================================
  • # ANA PROGRAM DÖNGÜSÜ
  • # =====================================================================
  • def ana_menu():
  • _windows_ansi_etkinlestir()
  • while True:
  • temizle()
  • banner_yazdir()
  • kutu_menu("ANA MENÜ", [
  • (1, "Nmap ile Port Taraması"),
  • (2, "Web Dizin Taraması (Directory Buster)"),
  • (3, "Zip Arşiv Çözücü (Normal / İç İçe)"),
  • (4, "OpenVPN Başlatıcı"),
  • (5, "Kelime Arama Aracı (Klasör / Dosya)"),
  • (6, "SSH Bağlantı Aracı"),
  • (7, "Encode / Decode Aracı"),
  • (8, "Hash Tanıma Aracı"),
  • (9, "Google Dork Aracı"),
  • (10, "Kişiye Özel Wordlist Üretici"),
  • (0, "Çıkış"),
  • ])
  • secim = input(f"\n{Renk.BOLD}Hangi işlemi yapmak istersiniz?:{Renk.RESET} ")
  • if secim == "1":
  • nmap_menusu()
  • elif secim == "2":
  • dizin_tarama_menusu()
  • elif secim == "3":
  • zip_menusu()
  • elif secim == "4":
  • vpn_baslatici_menusu()
  • elif secim == "5":
  • kelime_arama_menusu()
  • elif secim == "6":
  • ssh_baglanti_menusu()
  • elif secim == "7":
  • encode_decode_menusu()
  • elif secim == "8":
  • hash_menusu()
  • elif secim == "9":
  • google_dork_menusu()
  • elif secim == "10":
  • wordlist_uretici_menusu()
  • elif secim == "0":
  • print()
  • basari("Programdan çıkılıyor. Güvenli günler!")
  • sys.exit()
  • else:
  • hata("Geçersiz bir seçim yaptınız!")
  • devam_et()
  • if __name__ == "__main__":
  • ana_menu()