Files
2026-05-22 14:54:55 -03:00

19 KiB
Raw Permalink Blame History

StackSentry

English日本語PortugueseTürkçe

      Release



StackSentry basit bir fikirden çıktı: bir loader LoadLibrary çağrısının nereden geldiğini saklamaya çalışıyorsa, call stack büyük ihtimalle bir yerlerde iz bırakır.

Bu proje x64 user-mode çalışan bir araştırma aracıdır. Amacı memory triage, loader analizi ve hassas DLL-load tespitidir. Hedef process başlatılır, hafif bir monitor DLL enjekte edilir ve önemli olaylar canlı izlenir. Araç temelde tek soruya cevap arar: bu DLL load veya network kullanımını gerçekten kim tetikledi?

Important

Bu proje hâlâ geliştirme aşamasında. Bug, false positive ve false negative olabilir.
StackSentry esas olarak lab ortamında loader ve in-memory payload analizini kolaylaştırmak için geliştirildi.
Araç kernel driver kurmaz ve sistemde kalıcı değişiklik yapmaz; yine de sonuçları yardımcı araçlarla karşılaştırın ve output'u kesin hüküm değil, triage evidence olarak değerlendirin.

Fikir

StackSentry bellekte çalışan kodu hızlı şekilde triage etmeye odaklanır. Pratik mantık şu: bir C2, RAT veya fileless loader diskte dosya bırakmayabilir, uyurken kendini şifreleyebilir ve temiz görünen bir stack kurabilir; ama bir noktada yine network DLL yüklemek veya network API kullanmak zorundadır.

Windows tarafında bu genellikle ws2_32.dll, wininet.dll, winhttp.dll, dnsapi.dll veya bu modüllerin export ettiği API'ler anlamına gelir. Bu DLL'ler garip bir origin üzerinden yükleniyor veya kullanılıyorsa durup bakmaya değer.

Bu yaklaşım sıfırdan uydurulmuş bir fikir değil. Elastic'in davranışsal detection kurallarıyla da aynı eksene oturuyor:

Bu tarz detection'lar olduğu için bazı loader'lar artık düz LoadLibrary çağrısından kaçıyor. Callback, legitimate module içindeki gadget, threadpool chain, cross-thread dispatch, modified image execution veya unwind metadata manipulation gibi yöntemlerle origin'i saklamaya çalışıyorlar.

StackSentry bunu lab seviyesinde daha ileri taşımaya çalışır: yalnızca "hassas DLL yüklendi" demek yerine probable origin, memory state, stack pattern, dump ve loader'ın saklamaya çalıştığı yolu göstermeye çalışır.

Ne Arar?

  • Hassas DLL load olayları: ws2_32, wininet, winhttp, dnsapi, CLR/.NET ve ilişkili modüller.
  • Unbacked frame'ler: bilinen bir image'a ait olmayan executable MEM_PRIVATE veya MEM_MAPPED bellek.
  • BackedModified frame'ler: MEM_IMAGE içinde çalışan ama diskteki dosyayla byte seviyesinde uyuşmayan kod.
  • Proxy/gadget, callback, thread start, APC, VEH, threadpool, dispatch veya hedef .text içinden saklanan origin.
  • Stack spoofing: plausible callsite olmayan return frame, kesilmiş stack, synthetic stack veya olay için fazla temiz görünen visible caller.
  • BYOUD/unwind spoofing: .pdata, .xdata, .rdata, RUNTIME_FUNCTION ve dynamic unwind table değişimleri.
  • /network-use-trace açıkken gerçek network API kullanımını izleme; DLL zaten yüklü olsa bile.
  • Suspicious LDR metadata, EntryPoint hijack ve module inconsistency.
  • Memory audit: modified image, orphan executable mapping, private executable region ve odaklı dump.
  • events.jsonl, summary.json, memory.json, network_trace.json, byoud_trace.json, origin dump, module dump, hash, entropy ve strings gibi artifact'ler.

Sample komutları ve beklenen call-stack özetleri samples/README.md içinde.
Küçük uyarı: sample'lar lab için hazırlanmış şüpheli test dosyalarıdır; polished showcase binary beklemeyin.
Aşağıda StackSentry'nin kernel driver olmadan terminalde gösterebildiği birkaç pattern var.

