DF-3879 / kmemprobe.c
/* * DF-3879 root-side oracle: probe whether kernel VAs are mapped, safely, * by pread()ing /dev/kmem (unmapped KVA yields an error, not a panic). * Used to pick the attack t so that wild = b->buf + 0xFFFFF000 + t lands * on mapped kernel memory (kmem band measured via hw.snd.verbose=4 dmesg). * * usage: kmemprobe <base_va_hex> <pages> */ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char **argv) { if (argc < 3) { printf("usage: %s base_va_hex pages\n", argv[0]); return 2; } uint64_t base = strtoull(argv[1], NULL, 0); int pages = atoi(argv[2]); int fd = open("/dev/kmem", O_RDONLY); if (fd < 0) { printf("[-] open /dev/kmem: %s\n", strerror(errno)); return 2; } for (int i = 0; i < pages; i++) { uint64_t va = base + (uint64_t)i * 4096; char buf[16]; ssize_t n = pread(fd, buf, sizeof(buf), (off_t)va); if (n == sizeof(buf)) printf("%016llx MAPPED %02x %02x %02x %02x %02x %02x %02x %02x\n", (unsigned long long)va, (unsigned char)buf[0],(unsigned char)buf[1], (unsigned char)buf[2],(unsigned char)buf[3], (unsigned char)buf[4],(unsigned char)buf[5], (unsigned char)buf[6],(unsigned char)buf[7]); else printf("%016llx unmapped (pread=%zd errno=%d)\n", (unsigned long long)va, n, errno); } return 0; } |