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

310 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
![StackSentry](/static/StackSentry.png)
<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>
&nbsp;&nbsp;
<img src="https://img.shields.io/badge/Windows-%23000000.svg?style=for-the-badge&logo=Windows">
&nbsp;&nbsp;
![Release](https://img.shields.io/badge/release-v0.8-000000?style=for-the-badge)
<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.
![SilentMoonwalk synthetic stack detection](static/stack-03-silentmoon-synthetic.png)
### 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.
![BYOUD RDI detection](static/stack-05-byoud-rdi-1.png)
![BYOUD RDI detection](static/stack-05-byoud-rdi-2.png)
### 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.
![Threadpool callback-chain detection](static/stack-07-threadpool-chain.png)
### 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.
![Image .text proxy detection](static/stack-01-text-section-proxy.png)
### 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.
![Code cave modified image detection](static/stack-02-code-cave-modified-image.png)
### 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.
![SilentMoonwalk RDI synthetic detection](static/stack-04-silentmoon-rdi-synthetic-1.png)
![SilentMoonwalk RDI synthetic detection](static/stack-04-silentmoon-rdi-synthetic-2.png)
### 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.
![MassDriver-style dispatch detection](static/stack-06-massdriver-dispatch.png)
### 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](static/stack-08-network-use-trace-c2.png)
### 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](static/stack-09-compressed-stack.png)
#### 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](static/stack-10-full-stack.png)
#### 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](static/stack-11-inline-stack.png)
#### 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](static/stack-12-verbose-clean-load.png)
#### 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](static/stack-13-backed-modified-memory-audit.png)
## 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.