[prev in list] [next in list] [prev in thread] [next in thread] 

List:       full-disclosure
Subject:    Re: [FD] libmad memory corruption vulnerability
From:       Timo Teras <timo.teras () iki ! fi>
Date:       2017-08-30 8:26:17
Message-ID: 20170830112617.4a7c4c48 () vostro ! util ! wtbts ! net
[Download RAW message or body]

You wrote:
> ================
> Author : qflb.wu
> ===============
> 
> 
> Introduction:
> =============
> libmad is a high-quality MPEG audio decoder capable of 24-bit output.
> 
> 
> Affected version:
> =====
> 0.15.1b

Not affected. The bug is not in libmad, but in mpg321.

> Vulnerability Description:
> ==========================
> the mad_decoder_run function in decoder.c in libmad 0.15.1b can cause
> a denial of service(memory corruption) via a crafted mp3 file.

Not correct.

> I found this bug when I test mpg321 0.3.2 which used the libmad
> library.

mpg321 is the culprit here.

> ./mpg321 libmad_0.15.1b_memory_corruption.mp3
> 
> 
> ----debug info:----
> Program received signal SIGABRT, Aborted.
> 0x00007ffff6bf7cc9 in __GI_raise (sig=sig@entry=6)
>     at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
> 56../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
> (gdb) bt
> #0  0x00007ffff6bf7cc9 in __GI_raise (sig=sig@entry=6)
>     at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
> #1  0x00007ffff6bfb0d8 in __GI_abort () at abort.c:89
> #2  0x00007ffff6c34394 in __libc_message (do_abort=do_abort@entry=1, 
>     fmt=fmt@entry=0x7ffff6d42b28 &quot;*** Error in `%s&apos;: %s:
> 0x%s ***\n&quot;) at ../sysdeps/posix/libc_fatal.c:175
> #3  0x00007ffff6c4066e in malloc_printerr (ptr=&lt;optimized out&gt;, 
>     str=0x7ffff6d42c58 &quot;double free or corruption (out)&quot;,
> action=1) at malloc.c:4996
> #4  _int_free (av=&lt;optimized out&gt;, p=&lt;optimized out&gt;,
> have_lock=0) at malloc.c:3840
> #5  0x00007ffff749ab43 in mad_decoder_run (
>     decoder=decoder@entry=0x7fffffffbd20, 
>     mode=mode@entry=MAD_DECODER_MODE_SYNC) at decoder.c:559
> #6  0x0000000000403d5d in main (argc=&lt;optimized out&gt;,
> argv=&lt;optimized out&gt;) at mpg321.c:1092
> (gdb)
> 
> 
> POC:
> libmad_0.15.1b_memory_corruption.mp3
> CVE:
> CVE-2017-11552

The corruption is happening in the callbacks libmad is calling, but are
implemented in mpg321. Backtraces after memory corruption are not
reliable, as the crash often happens a lot later than the corruption.

valgrind says corruption is happening in mpg321's mad.c:
==22190== Invalid write of size 8
==22190==    at 0x10EEFE: read_header (mad.c:285)
..
==22190== Invalid write of size 8
==22190==    at 0x10EF05: read_header (mad.c:287)
..
==22190== Invalid write of size 8
==22190==    at 0x10EF08: read_header (mad.c:287)

Potential fix to mpg321 is:

diff -ru mpg321-0.3.2.orig/mad.c mpg321-0.3.2-fixed/mad.c
--- mpg321-0.3.2.orig/mad.c     2012-03-25 15:27:49.000000000 +0300
+++ mpg321-0.3.2.fixed/mad.c    2017-08-30 11:16:37.055394106 +0300
@@ -572,7 +572,7 @@
         mad_timer_add(&buf->duration, header.duration);
     }
 
-    if (!is_vbr)
+    if (header.bitrate > 0 && !is_vbr)
     {
         double time = (len * 8.0) / (header.bitrate); /* time in seconds */
         double timefrac = (double)time - ((long)(time));

Preventing the faulty length calculation to happen when bitrate is not
detected properly. In the POC case it's zero causing the double to be
'inf' and resulting in huge number for the 'num_frames'.

Other options are changing num_frames data type, and/or increasing code
robustness elsewhere.

Timo

_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: http://seclists.org/fulldisclosure/
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic