
Lettura di file locali ad alto privilegio: LiteBox v0.1.0 linux-userland seccomp SYS_open O_RDONLY non ha alcun controllo del percorso host
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · litebox-seccomp-open-rdonly
Classe: Lettura di file (confine del FS della sandbox) Portata: Locale
LiteBox v0.1.0 (d8556e3) - Microsoft
Il runner Linux-userland documentato (litebox-runner-linux-userland) installa un filtro seccomp deny-by-default, poi carica un ELF guest nello stesso processo. SYS_open è nella allowlist quando l'argomento 1 (flags) è un dword uguale a OFlags::RDONLY (0). Non esiste alcun predicato sul percorso. Un guest che emette una vera syscall con flags 0 apre il VFS dell'host con l'UID del runner, poi read / mmap quei byte. Il rewriter ELF non è un confine di sicurezza su questo pin. --rewrite-syscalls è -Z e disattivato di default.
Questo residuo è lettura dell'FS host. Non è scrittura host, non è exec, non è ptrace, non è LPE e non è RCE.
| ID | nessuna CVE al momento |
| Classe | Lettura di file (confine del FS della sandbox) |
| Portata | Locale (binario guest non fidato nel processo del runner) |
| CWE | CWE-284, CWE-862 |
| CVSS | Alto: 7.1 CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N |
| Prodotto | microsoft/litebox |
| Affetto | v0.1.0 (d8556e33676e47244bfefa139c1e9ff95bd67d53) piattaforma Linux userland + runner |
| Auth | guest già in esecuzione all'interno della sandbox |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1, linux/amd64 |
Chi: un binario guest non fidato in litebox-runner-linux-userland. Il vendor (CvvT su GitHub #1006) e la documentazione del crate rewriter affermano che i trampolini ELF non sono un confine di sicurezza. La sicurezza del Linux userland è questo filtro. enable_seccomp_filter è deny-by-default (Errno(EINVAL) in release) con TSYNC e PR_SET_NO_NEW_PRIVS. Il buco è SYS_open con flags Eq 0 senza controllo sul percorso. Il commento in page_mgmt.rs dice che la mappatura CoW riapre il file del programma host dopo che il filtro è attivo, invece di mantenere un FD pre-aperto.
| Metodo + sink | Privilegio |
|---|---|
vera SYS_open("/oracle/secret", 0) poi SYS_read | Byte del file host che l'UID del runner può leggere. Lab: fd 3, 35 byte, witness LITEBOX-SECCOMP-OPEN-RDONLY-WITNESS. Il percorso è il VFS host dell'initramfs, non l'overlay del guest. |
| Metodo + sink | Privilegio |
|---|---|
SYS_open("/etc/passwd", 0) poi read / mmap | file host leggibili da tutti con l'UID del runner |
SYS_open di percorsi di proprietà del runner (chiavi ssh, .env, kubeconfig, credenziali cloud, tar --initial-files) | quei byte se l'UID può aprirli |
SYS_open("/etc/shadow", 0) | hash di shadow solo se il runner è root |
SYS_open("/proc/self/maps", 0) | mappe del runner, inclusi .text host / libc (stesso processo) |
SYS_open("/proc/self/mem", 0) poi mmap dell'FD | spazio di indirizzamento del runner che l'UID può leggere via procfs. pread è deny non corrispondente; SYS_mmap è consentito. |
Nessuna su questo residuo. I negativi dimostrati in lab hanno tutti restituito errno=22 EINVAL e non hanno creato file:
| Metodo + sink | Risultato |
|---|---|
SYS_open O_RDWR | EINVAL |
SYS_open O_CREAT | EINVAL, nessun file creato |
SYS_openat anche con O_RDONLY | EINVAL |
SYS_execve | EINVAL |
socket, ptrace | EINVAL (deny non corrispondente aggiuntivo) |
openat / openat2 / creat / unlink / chmod restano deny non corrispondente sul pin.
Non in bar.
process_vm_readv, io_uring_setup, bpf, mount, pivot_root, unshare, setns, connect, ioctl, getdentsAUDIT_ARCH_X86_64 o KILL_PROCESSclone3 eredita il filtro; scrivere uid_map richiede un open bloccatoin_mem + tar_ro) è invariato. Questo residuo è il VFS host tramite una vera syscallHo fissato microsoft/litebox v0.1.0 (d8556e3, 2026-10-07) invece di main. Diciotto ricerche nel sorgente. Il crate rewriter e GitHub #1006 dicono già che i trampolini non sono il confine. Il filtro Linux userland lo è. SYS_open con flags 0 è lì perché CoW possa riaprire il file del programma. Non c'è alcun controllo sul percorso.
Falsa pista: Docker Desktop Rosetta e qemu-user-static rifiutano entrambi seccomp(SET_MODE_FILTER) su questo host (EINVAL / ENOSYS). Il lab quindi avvia un kernel virt Alpine x86_64 sotto qemu-system-x86_64 TCG ed esegue il filtro copiato come PID 1, così il BPF colpisce un vero kernel x86_64. Regole seccompiler 0.5.0 copiate, non una chiamata in-tree a enable_seccomp_filter, e non l'intero workspace.
cd lab
./run.sh
Loopback 127.0.0.1:19110. Progetto Compose litebox-seccomp-open-rdonly. Piattaforma linux/amd64. Witness LITEBOX-SECCOMP-OPEN-RDONLY-WITNESS. Ultima riga:
SUCCESS litebox-seccomp-open-rdonly open-rdonly-ok rdwr-einval openat-einval execve-einval LITEBOX-SECCOMP-OPEN-RDONLY-WITNESS
Rimuovere SYS_open dal filtro e pre-aprire gli FD CoW prima di PR_SET_SECCOMP, oppure aggiungere un predicato sul percorso che non possa vedere percorsi host al di fuori del FS del guest. Il deny non corrispondente copre già openat.
L'intake del vendor è MSRC (https://msrc.microsoft.com/create-report). Non aprire una issue pubblica su GitHub per microsoft/litebox.
Abraxas Labs - abraxaslabs.tech - github.com/abraxas - @abraxas_null - [email protected]