🦅 gokdogan
Statik PE Malware Triyaj Motoru
İçindekiler
- gokdogan’ın Anatomisi
- Neden “triyaj”?
- Tek bakışta gokdogan
- Tasarım ilkeleri
- Mimari ve pipeline
- 31 modül, beş katman
- Kimlik & kümeleme
- Yapı
- İçerik
- Davranış
- İstihbarat
- Karar modeli
- Raporlama ve çıktılar
- Mühendislik detayları
- Yanlış pozitifi kalibrasyonla yok etmek
- Anahtar-değişmez komşuluk araması
- İmzalı-enjektör maskesi: bir denge
- Çevrimdışı çekirdek, opt-in egress
- Windows’a özgü zorluklar
- Test stratejisi
- Kurulum ve kullanım
- Sınırlar ve kapanış
gokdogan’ın Anatomisi
Bir Windows çalıştırılabilirini hiç çalıştırmadan analiz eden, şeffaf ve gerekçeli bir triyaj kararı üreten bir motor. Bu sayfa; mimarisini, 31 modülünü, karar modelini ve arkasındaki mühendislik kararlarını baştan sona anlatır.

01 · Problem
Neden “triyaj”?
Bir malware analistinin masasına günde yüzlerce, bazen binlerce örnek düşer. Her birini tersine mühendislikle, dinamik analizle incelemek imkânsızdır. İhtiyaç duyulan şey önceliklendirme: “Bu örneğe önce mi bakmalıyım?” sorusuna saniyeler içinde, güvenilir bir cevap.
gokdogan bir Windows PE dosyası alır, onu çalıştırmadan statik özelliklerini çıkarır ve şeffaf, gerekçeli bir karar üretir: LIKELY_CLEAN, SUSPICIOUS veya HIGH_RISK.
İsim, Türkçede peregrine falcon (gök doğanı) anlamına gelir — gökyüzünün en hızlı avcısı. Triyaj da hız işidir. (Paket, komut ve repo her yerde ASCII gokdogan’dır; çünkü ö/ğ Python paket adlarını ve URL’leri bozar.)
02 · Özet
Tek bakışta gokdogan
- Ne yapar — Statik PE malware triyajı; örneği asla çalıştırmaz
- Kod — ~4.500 satır Python · 31 modül · 173 test
- Sabit bağımlılık —
pefile·ppdeep(saf-Python ssdeep) - Opsiyonel —
yara-python·py-tlsh - Karar — LIKELY_CLEAN / SUSPICIOUS / HIGH_RISK (eşik 30 / 60)
- Çıkış kodları —
0temiz ·2şüpheli ·3yüksek risk - Çıktılar — konsol · JSON · HTML · CSV/JSONL · ATT&CK Navigator · MISP
- Kurulum —
pip install gokdogan-triage
03 · İlkeler
Tasarım ilkeleri
Motorun tamamı, onu bir analist için doğru ve güvenilir kılan beş karar etrafında örgütlenir:
- Saf fonksiyonlar → dataclass’lar — Her analizör,
bytes/PEalıp dataclass döndüren saf bir fonksiyondur. Yeni aşama = bir modül +engine.py’de bir satır. - Varsayılan çevrimdışı —
triage()çekirdeği asla ağa dokunmaz, örneği asla çalıştırmaz. Tek ağ özelliği (itibar) opt-in ve hash-only. - Denetlenebilir karar — Skor raporun kendisidir: her puanın insan-okur bir gerekçesi var. Gizli model yok.
- FP’ye karşı kalibre — Eşikler tahminle değil, stok imzalı Windows ikililerine karşı ölçülerek ayarlandı.
- Zarif çökme — Eksik YARA, bozuk kaynak ağacı, çözülemeyen import — her biri raporda bir nota dönüşür, çökmeye değil.
04 · Mimari
Mimari ve pipeline
Motor tek bir orkestratör fonksiyonun etrafında döner: engine.triage(). Her aşama, paylaşılan bir TriageReport yapısının tek bir dilimini doldurur; reporter’lar ve karar motoru yalnızca bu yapıyı okur. Böylece analiz ve sunum tümüyle ayrıktır — yeni bir yetenek eklemek, mevcut hiçbir şeyi bozmadan bir modül + bir satır yazmaktır.

05 · Analiz yüzeyi
31 modül, beş katman

