CVE-2009-0385: FFmpeg Type Conversion Vulnerability

Original Advisory

http://www.trapkit.de/advisories/TKADV2009-004.txt


Citar
==================
Technical Details:
==================

Source code file: libavformat/4xm.c

[..]
 93 static int fourxm_read_header(AVFormatContext *s,
 94                               AVFormatParameters *ap)
 95 {
 ..
103 [8]  int current_track = -1;
 ..
106 [9]  fourxm->track_count = 0;
107 [10] fourxm->tracks = NULL;
 ..
160      } else if (fourcc_tag == strk_TAG) {
161          /* check that there is enough data */
162          if (size != strk_SIZE) {
163              av_free(header);
164              return AVERROR_INVALIDDATA;
165          }
166 [1]      current_track = AV_RL32(&header[i + 8]);
167 [2]      if (current_track + 1 > fourxm->track_count) {
168             fourxm->track_count = current_track + 1;
169             if((unsigned)fourxm->track_count >= UINT_MAX /
                           sizeof(AudioTrack))
170               return -1;
171 [3]         fourxm->tracks = av_realloc(fourxm->tracks,
172                 fourxm->track_count * sizeof(AudioTrack));
173             if (!fourxm->tracks) {
174               av_free(header);
175               return AVERROR(ENOMEM);
176             }
177         }
178 [4] fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);
179 [5] fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);
180 [6] fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i+40]);
181 [7] fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]);
[..]

[1] The signed int variable "current_track" (see [8]) is filled with user
    supplied data from the media file
[2] This statement checks if the user controlled value of "current_track"
    is greater than "fourxm->track_count". The variable "fourxm-
    >track_count" is initialized with 0 (see [9]). By supplying a value >=
    0x80000000 for "current_track" it is possible to cause a change in sign
    that results in "current_track" being negative. If "current_track" is
    negative, the if statement will always return false and the buffer
    allocation in [3] will never be reached.
[4] As "fourxm->tracks" is initialized with NULL (see [10]) and line 171 is
    never reached this leads to an exploitable NULL pointer dereference. It
    is possible to write 4 bytes of user controlled data to the memory
    location "NULL + current_track". As the value of "current_track" is
    also controlled by the user it is possible to write 4 bytes of
    arbitrary data at a wide range of memory addresses.
[5] See [4]
[6] See [4]
[7] See [4]

A malicious party may exploit this issue to execute arbitrary code by
overwriting a sensitive memory location (such as a GOT/IAT entry, a return
address, buffer length or boolean variable).


Afecta a algunos reproductores como xine Mplayer entre otros, Según yo solo podremos crear un DoS pero seria de ver.

Ya hay parche pero dudo que los linuxeros (Comunes) estén parcheando cada una de las vulnerabilidades que salen...

Bueno, he tratado de crear un PoC para la vulnerabilidad sin embargo no lo he logrado, tengo un archivo 4xm que según yo debería de funcionar o por lo menos eso creo.

Al parecer no he comprendido muy bien el formato de los los archivos 4xm.

El formato 4x Movie esta descrito aqui:
http://multimedia.cx/4xm-format.txt

Citar
4xm files appear to have the following general structure:

  RIFF header
    LIST-HEAD chunk
      LIST-HNFO chunk
    LIST-TRK_ chunk
      LIST-VTRK chunk
      LIST-STRK chunk
      [..more tracks..]
    LIST-MOVI chunk
      LIST-FRAM chunk
      LIST-FRAM chunk
      LIST-FRAM chunk
      [..more frame tracks..]

tengo duda de LIST-HNFO ya que de este no esta entre las decalaraciones de los Tag de la libreria:

libavformat/4xm.c

Código
#define  RIFF_TAG MKTAG('R', 'I', 'F', 'F')
#define _4XMV_TAG MKTAG('4', 'X', 'M', 'V')
#define  LIST_TAG MKTAG('L', 'I', 'S', 'T')
#define  HEAD_TAG MKTAG('H', 'E', 'A', 'D')
#define  TRK__TAG MKTAG('T', 'R', 'K', '_')
#define  MOVI_TAG MKTAG('M', 'O', 'V', 'I')
#define  VTRK_TAG MKTAG('V', 'T', 'R', 'K')
#define  STRK_TAG MKTAG('S', 'T', 'R', 'K')
#define  std__TAG MKTAG('s', 't', 'd', '_')
#define  name_TAG MKTAG('n', 'a', 'm', 'e')
#define  vtrk_TAG MKTAG('v', 't', 'r', 'k')
#define  strk_TAG MKTAG('s', 't', 'r', 'k')
#define  ifrm_TAG MKTAG('i', 'f', 'r', 'm')
#define  pfrm_TAG MKTAG('p', 'f', 'r', 'm')
#define  cfrm_TAG MKTAG('c', 'f', 'r', 'm')
#define  ifr2_TAG MKTAG('i', 'f', 'r', '2')
#define  pfr2_TAG MKTAG('p', 'f', 'r', '2')
#define  cfr2_TAG MKTAG('c', 'f', 'r', '2')
#define  snd__TAG MKTAG('s', 'n', 'd', '_')
 

Por lo cual dudo de su existencia, el PoC que hice esta usando dicha LIST pero al parecer el programa dentro del codigo no lo toma en cuenta, voy a seguir probando para generar un PoC que funcione:

Aqui esta el que cree 4xm_evil.4xm

El código en C con el cual lo cree esta bien raro, por lo cual mejor prefiero ordenarlo un poco mas y liberarlo.

Espero y les interese, Saludos.

--
- Anon

Comentarios

Entradas populares de este blog

Clave WPA2 por Defecto de equipos TotalPlay (Huawei HG8245H)

Cable modem Ubee - WPA2 y WPS por defecto