[DZC-2009-001] The Movie Player and VLC Media Player Real Data Transport parsing integer underflow

hello

I have published a security advisory for Mplayer and VLC: [DZC-2009-001]

Advisory blog post:

Advisory:
The Movie Player and VLC Media Player Real Data Transport
parsing integer underflow.

Affected products:
The Movie player <= svn r29446 [1]
VLC media player <= 1.0.0 [2]
Possible others applications that use the xine lib code [3].

Discovred by:
tixxDZ
DZCORE Labs, Algeria

Date reported:
2009/07/25

Release Date:
2009/07/27

Solutions:
VLC: update to VLC media player 1.0.1 [2] [4].
Mplayer: update to svn r29447.

———
Abstract:
———

Mplayer
Source file: stream/realrtsp/real.c
function: int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer, int rdt_rawdata)

VLC
Source file: modules/access/rtsp/real.c
function: int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph)

The original code is part of the xine library [3]:
Source file: src/input/libreal/real.c
function: int real_get_rdt_chunk(rtsp_t *rtsp_session, unsigned char **buffer)

Function real_get_rdt_chunk() calls rtsp_read_data() to read RDT (Real Data Transport) chunks headers from the network and after that it will parse them.
A controled variable is used to allocate a buffer and later passed on to the rtsp_read_data() function in order to specify the length of an RDT chunk data to read from the network.
An integer underflow can be triggered when parsing a malformed RDT header chunk, a remote attacker can exploit it to execute arbitrary code in the context of the application.

The xine lib [3] seems not to be vulnerable due to an additional check in the xio_rw_abort() funcion (file: src/xine-engine/io_helper.c), which takes the length of an RDT packet as an off_t type and performs some comparison checks (line: 350) before reading chunks from the network.
The Movie player [1] and the VLC media player [2] are vulnerable, the length of an RDT packet is passed as an unsigned int to their own network read functions.

———–
Descripton:
———–
xine-lib source file: src/input/libreal/real.c

int real_get_rdt_chunk(rtsp_t *rtsp_session, unsigned char **buffer) {

int n=1;
uint8_t header[8];
rmff_pheader_t ph;
int size;
int flags1;
int unknown1;
uint32_t ts;

n=rtsp_read_data(rtsp_session, header, 8);
if (n<8) return 0;
if (header[0] != 0x24)
{
lprintf(“rdt chunk not recognized: got 0x%02x\n”, header[0]);
return 0;
}
size=(header[1]<<16)+(header[2]<<8)+(header[3]); /* [1] */
flags1=header[4];
if ((flags1!=0x40)&&(flags1!=0x42))
{
lprintf(“got flags1: 0x%02x\n”,flags1);
if (header[6]==0x06)
{
lprintf(“got end of stream packet\n”);
return 0;
}

size-=9; /* [2] */
}
unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]);
n=rtsp_read_data(rtsp_session, header, 6);

if (n<6) return 0;
ts=_X_BE_32(header);

lprintf(“ts: %u size: %u, flags: 0x%02x, unknown values: %u
0x%02x 0x%02x\n”,
ts, size, flags1, unknown1, header[4], header[5]);

size+=2; /* [3] */

ph->object_version=0;

ph->length=size; /* [4] */
ph->stream_number=(flags1>>1)&1;
ph->timestamp=ts;
ph->reserved=0;
ph->flags=0; /* TODO: determine keyframe flag and insert here? */

xine_buffer_ensure_size(*buffer, 12+size); /* [5] */

rmff_dump_pheader(&ph, *buffer);

size-=12; /* [6] */

n=rtsp_read_data(rtsp_session, (*buffer)+12, size); /* [7] */

return (n <= 0) ? 0 : n+12;

}

[1] The signed int size variable is filled with data from the network.

[2] [3] Some arithmetics operations, we assume that at the end size == 11.

[4] The value of the size variable is assigned to the ph->length.

[5] The size variable is used to allocate (realloc) space for the buffer.

[6] An integer underflow is triggered, size == 0xffffffff.

[7] The size variable is passed to the rtsp_read_data() function as an
unsigned integer in order to specify the length of an RDT packet.

Mplayer:
Mplayer is vulnerable, the rtsp_read_data() function passes the
length to the read_stream() function (file: stream/librtsp/rtsp.c) as
a size_t type which can lead to read a big amount of data from the
network and cause a heap overflow.