Kimlik & kümeleme
loader (PE parse, MD5/SHA1/SHA256, imphash, yapısal anomaliler, delay-load import’lar), rich (Rich header hash + checksum doğrulaması), fuzzy (ssdeep + opsiyonel TLSH; --compare), hashes (authentihash + impfuzzy), cluster (--cluster union-find), baseline (--baseline diff).
Yapı
entropy (bölüm + genel Shannon entropisi), packers (bilinen adlar + sezgiseller), blobs (yazılabilir bölümlerdeki entropi adaları → embedded-config), resources (.rsrc yürüyücüsü, gömülü PE + PNG ikon beyaz listesi), overlay, signature (Authenticode / WinVerifyTrust, çevrimdışı — geçerli imzayı kurcalanmıştan ayırır), dotnet (.NET CLR + obfuscator parmak izleri).
İçerik
strings_ext (ASCII/UTF-16 + IOC sınıflandırma), decoded (FLOSS-lite: XOR/ADD/ROL + Base64/hex kurtarma), stackstrings (desen tabanlı x86 stack-string, emülatörsüz), extractors (Discord/Telegram/stager aile config’i).
Davranış
exports (başlatma-mekanizması export’ları: ReflectiveLoader, DllRegisterServer, ServiceMain), capabilities (import + delay-import + export → davranış etiketleri; her kural minimum sayıda farklı API isabeti ister — yanlış pozitife karşı).
İstihbarat
attack (yetenekler/YARA → MITRE ATT&CK, taktiğe göre gruplu; Navigator layer export), yara_scan (opsiyonel; meta.weight doğrudan skoru besler), reputation (opt-in VirusTotal / MalwareBazaar hash-only sorgusu).
06 · Karar
Karar modeli
Puanlama kasıtlı olarak şeffaf ve toplamsaldır. Her sinyal bir puan ekler ve raporda o puanın gerekçesi yazılır — YARA kuralları kendi ağırlıklarını enjekte ederek sezgisellere üstün gelebilir.

Örnek bir gerekçe dökümü (demo örneği):
── Verdict ───────────────────────────────────────────────
+ 6 anomaly: PE header checksum does not match computed checksum
+ 18 capability: anti-recovery
+ 18 capability: persistence-registry
+ 30 YARA match: Shadow_Copy_Deletion
+ 15 YARA match: Injection_API_Cluster
+ 16 2 encoded IOC/payload string(s) recovered
+ 15 extracted config: Discord webhook
...
HIGH RISK (score 140, thresholds: suspicious ≥ 30, high risk ≥ 60)
Nüans: geçerli bir Authenticode imzası (−15) ciddi (sev-3) bir yeteneği maskeleyemez — o durumda karar SUSPICIOUS eşiğinin altına inemez (taban). Bu, imzalı-enjektör maskesini kırar ama kernel32’ü yanlış pozitif yapmaz.
07 · Raporlama
Raporlama ve çıktılar
Tek motor, birçok çıktı — terminal triyaj için, HTML vaka dosyası için, CSV dropzone için, JSON pipeline için, MISP paylaşımı için. HTML rapor tek dosyadır, gömülü CSS’lidir ve hiç dış istek yapmaz.

