Skip to content

UDP UFO out-of-bounds LPE (CVE-2017-1000112)

Bir MSG_MORE UDP send'i, mesaj ortasında UFO (UDP Fragmentation Offload) append yolundan sıradan fragmentation yoluna geçebilir; bu da negatif copy uzunlukları üretir ve bir socket buffer'a out-of-bounds write sürükler.

Mechanism

Userspace bir datagram'ı MSG_MORE ile artımlı olarak kurarken, __ip_append_data() UFO yolu (ip_ufo_append_data(), daha sonra donanım/segmentasyonla düzeltilen tek büyük lineer skb) ile sıradan yol (fragment skb'ler allocate etme) arasında karar verir. Seçim device feature'larına ve send-başına flag'lere bağlıdır; bunlar aynı mesaj üzerindeki iki send() çağrısı arasında farklılık gösterebilir.

Note

İhlal edilen invariant şudur: "tek bir append edilen datagram tamamen tek bir yolda kurulur." İlk send() bir UFO skb'i (uzunluğunun MTU'yu aşmasına izin verilen) kurar ve ardından ikinci bir send() non-UFO yolda işlenirse, kod MTU-üstü bir skb'e karşı copy = maxfraglen - skb->len'i hesaplar ve copy'yi negatif yapar. Negatif değer, kontrolü new-fragment dalına yönlendirir; burada fraggap = skb_prev->len - maxfraglen MTU'yu aşabilir ve ardından copy = datalen - transhdrlen - fraggap da negatif olur. Bu negatif uzunluklar skb_copy_and_csum_bits()'e akar; bu da skb'in allocate edilen tail'ini çok aşarak kopyalar — lineer bir heap out-of-bounds write (bkz. out-of-bounds-write.md). IPv6 yolunda da benzer bir açık vardı.

Bug 2005'te tanıtıldı (e89e9cf539a2, "[IPv4/IPv6]: UFO Scatter-gather approach") ve 2017'de 85f1bd9a7b5a ("udp: consistently apply ufo or fragmentation") ile düzeltildi; Linux 4.14 için merge edildi ve yol kararını tüm datagram için tutarlı kılar.

Walkthrough

Andrey Konovalov'un public oss-security disclosure'ından ve writeup'ından yüksek seviyeli yeniden kurgu; silahlandırılmış kod ya da offset tekrar üretilmez.

  1. Koşulu oluştur. MTU < 65535 olan UFO-yetenekli bir interface'te bir UDP datagram başlat. Unprivileged user namespace'ler bunu erişilebilir kılar: bir kullanıcı interface'i kurabilir ve send'ler arasında yol geçişini zorlamak için NETIF_F_UFO'yu disable edebilir ya da SO_NO_CHECK'i set edebilir.
  2. Geçişi tetikle. İlk chunk'ı MSG_MORE ile gönder ki bir UFO skb'i oluşsun, sonra yol non-UFO'ya döndükten sonra ikinci bir chunk gönder. Yukarıdaki negatif-uzunluk aritmetiği skb_copy_and_csum_bits()'in skb'i overflow etmesine yol açar. Slab'i öyle groom etmek ki skb'in arkasından işe yarar bir nesne gelsin klasik sk-buff-spray.md / heap-grooming-feng-shui.md'dir.

    // conceptual: same datagram, path differs between the two appends
    send(fd, buf1, len1, MSG_MORE);   // builds a UFO skb (len may exceed MTU)
    send(fd, buf2, len2, 0);          // handled non-UFO -> copy/fraggap go negative
    
  3. Control'ü hijack et. Public PoC, skb verisinin hemen ardından duran skb_shared_info.destructor_arg->callback function pointer'ını overwrite eder ve skb destruct edildiğinde onu saldırgan shellcode'una yönlendirir.

  4. Mitigation'ları aş. Exploit SMEP'i ve KASLR'ı bypass eder ama SMAP'i bypass etmez — execution bir userland buffer yerine kernel'de yerleşik bir payload'a yönlendirilir. Çevredeki bypass stratejileri için bkz. disable-smep-via-cr4-rop.md ve token-stealing-shellcode-smep-bypass.md. Unprivileged user namespace'ler mevcut olduğunda bu root verir.

Warning

Corruption network TX yoluna bindiği ve overwrite edilen pointer bir skb destructor callback'i olduğu için, trigger ile control-flow hijack zaman içinde ayrışır — saldırgan için yararlı, naif call-stack tabanlı detection için zahmetli.

Detection

  • Crash/oops telemetrisi. Başarısız denemeler dmesg'de skb ilişkili oops'lar, slab corruption raporları ya da UDP/UFO append fonksiyonlarında (__ip_append_data, skb_copy_and_csum_bits) KASAN out-of-bounds-write trace'leri üretir.
  • User namespace + netns aktivitesi. Unprivileged process'lerin user/network namespace oluşturup sonra olağandışı MSG_MORE + SO_NO_CHECK/feature-toggle desenleriyle UDP socket'leri hazırlaması, userns'in izin verildiği yerde işaretlenmeye değer anormal bir dizidir.
  • Post-exploitation belirtileri. Unprivileged parent'lardan uid-0 geçişleri, beklenmedik kernel-context execution'ı ve socket aktivitesini izleyen SELinux/AppArmor denial'ları.

Mitigation

  • Patch. 85f1bd9a7b5a'yı içeren bir kernel'e güncelle (Linux ≥ 4.14 ve Ubuntu/Debian/Red Hat'ten distro stable backport'ları). UFO daha sonra kernel'den tamamen kaldırıldı ve path-switch sınıfını ortadan kaldırdı.
  • User namespace'leri kısıtla. Interface/feature manipülasyonunu erişilebilir kılan unprivileged yolu reddetmek için kernel.unprivileged_userns_clone=0 (Debian/Ubuntu) ya da user.max_user_namespaces=0 ayarla.
  • Defense in depth. SMAP (desteklenen yerlerde) daha basit userland-payload varyantlarını engeller; CONFIG_HARDENED_USERCOPY ve slab hardening, OOB write'ı güvenilir bir control-flow hijack'e çevirmenin maliyetini artırır.

References