VLC:
VLC is vulnerable, the real_get_rdt_chunk_header() function will read
and parse the header, the vulnerable call to the rtsp_read_data()
function is made by the real_get_rdt_chunk() function, the length is
passed to the __net_Read() function (file: src/network/io.c) as a
size_t type which can lead to read a big amount of data from the
network and cause a heap overflow.

——–
Patches:
——–

VLC
Official patch by the VideoLAN team (Patch development time: 2 hours) [4].

Mplayer
Official patch by the Mplayer team, please update svn to revision 29447.

———–
References:
———–

[1] http://www.mplayerhq.hu/
[2] http://www.videolan.org/
[3] http://www.xine-project.org/
[4] http://git.videolan.org/?p=vlc.git;a=commitdiff;h=dc74600c97eb834
c08674676e209afa842053aca

———–
Disclaimer:
———–

The document is provided as is without warranty of any kind. The content
may change without notice. In no event shall the author be liable for any
special, direct or indirect damages, losses or unlawful offences.
Use at your own risk.

Copyright (c) 2009 tix tixxDZ, DZCORE Labs. All rights reserved.

#end

PS: the original Advisory published on bugtraq contains an unofficial patch of mine to the Mplayer, however the Mplayer Team responded quickly and a patch is available, please update to svn revision 29447.
PS: the VideoLan team had already corrected the bug and normally the VLC version 1.0.1 will be available soon.

EDIT:
[5] Allocating (realloc) memory for the buffer (memory size: 12 + 11 bytes)
[6] Integer underflow, size == -1 == 0xffffffff
[7] The size variable is used as an unsigned integer to read data from the network, please see the conversion table below:

  • 32bit signed int max value:  2147483647 (0x7fffffff)
  • 32bit signed int min value:   -2147483648 (0x80000000)
  • 32bit unsigned int max value:  4294967295 (0xffffffff)
  • 32bit unsigned int min value:   0

so if we are dealing with an unsigned int the value -1 will be converted to 4294967295 and in this case the network function will try to read 4GB of data into the buffer.

Advertisements

20 Responses to [DZC-2009-001] The Movie Player and VLC Media Player Real Data Transport parsing integer underflow

  1. […] [DZC-2009-001] The Movie Player and VLC Media Player Real Data Transport parsing integer underflow … […]

  2. Thanks tixxDZ, I’ll send a notification through identi.ca.
    Ihope that a patch will be released soon ;)

  3. zendyani says:

    bon courage a toi tixxdz, jolie travail.

  4. secdz says:

    J’ai pas encore lu le billet …je veux juste te féliciter pour le nouveau blog …enfin :)

    Je reviendrais pour apprendre de ton billet

  5. Un petit blog pour l’homme mais un grand pas pour les human being !!! :-)

    Bon courage !!!

  6. Rama says:

    It’s very enjoying to know someone (algerian) trying the adventure in the shakespeare’s way!
    i’m a real dummy in security but I see that you’re an expert and you really know what you’re talking about!
    anyway, you’re already caught in my reader! :D

    congratulation for the rocket’s launching as said KT! :D hope reading you very soon!

  7. tixxdz says:

    thx for all your comments and please see the EDIT to clarify the conversion issues.

  8. hnawelhik says:

    je vais posé une question un peut naïve, mais vous parlez de quoi? entre programmation et anglais je suis perdu.
    salamalikom

    • tixxdz says:

      salam, désolé hnawelhik pour le retard, je suis lhik maintenant (douar sans connection).
      oui effectivement le sujet parle de programmation, vulnérabilité … etc en anglais.

  9. barabas says:

    nice work…keep it up

  10. Xuphanc says:

    Hey..

    I’ve seen before the RTSP and SSA support vuln through my debuging system..LOL, It seem A nice to make a POC,I think that the new versoion has not yet fixed the integer underflow in Real pseudo-RTSP module? Any way congrtatulation weld bladi..I m so happy to hear/t ;) good new about you..Inchallah more and more..

    Keep doing..

    /Xuphanc.

  11. Jugurtha Hadjar says:

    J’étais en train de regarder une vidéo [La présentation de Fyodor au Defcon18, Nmap Scripting Engine] .. Il y avait un certain “nfs-ls”…

    J’ai vu le nom de l’auteur, qui sonnait plutôt familier.. A Google query later.. ça a donné des échanges archivés des mailing lists, avec le co-auteur, ainsi que ce blog.

    Intéressant :)

    Bookmarked of course.

    Keep it up,

    USTHB.

  12. […] MISC (link is external) FULLDISC MLIST (link is external) […]

  13. […] MISC (link is external) FULLDISC MLIST (link is external) […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: