Skip to content

core_pattern overwrite privesc

Kernel'in core-dump handler string'ini |/path ile overwrite et; böylece herhangi bir process crash'i bir attacker programını root olarak çalıştırır.

Mechanism

/proc/sys/kernel/core_pattern (in-kernel global core_pattern[] ile desteklenir) core dump'ların nasıl handle edileceğini kontrol eder. Kernel admin dokümanlarına göre, pattern'in ilk karakteri | ise kernel geri kalanını çalıştırılacak bir komut olarak ele alır: do_coredump() ispipe'ı set eder, pattern'i format_corename()/argv_split() ile parse eder ve adı verilen programı core dump'ı stdin'ine pipe'layarak call_usermodehelper() üzerinden başlatır.

Note

Bu helper, kernel'in root usermodehelper context'inde çalışır. Dolayısıyla core_pattern'i |/path/to/script olarak overwrite edip ardından herhangi bir process'i crash etmek script'i root olarak çalıştırır. Bu, modprobe_path ile aynı usermodehelper sink'idir, ama trigger "bad-magic bir dosya çalıştırmak" yerine "herhangi bir segfault" — bir process'i crash etmeye izin veren ama yeni dosya çalıştırmayı engelleyen sandbox'larda kullanışlıdır. Core dump'ları pipe'lamak ayrıca RLIMIT_CORE boyut limitini de by-pass eder, yani helper ulimit -c 0 olsa bile ateşlenir.

Walkthrough

Sink'i root setup ile göstermek için:

echo '|/tmp/evil.sh' > /proc/sys/kernel/core_pattern

Bir kernel R/W ya da ROP chain'inden global'i doğrudan overwrite et. Literal "|/evil"'i yazan örnek chain fragment'ı:

payload[i++] = pop_rax_ret;
payload[i++] = 0x6c6976652f7c;          // "|/evil" little-endian
payload[i++] = pop_rsi_pop1_ret;
payload[i++] = core_pattern + kernel_base_offset;   // dest address
// ... store rax at [rsi]

Kontrol ettiğin bir process'i crash ederek tetikle:

*(volatile char *)0 = 0;   // or raise(SIGSEGV);

Beklenen console çıktısı: Segmentation fault (core dumped) ve kernel /evil'i, core stream stdin'de olacak şekilde root olarak çalıştırır.

Warning

core_pattern tarihsel olarak (en azından Linux v5.x boyunca) namespace'lenmiş değildi — core-dump up-call host'un initial namespace'inden çalışır, dolayısıyla container'lar host'un global değerini paylaşır. Bu davranış kernel sürümleri arasında evrilebildiği için (namespace desteği eklenmiş olabilir) mutlak bir gerçek varsaymadan kendi kernel sürümünde doğrula. Bu, tarihsel olarak (Linux v5.x ve günümüzdeki mainline dahil) bir container içindeki bir process'in, host-root bir helper çalıştıran bir crash'i tetiklediği container-escape varyantlarına olanak tanımıştır. Namespace izolasyonu kernel sürümleri arasında evrildiği için davranışı kendi kernel sürümünde doğrula; bu sink Kasım 2025 runc advisory'lerinde (CVE-2025-31133 vb.) tekrar erişilebilir hale gelmiştir.

Detection

/proc/sys/kernel/core_pattern'e yapılan write'ları izle (örn. Aqua Tracee'nin "Core Pattern Modification" signature'ı). Standart olmayan bir path'e point eden pipe-prefixed bir değer güçlü bir göstergedir.

Mitigation

/var/crash/%e-%p.core gibi absolute, pipe olmayan bir path ayarla. modprobe_path'te olduğu gibi, CONFIG_STATIC_USERMODEHELPER tüm helper'ları tek bir sabit binary üzerinden yönlendirir.

References