Bazı görseller v0.8 döneminde alınmış output'u gösterir. Sonrasında console rendering, stack compaction ve noise reduction iyileştirildi; ama sırf output temizlendi diye buna v0.9 demek istemedim.

Important

Aşağıdaki görsellerin çoğu detection sonucunun sadece bir bölümünü gösterir. Tam sonucu görmek için sample'ları çalıştırın.

Synthetic Stack ile SilentMoonwalk

Bu test klezVirus/SilentMoonwalk varyantını kullanır. Network DLL synthetic stack ile yüklenir. Visible frame'ler legitimate module gibi görünür; ama callsite validation ve origin tracing hâlâ DLL load'u çağrıyı hazırlayan koda bağlar.

SilentMoonwalk synthetic stack detection

BYOUD / Unwind Metadata Spoofing

Bu test klezVirus/byoud projesinin RDI shellcode haline getirilmiş varyantını kullanır. Bootstrap aşaması wininet.dll ve mscoree.dll gibi DLL'leri yükleyebilir; önemli kısım ise ws2_32.dll load'unun BYOUD ile gizlenmesidir. Return address değiştirmek yerine Windows unwind metadata manipüle edilir. StackSentry sensitive load öncesindeki temporal divergence'ı yakalar.

BYOUD RDI detection BYOUD RDI detection

Threadpool Callback Chain

Bu sample klezvirus/ThreadPoolExecChain fikrine dayanır. Threadpool/proxy chain sayesinde DLL load daha doğal görünen bir context içinde gerçekleşir. StackSentry chain context'i korur ve yol üzerindeki modified frame'leri işaretler.

Threadpool callback-chain detection

Image .text Proxy

Bu test, LibTPLoadLib temeline dayanan deneysel RefinedPool varyantından üretilmiş PIC shellcode kullanır. Teknik, paranoidninja tarafından anlatılan API proxying çizgisine ve Proxy-DLL-Loads projesine yakındır.

PIC olduğu için kod loader'ın .text bölümünde yaşayabilir ve nvwgf2umx.dll içindeki mevcut gadget üzerinden proxy LoadLibrary akışı oluşturabilir. Final stack temiz görünebilir; ama register/origin tracing load'u başlatan .text region'a geri bağlar.

Image .text proxy detection

Code Cave / Modified Image

Bu pattern de RefinedPool üzerinde yapılan küçük deneysel değişikliklerden gelir. Sensitive load, image-backed code cave içine yazılmış byte'lardan geçer. StackSentry modified module dump'ını ve .tag changed-byte map dosyasını korur; triage sırasında bu çoğu zaman tek başına çok değerlidir.

Code cave modified image detection

SilentMoonwalk RDI Synthetic Stack

Burada SilentMoonwalk varyantı Donut/RDI payload olarak paketlenmiştir. Bootstrap wininet.dll ve mscoree.dll yükleyebilir; asıl stage synthetic stack ile ws2_32.dll yükler. İkinci görsel hidden executable region'a geri giden probable origin'i gösterir.

SilentMoonwalk RDI synthetic detection SilentMoonwalk RDI synthetic detection

MassDriver Tarzı Dispatch

Sizeable-Bingus/MassDriver dispatch pattern'inden esinlenen bu sample'da temiz görünen worker thread LoadLibraryA çalıştırır. /dispatch-trace, load'u dispatch structure'ı gönderen requester'a bağlar.

MassDriver-style dispatch detection

C2 Payload içinde Network Use Trace

Bu örnek /network-use-trace kullanır. Burada ilginç olan sadece network DLL'in yüklenmesi değil; payload'un connect, WSAConnect, send, recv, WinHTTP/WinINet gibi API'leri gerçekten kullanmasıdır. Output domain, IP/port ve hatta pastebin.com gibi üçüncü taraf servisleri gösterebilir.

Görselde stack bilinçli olarak compact edilmiştir. Eski ekran görüntülerindeki gibi full stack'i tek satırda görmek isterseniz /inline-stack; frame frame offset'li çıktı için /full-stack kullanın.

Network-use trace detection in C2 payload

Stack Görüntüleme Modları

Detection dışında, mevcut StackSentry console çıktısı analizi daha az yorucu hale getirmeye çalışır. Aynı stack, neyi incelemek istediğinize göre farklı biçimlerde gösterilebilir:

Compact Stack

Bu mevcut default formattır. Tekrarlanan frame'ler [module.dll xN] şeklinde gruplanır. .NET gibi büyük runtime'lardan geçen payload'larda bu, gürültüyü ciddi biçimde azaltır.

Compact stack

Offset'li Full Stack

/full-stack ile her frame ayrı satırda ve module offset'iyle yazdırılır. Her return frame'in tam olarak nereye düştüğünü görmek istediğinizde kullanışlıdır.

Full stack with offsets

Compression Olmadan Inline Stack

/inline-stack ile stack tekrar tek satırlık formata döner ve tekrarlanan frame compression uygulanmaz.

Inline stack without compression

Verbose ile Clean Event'ler

Default console çıktısı terminali doldurmamak için alert'leri öne çıkarır. /verbose ile score=0 clean load event'leri de görünür; bu event'ler mavi renkte çıkar. Böylece bir DLL load'ın görüldüğünü ve kaydedildiğini, şüpheli olmasa bile hızlıca doğrulayabilirsiniz. /verbose kullanmasanız bile score=0 event'leri events.jsonl ve memory.json içine yazılır.

Clean event in verbose mode

BackedModified ve Memory Audit

Return frame gerçek bir DLL içinde görünse bile, o region'daki bytes diskteki file ile uyuşmuyorsa StackSentry bunu clean frame olarak ele almaz. Stack BackedModified / captured-modified olarak işaretlenir; Memory Audit de module, region ve değişikliğin temporal detayını kaydeder.

BackedModified and memory audit

Build

Build işlemi için build.ps1 kullanılır. Microsoft Visual Studio/MSVC gerekir.

.\build.ps1

Script çıktıları build\ altına yazar:

  • StackSentry64.exe
  • CallstackMonitor.dll

Third-party kodlar third_party\ altında tutulur. Lisans ve credit notları için THIRD_PARTY_NOTICES.md dosyasına bakın.

Test Komutları

Önerilen komutlar ve exact sample komutları samples/README.md içinde. Nereden başlayacağınızı bilmiyorsanız oradan başlayın; quick pass, strong profile, stack output mode'ları ve gallery screenshot'larını doğrulamak için kullandığım örnekler orada.

Ana Profiller

  • /quick: düşük noise DLL-load triage profili.
  • /deep: callback/thread-start hook, unwind hook, LDR integrity ve dump/correlation içeren hunting profili. Memory API hook'ları hâlâ opt-in kalır.
  • /max: pratikte en güçlü DLL-load profili. Deep telemetry, stack audit, LDR checks ve default /auto-enter içerir; /mem, /tp, /wait ayrı açılır.
  • /profile <quick|deep|max>: profil seçer.

Şüpheli bir loader için düşünmeden başlanacak yer genelde /max. Sonrasında sonuca göre /hunt, /network-use-trace veya spesifik flag eklemek daha temizdir.

Komut Grupları

Tüm argümanlar için:

.\build\StackSentry64.exe /features

Öne çıkan gruplar:

  • Output style: /no-target-output, /inline-stack, /full-stack, /quiet, /plain, /live, /no-color.
  • Origin / proxy analysis: /regtrace, /dispatch-trace, /threadpool-chain-trace.
  • Network use analysis: /network-use-trace ve /net-use-trace.
  • Remote / multi-process: /follow-remote, /net-reset.
  • Extra telemetry / integrity: /etw, /ldr-integrity, /unwind, /stack-audit, /memory-audit, /byoud-trace, /shadow-stack.
  • Aggressive / low-level hooks: /mem, /tp, /wait, /xhooks.

Önemli Modlar

Origin Tracing

Proxy DLL-load teknikleri final stack'i temiz gösterebilir. /regtrace bu durumlarda origin'i yakalamaya çalışır:

.\build\StackSentry64.exe /run .\samples\sample_03_text_section_proxy.exe /max /regtrace /no-target-output /timeout 9000

/origin-trace callback/thread/APC context ile korelasyon yapar. /regtrace, bunu genişletip gadget/proxy arkasındaki gerçek origin'i yakalamaya çalışır. Artifact'ler origin_regions\ altına yazılır.

Technical note: Mevcut /regtrace, main image olmayan ve 32 MB'tan büyük image module'ler üzerinde full register tracing yapmaktan bilinçli olarak kaçınır. Private executable memory, thread start, dynamic executable transition ve origin correlation hâlâ izlenir. Bu sınırlama sadece büyük gadget-carrier image'lara pahalı full instrumentation uygulamamak içindir. Bir lab case için gerçekten daha yüksek limit gerekiyorsa, source içindeki küçük bir constant değiştirilebilir.