Aracın kendi güvenliği: malware string’leri markup içerebilir. HTML rapor her örnek-türevi değeri html.escape’ten geçirir — bir raporu açmak gömülü bir <script>’i asla çalıştıramaz (testle doğrulandı).
08 · Derin dalışlar
Mühendislik detayları
Yanlış pozitifi kalibrasyonla yok etmek
Bir triyaj aracını işe yaramaz yapan şey, temiz dosyaya kurt demesidir. Şifreli-config tespiti 150 stok imzalı sistem ikilisine karşı süpürüldü. İki ders: (1) 256 baytlık pencere entropi ölçmek için fazla küçük — gerçekten rastgele veri bile orada ortalama ~7.17 bit/byte verir (küçük örneklem yanlılığı), eşik sessizce ulaşılamazdı → 512 bayt pencere, 7.4 eşik. (2) Salt-okunur .rdata sertifika verisiyle meşru yüksek entropi taşır → tarama yalnızca yazılabilir bölümlerle sınırlandı → 0 yanlış pozitif.
Anahtar-değişmez komşuluk araması
Naif yaklaşım (255 anahtar × çıpa × tüm dosya) 800 KB’lık bir DLL’de ~2.440 ms sürüyordu. İçgörü: tek-baytlık XOR/ADD altında encoded[i] ⊕ encoded[i-1] anahtardan bağımsızdır.
plaintext[i] ⊕ plaintext[i-1] == encoded[i] ⊕ encoded[i-1]
Tamponu bir kez “komşuluk dönüşümü”nden geçir (koca bir tamsayı kaydırmasıyla, C hızında), sonra anahtar bulmak her çıpa için tek bir alt-dize aramasına dönüşür — 2.440 ms → 133 ms, tam kapsama korunarak.
İmzalı-enjektör maskesi: bir denge
Geçerli bir imza güven verir (−15). Ama CreateRemoteThread + VirtualAllocEx + WriteProcessMemory üçlüsü olan, geçerli imzalı (çalınmış sertifika) bir enjektör bu krediyle temiz görünebiliyordu. İlk çözümüm (krediyi kısmak) kernel32’ü FP yaptı. Oturan denge: kredi düz −15 kalır, ama sev-3 yetenek varken imza kararı SUSPICIOUS eşiğinin altına itemez (taban). Ders: güvenlikte çoğu karar bir dengedir; “doğru” cevap iki uç senaryoyu da bozmayandır.
Çevrimdışı çekirdek, opt-in egress
İtibar tek ağ özelliğidir. Varsayılan kapalıdır, yalnızca SHA-256 gönderir (dosyayı asla), anahtar olmadan çalışmayı reddeder ve CLI katmanında iliştirilir — böylece triage() motoru kanıtlanabilir biçimde çevrimdışı kalır. Opsiyonel web servisi gövdeyi parça parça okur ve 64 MB sınır koyar (aşımda HTTP 413).
09 · Platform
Windows’a özgü zorluklar
- ASCII olmayan yollar.
yara-python, C tarafında “Masaüstü” gibi yolları sindiremiyordu → kuralları dosya yolu yerine içerik (sources=) olarak derledim. - PyInstaller sessiz modül düşürme. ASCII olmayan yol + editable kurulum bazı modülleri atlıyordu →
--paths .şart. - Legacy kod sayfası (cp1254). Kutu-çizim karakterleri dosyaya yönlendirilince
UnicodeEncodeErrorfırlatıyordu → çıktı akışını saran, gerektiğinde ASCII’ye çeviren bir katman. - 64-bit ctypes. Authenticode’da işaretçi döndüren
crypt32fonksiyonlarındarestypeayarlamayı unutursanız adresler kırpılır.
10 · Test
Test stratejisi
173 test / ~1.900 satır. Birim testleri her analizörü sentetik girdilerle izole eder (XOR/base64 payload’lar, sahte PE tamponları, ekilmiş entropi adaları). Entegrasyon süiti tüm pipeline’ı gerçek sistem ikililerine (notepad.exe, kernel32.dll, mmc.exe) karşı çalıştırır ve stok Microsoft ikililerinin asla HIGH_RISK çıkmadığını doğrular. Ağ kodu enjekte edilmiş HTTP mock’larıyla test edilir — gerçek dış çağrı yok.
11 · Kullanım
Kurulum ve kullanım
PyPI’dan:
# kur
pip install gokdogan-triage
# tek örnek için tam rapor
gokdogan sample.exe
# vaka dosyası için kendine yeten HTML
gokdogan sample.exe --html report.html
# bir dropzone'u tek sıralanabilir tabloya
gokdogan C:\dropzone --csv triage.csv
# aileye göre kümele / bilinen-iyi ile diff'le
gokdogan C:\dropzone --cluster
gokdogan suspect_svchost.exe --baseline C:\Windows\System32\svchost.exe
# opt-in itibar: yalnızca SHA-256 gönderir (dosyayı asla)
gokdogan sample.exe --reputation --vt-key $VT_API_KEY
Web servisi (tarayıcıdan yükle, HTML rapor al):
pip install "gokdogan-triage[web]"
uvicorn gokdogan.web:app --host 127.0.0.1 --port 8000
Python gerektirmeden: Releases sayfasından gokdogan-setup.exe (per-user kurucu) veya tek-dosya gokdogan.exe.
12 · Kapanış
Sınırlar ve kapanış
gokdogan yalnızca statik triyaj yapar. Örneği asla çalıştırmaz ve verdiği karar bir önceliklendirme sinyalidir, kesin bir sınıflandırma değil. Gerçek malware’i her zaman izole bir analiz VM’inde ele alın.
Bu proje bana “kod yazmak” ile “güvenilir bir araç yapmak” arasındaki farkı öğretti: asıl iş, temiz dosyaya yanlışlıkla kurt dememek; doğru soruyu sorup 2.440 ms’yi 133’e indirmek; ve “çalışan kod”u başkasının tek komutla kurabileceği bir şeye dönüştürmek.
gokdogan — açık kaynak (MIT). Geri bildirime ve önerilere açığım.
github.com/IlkerUnver00/gokdogan-triage · pip install gokdogan-triage · canlı mimari sayfası
⚠ Triaj, mahkûmiyet değil. Örnek asla çalıştırılmaz; karar bir önceliklendirme sinyalidir.