Kaynak Kod
arac.py — Siber Güvenlik / CTF Araç Seti
- 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()