create_elf_tables integer overflow (CVE-2018-14634)¶
Linux kernel'inin
create_elf_tables()fonksiyonundaki, exec stack-pointer matematiğini tersine çeviren ve root elde etmek için bir SUID process'in initial stack'ini corrupt eden bir integer overflow ("Mutagen Astronomy").
Mechanism¶
Kırılan invariant
create_elf_tables() item count'unu
(argc + 1) + (envc + 1) + 1'i bir signed int içinde tutar.
MAX_ARG_STRINGS 0x7FFFFFFF'e kadar argument/env entry'sine izin verdiğinden,
toplam INT_MAX'i aşıp negatif olabilir. Bu negatif değer stack-pointer
rounding'ine (STACK_ROUND) akar ve stack-pointer yönünü tersine çevirir;
böylece bprm->p aşağı yerine argv/envp string alanına doğru yukarı hareket
eder — bir SUID binary'nin exec'i sırasında yeni process'in initial stack'ini
corrupt eder ve root verir. (Bkz.
integer overflow to buffer overflow.)
Kavramsal akış (boyutlar/yönler illustratif; gerçek değerler kernel'e göre değişir):
items = (argc+1) + (envc+1) + 1 ───► signed int
│
│ argc/envc ≈ MAX_ARG_STRINGS (≈ 0x7FFFFFFF)
▼
toplam > INT_MAX ──overflow──► items < 0 (negatif)
│
▼ STACK_ROUND(sp, items) — negatif items pointer matematiğini bozar
│
Beklenen: bprm->p ▼ (stack aşağı büyür, string alanından uzağa)
Gerçek: bprm->p ▲ (yön tersine döner, argv/envp string alanına doğru)
high addr ┌───────────────────────┐
│ argv / envp strings │ ◄── bprm->p buraya "yukarı" sapar
├───────────────────────┤ (initial stack corrupt olur)
│ ... │
low addr └───────────────────────┘
Walkthrough¶
Qualys advisory'sinden çıkarılan kavramsal reprodüksiyon.
-
~32 GB RAM'e sahip 64-bit bir sistemde, bir SUID-root binary'nin
exec'ini hazırla. (argc+1)+(envc+1)+1'inint'i overflow edip negatif olması için kabaca0x80000000argument/environment pointer'ı sağla.- Negatif
items,create_elf_tables()içindeki stack-pointer matematiğini tersine çevirir vebprm->p'yi daha yüksek adresli argument/environment string'lerine yönlendirir. - Ters çevrilmiş pointer'ın attacker tarafından kontrol edilen data'ya inmesi için kontrol edilen single-byte değerlerle harmanlanmış büyük (her biri ≈16 GB) padding-string blokları yerleştir.
ld.so'nun bu clobber edilmiş string'leri handle edişini abuse et; böylece tehlikeli env var'ları (örn.LD_LIBRARY_PATH/LD_PRELOAD) onları sıyırması gereken SUID sanitization'ından sağ çıksın.- Privileged binary'de library preloading üzerinden root olarak code execution elde et.
Detection¶
- Absürt biçimde büyük argv/envp sayılarıyla (
MAX_ARG_STRINGS'e yakın) SUID binary'lerinexec'i — güçlü bir anomali sinyali. - Bir setuid binary'nin
execve'sinden hemen önce çok büyük bellek (onlarca GB) tüketen process'ler. - Buna rağmen etkili olan, bir SUID execution'ının environment'ında set edilmiş
LD_PRELOAD/LD_LIBRARY_PATH. - Anormal argument-count/size'a sahip auditd
execvekayıtları ve ardından bir root shell. - Vulnerable kernel'lerde exec stack setup civarında kernel crash'leri / oops'lar.
Mitigation¶
- Vendor kernel güncellemesini uygula; fix (commit
da029c11e6b1, "exec: Limit arg stack to at most 75% of_STK_LIM") argument-stack boyutunu sınırlandırır, böylece overflow'a ulaşılamaz. - Yalnızca
b6a2fea39318'e (Tem 2007) sahip amada029c11e6b1'den (Tem 2017) yoksun kernel'ler exploit edilebilir — kernel'inin cap'i içerdiğini doğrula. - Gereksiz SUID-root binary'leri sınırlandırarak / kaldırarak attack surface'i azalt.
RLIMIT_STACK/ argument-size limitleri ve ASLR zorluğu artırır; 64-bit kernel'lerin arg-stack cap'ini taşıdığından emin ol.