mirror of
https://github.com/Vith0r/StackSentry
synced 2026-06-21 13:46:19 +00:00
310 lines
19 KiB
Markdown
310 lines
19 KiB
Markdown

|
||
|
||
<div align="center">
|
||
|
||
<a href="README.md">`English`</a>
|
||
•
|
||
<a href="README_JP.md">`日本語`</a> •
|
||
<a href="README_PT-BR.md">`Portuguese`</a> •
|
||
<a href="README_TR.md">`Türkçe`</a>
|
||
|
||
<a href="#build"><img src="https://img.shields.io/badge/Documentation-%23000000.svg?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0ibHVjaWRlIGx1Y2lkZS1ib29rLW9wZW4iPjxwYXRoIGQ9Ik0xMiA3djE0Ii8+PHBhdGggZD0iTTMgMThhMSAxIDAgMCAxLTEtMVY0YTEgMSAwIDAgMSAxLTFoNWE0IDQgMCAwIDEgNCA0IDQgNCAwIDAgMSA0LTRoNWExIDEgMCAwIDEgMSAxdjEzYTEgMSAwIDAgMS0xIDFoLTZhMyAzIDAgMCAwLTMgMyAzIDMgMCAwIDAtMy0zeiIvPjwvc3ZnPg==&logoColor=white"></a>
|
||
|
||
<img src="https://img.shields.io/badge/Windows-%23000000.svg?style=for-the-badge&logo=Windows">
|
||
|
||

|
||
|
||
<hr>
|
||
|
||
<br>
|
||
|
||
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?**
|
||
|
||
</div>
|
||
|
||
> [!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. <br> 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. |
|
||
|
||
<br>
|
||
|
||
## 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:
|
||
|
||
- [`defense_evasion_library_loaded_via_a_callback_function.toml`](https://github.com/elastic/protections-artifacts/blob/6e9ee22c5a7f57b85b0cb063adba9a3c72eca348/behavior/rules/windows/defense_evasion_library_loaded_via_a_callback_function.toml): bir kütüphanenin callback üzerinden yüklendiğini yakalar; bu, `LoadLibrary` çağrısının gerçek origin'ini call stack'ten saklama girişimi olabilir.
|
||
- [`defense_evasion_network_module_loaded_from_suspicious_unbacked_memory.toml`](https://github.com/elastic/protections-artifacts/blob/6e9ee22c5a7f57b85b0cb063adba9a3c72eca348/behavior/rules/windows/defense_evasion_network_module_loaded_from_suspicious_unbacked_memory.toml): thread stack içinde bilinen executable image dışında frame varken network module load edildiğini tespit eder.
|
||
- [`defense_evasion_library_loaded_from_a_spoofed_call_stack.toml`](https://github.com/elastic/protections-artifacts/blob/6e9ee22c5a7f57b85b0cb063adba9a3c72eca348/behavior/rules/windows/defense_evasion_library_loaded_from_a_spoofed_call_stack.toml): gerçek call source'u gizlemek için değiştirilmiş/spoofed call stack üzerinden yapılan library load durumunu yakalar.
|
||
|
||
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.
|
||
|
||
## Detection Gallery
|
||
|
||
Sample komutları ve beklenen call-stack özetleri [samples/README.md](samples/README.md) içinde. <br> Küçük uyarı: sample'lar lab için hazırlanmış şüpheli test dosyalarıdır; polished showcase binary beklemeyin. <br>
|
||
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](https://github.com/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.
|
||
|
||

|
||
|
||
### BYOUD / Unwind Metadata Spoofing
|
||
|
||
Bu test [klezVirus/byoud](https://github.com/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.
|
||
|
||

|
||

|
||
|
||
### Threadpool Callback Chain
|
||
|
||
Bu sample [klezvirus/ThreadPoolExecChain](https://github.com/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.
|
||
|
||

|
||
|
||
### Image `.text` Proxy
|
||
|
||
Bu test, [LibTPLoadLib](https://github.com/AlmondOffSec/LibTPLoadLib) temeline dayanan deneysel [RefinedPool](https://github.com/Vith0r/RefinedPool/tree/main/RefinedPool) varyantından üretilmiş PIC shellcode kullanır. Teknik, [paranoidninja](https://0xdarkvortex.dev/hiding-in-plainsight/) tarafından anlatılan API proxying çizgisine ve [Proxy-DLL-Loads](https://github.com/paranoidninja/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.
|
||
|
||

|
||
|
||
### Code Cave / Modified Image
|
||
|
||
Bu pattern de [RefinedPool](https://github.com/Vith0r/RefinedPool/tree/main/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.
|
||
|
||

|
||
|
||
### SilentMoonwalk RDI Synthetic Stack
|
||
|
||
Burada [SilentMoonwalk](https://github.com/klezVirus/SilentMoonwalk) varyantı [Donut](https://github.com/TheWover/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.
|
||
|
||

|
||

|
||
|
||
### MassDriver Tarzı Dispatch
|
||
|
||
[Sizeable-Bingus/MassDriver](https://github.com/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.
|
||
|
||

|
||
|
||
### 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.
|
||
|
||

|
||
|
||
### 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.
|
||
|
||

|
||
|
||
#### 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.
|
||
|
||

|
||
|
||
#### Compression Olmadan Inline Stack
|
||
|
||
`/inline-stack` ile stack tekrar tek satırlık formata döner ve tekrarlanan frame compression uygulanmaz.
|
||
|
||

|
||
|
||
#### 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.
|
||
|
||

|
||
|
||
#### 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.
|
||
|
||

|
||
|
||
## Build
|
||
|
||
Build işlemi için `build.ps1` kullanılır. Microsoft Visual Studio/MSVC gerekir.
|
||
|
||
```powershell
|
||
.\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](THIRD_PARTY_NOTICES.md) dosyasına bakın.
|
||
|
||
## Test Komutları
|
||
|
||
Önerilen komutlar ve exact sample komutları [samples/README.md](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:
|
||
|
||
```powershell
|
||
.\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:
|
||
|
||
```powershell
|
||
.\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:
|
||
|
||
```powershell
|
||
.\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:
|
||
|
||
```powershell
|
||
.\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:
|
||
|
||
```powershell
|
||
.\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:
|
||
|
||
```text
|
||
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:
|
||
|
||
```powershell
|
||
.\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. <br> 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](THIRD_PARTY_NOTICES.md) içinde korur.
|