Network Use Trace

Payload network DLL'i zaten yüklü bulursa yeni LoadLibrary olmayabilir. /network-use-trace bu durumda network API kullanımını izler:

.\build\StackSentry64.exe /run target.exe /max /network-use-trace /timeout 10000
.\build\StackSentry64.exe /run target.exe /max /hunt /network-use-trace /timeout 15000

Bu mod /hunt içinde default değildir, çünkü güçlü ama verbose olabilir. Findings == Network Use Details ==, network_trace.json, memory.json ve summary.json içinde görünür.

Memory Audit

/memory-audit, Moneta tarzı memory artifact sınıflarından ilham alan canlı process memory scan'dir:

.\build\StackSentry64.exe /run target.exe /max /memory-audit /timeout 10000

Modified image, orphan executable mapping, private executable region ve suspicious section permission gibi bulguları raporlar. Zayıf bulgular genelde console alert değil, hunting context olarak JSON'da kalır.

BYOUD ve Shadow Stack Research

/byoud-trace, return address yerine Windows x64 unwind metadata manipülasyonunu gözlemlemek için lab modudur:

.\build\StackSentry64.exe /run target.exe /max /byoud-trace /regtrace /timeout 12000

/hunt bunu içerir. /shadow-stack ise CET/HSP araştırma switch'idir; platform user-mode shadow-stack state sağlamıyorsa sessiz kalabilir ve /hunt içinde değildir.

Console Output

Console output alert odaklıdır. Ham ayrıntı JSON artifact'lerinde kalır.

  • /no-target-output: hedefin stdout/stderr çıktısını StackSentry console'una karıştırmaz.
  • /inline-stack: repeated-frame compression olmadan full stack'i tek satırda basar.
  • /full-stack: her frame'i offset ile ayrı satırda basar.
  • /verbose: non-alert event'leri de gösterir.
  • /quiet: artifact yazar, console UI'ı azaltır.

Exit code:

  • 0: alert yok.
  • 10: en az bir alert üretildi.
  • 1/2: runtime, argüman veya target/config hatası.

Outputs

Her run seçilen /out dizini içinde per-process klasörü oluşturur:

out\loader\loader_binary.exe - 24216\

Önemli artifact'ler:

  • summary.json, memory.json, events.jsonl
  • origin_regions\
  • dumps\, memory_audit\, modified_modules\, modified_network_modules\
  • network_trace.json, byoud_trace.json, shadow_stack_trace.json, etw_timeline.json
  • children\ (/follow-remote için)

Modified module dump yanında yazılan .tag dosyası özellikle değerlidir: diskteki dosyaya göre değişen offset/byte haritasını tutar.

Kurallar

Default rule formatı için config\rules.json dosyasına bakın. Özel config:

.\build\StackSentry64.exe /run target.exe --rules path\to\rules.json

Eski watch_dlls alanı compatibility alias olarak hâlâ kabul edilir.

Mevcut Limitler

  • Bu hâlâ user-mode instrumentation. Güçlü target hook'ları tespit edebilir veya kaldırabilir.
  • /mem, /tp ve /wait gürültülü veya destabilizing olabilir, bu yüzden ayrı açılır.
  • /follow-remote user-mode remote-execution setup'ını görmeye bağlıdır.
  • /net-reset her zaman network DLL'i unload edemez.
  • /memory-audit, hedef process hâlâ canlıyken anlamlıdır.
  • /shadow-stack deneysel CET/HSP modudur ve birçok sistemde output üretmeyebilir.
  • Advanced stack spoofing ring3 içinde tamamen imkânsız değildir; StackSentry maliyeti artırmak için callsite, origin, memory, unwind ve network-use korelasyonu yapar.

Lisans

Bu proje MIT License altında dağıtılır (Modify It Tonight). Kullan, değiştir, lab'da boz, düzelt, karşılaştır, sonuç yayınla; ne gerekiyorsa yap.
Eğer birkaç saatlik analiz süresi kazandırırsa ben zaten mutluyum. Kahve kabul edilir.

Third-party kodlar kendi lisans ve credit notlarını THIRD_PARTY_NOTICES.md içinde korur.