Not sure this one is valid. Auditors please confirm: Advisory: mplayer buffer overflow Product: mplayer Affected Version: 1.0_pre7 (tested), 1.0_pre6-r4 (tested), 1.0pre6-3.3.5-20050130 (confirmed) OS affected: Linux 2.4.* (tested), 2.6.* (confirmed), other OS not tested Date: 24.08.2005 Author: Sven Tantau - http://www.sven-tantau.de/ Advisory-URL: http://www.sven-tantau.de/public_files/mplayer/mplayer_20050824.txt Vendor-URL: http://www.mplayerhq.hu/ Vendor-Status: informed Product ======= >> man mplayer DESCRIPTION mplayer is a movie player for Linux (runs on many other platforms and CPU architectures, see the documentation). It plays most MPEG/VOB, AVI, ASF/WMA/WMV, RM, QT/MOV/MP4, OGG/OGM, MKV, VIVO, FLI, NuppelVideo, yuv4mpeg, FILM and RoQ files, supported by many native and binary codecs. You can watch VideoCD, SVCD, DVD, 3ivx, DivX 3/4/5 and even WMV movies, too. ... Details ======= For high values of the 2 bytes strf parameter in the audio header of a video file, it is possible to overflow sh_audio->a_buffer, overwrite the instruction pointer and execute arbitrary code. Not sure, but I think the problem is in: af.c: int af_calc_insize_constrained(af_stream_t* s, int len,int max_outsize,int max_insize); ...as this function is used to calculate declen in dec_audio.c, and declen is supposed to prevent an overflow. Instruction pointer gets overwritten in: libmpdemux/demuxer.c: int demux_read_data(demux_stream_t *ds,unsigned char* mem,int len); If would like to reproduce this or write an exploit: Get a copy of 'Animaniacs - Nations of the World.avi'. (md5: 5ef6428a55c7b00095e2cb5554490acf sha1: 1deeb9640f9864cd5b3db04ffc9a660039a172e4) Watch it. :) Patch offset 0x12B to 0xFF. Use gdb. Have fun. History ======= 2005-08-10 issue found by Sven Tantau 2005-08-16 vendor contacted and public disclosure 2005-08-24 no reaction from mplayer team, posting to full disclosure
Setting to Auditing pending a confirmation.
*** Bug 103690 has been marked as a duplicate of this bug. ***
confirmed, definitely exploitable.
Created attachment 66878 [details] poc the quick code I wrote to confirm vulnerability.
This should fix it: http://www1.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ libmpcodecs/ad_pcm.c.diff?r1=1.18&r2=1.19 A workaround without recompiling should be adding "ac=-pcm," to the config file. Exploiting this in more recent version should be more difficult due to a behaviour change that causes audio not to be played.
*** Bug 103842 has been marked as a duplicate of this bug. ***
pre7-r1 in cvs waiting for stabilization
Arches, please test and mark stable. Target KEYWORDS="alpha amd64 hppa ia64 ppc ppc64 sparc x86" Let the maintainer know if some of you need a backport on pre6...
Who can reproduce the exploit? Because I compiled pre7 on Debian and it did have no effect at all on eip (but it seemed to break the X Display info, so it crashed later on). My Gentoo system is 64bit, so it won't work there either...
(In reply to comment #9) > Who can reproduce the exploit? Because I compiled pre7 on Debian and it did have > no effect at all on eip (but it seemed to break the X Display info, so it > crashed later on). My Gentoo system is 64bit, so it won't work there either... Reimar, it was only a quick example to reproduce the crash as the instructions provided in the original advisory were not very helpful. It would take much more work to make a general purpose, work everywhere exploit and my motivation was simply to satisfy myself that this issue could be exploited. If you want to confirm it can be exploited, you will have to modify it to work on your system: run mplayer on the exploit.avi in gdb, and break on the decode_video function: $ gdb -q (gdb) file mplayer Reading symbols from /usr/bin/mplayer...done. Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) break decode_video Breakpoint 1 at 0x80ed814: file dec_video.c, line 303. (gdb) r -really-quiet -vo sdl exploit.avi [Thread debugging using libthread_db enabled] [New Thread 1091755168 (LWP 8887)] [Switching to Thread 1091755168 (LWP 8887)] Breakpoint 1, decode_video (sh_video=0x86949d8, start=0x8715d58 '\220' <repeats 200 times>..., in_size=141647192, drop_frame=0) at dec_video.c:303 303 unsigned int t=GetTimer(); confirm the buffer at *start contains the exploit code: (gdb) x/10x 0x8715d58 0x8715d58: 0x90909090 0x90909090 0x90909090 0x90909090 0x8715d68: 0x90909090 0x90909090 0x90909090 0x90909090 0x8715d78: 0x90909090 0x90909090 yes, this is the nop sled.. now recompile the exploit with the ADDR defined as somewhere in this buffer. $ mplayer -really-quiet -vo sdl /home/taviso/exploit.avi SDL: Using driver: x11 SDL: deactivating XScreensaver/DPMS SDL: X11 Resolution 1280x1024 SDL: Using 0x32315659 (Planar YV12) image format SDL: using hardware-surface uid=1000(taviso) gid=100(users) groups=5(tty),6(disk),10(wheel) You must use sdl, as the exploit overwrites one of libsdl's function pointers that gets executed via vo_sdl, there are other targets, but this was only a quick demonstration. If I set the exploit to use 0xdeadbeef, you can see how it reaches the sdl function pointer: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 1091755168 (LWP 9195)] 0xdeadbeef in ?? () (gdb) bt #0 0xdeadbeef in ?? () #1 0x407f19c2 in SDL_ListModes (format=0xdeadbeef, flags=3221225473) at SDL_video.c:341 #2 0x080d6615 in sdl_open (plugin=0x0, name=0x0) at vo_sdl.c:478 #3 0x080d6c60 in config (width=156, height=88, d_width=156, d_height=88, flags=0, title=0xc0000001 <Address 0xc0000001 out of bounds>, format=842094169) at vo_sdl.c:850 #4 0x080f6ba4 in config (vf=0x873e270, width=156, height=88, d_width=156, d_height=88, flags=0, outfmt=842094169) at vf_vo.c:48 #5 0x080edd6c in mpcodecs_config_vo (sh=0x86949d8, w=88, h=156, preferred_outfmt=3221225473) at vd.c:312 #6 0x080f0d63 in init_vo (sh=0x86949d8, pix_fmt=PIX_FMT_YUV420P) at vd_ffmpeg.c:512 #7 0x080f0ea4 in get_buffer (avctx=0x873d3a0, pic=0x8745028) at vd_ffmpeg.c:563 #8 0x083049e5 in cinepak_decode_frame (avctx=0x873d3a0, data=0x873e390, data_size=0xc0000001, buf=0xc0000001 <Address 0xc0000001 out of bounds>, buf_size=8192) at cinepak.c:396 #9 0x081d5f80 in avcodec_decode_video (avctx=0x873d3a0, picture=0xc0000001, got_picture_ptr=0xbfffc3fc, buf=0xc0000001 <Address 0xc0000001 out of bounds>, buf_size=-1073741823) at utils.c:536 #10 0x080f12db in decode (sh=0x86949d8, data=0x8715d60, len=8192, flags=0) at vd_ffmpeg.c:765 #11 0x080ed83e in decode_video (sh_video=0x86949d8, start=0xc0000001 <Address 0xc0000001 out of bounds>, in_size=-1073741823, drop_frame=0) at dec_video.c:309 #12 0x080a0a90 in main (argc=2, argv=0xbfffd804) at mplayer.c:2302 (gdb) ptype current_video type = struct SDL_VideoDevice { const char *name; int (*VideoInit)(SDL_VideoDevice *, SDL_PixelFormat *); SDL_Rect **(*ListModes)(SDL_VideoDevice *, SDL_PixelFormat *, Uint32); ... (gdb) info addr current_video Symbol "current_video" is static storage at address 0x4081a400. (gdb) info symbol 0x4081a400 current_video in section .bss The function pointer overwritten is part of the `current_video` struct owned by libSDL. It's possible you're using different features or configuration that means something else gets interrupted before sdl gets a chance to init, if so you will just have to take my word that this is definitely a serious security issue that could be exploited by someone willing to put some work into developing a reliable exploit. SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags) { SDL_VideoDevice *video = current_video; SDL_VideoDevice *this = current_video; SDL_Rect **modes; modes = NULL; if ( SDL_VideoSurface ) { if ( format == NULL ) { format = SDL_VideoSurface->format; } modes = video->ListModes(this, format, flags); /* <--- */ } return(modes); }
Thanks for that extensive reply, I asked mostly out of personal interest. And also because I wanted to know what we have lying around on the heap, maybe some of it can be moved to read-only places, making exploits more difficult. Would be an interesting project if I happen to have too much time somewhen *g*.
hppa and ia64 were already pre7 ppc marked. Removing them.
stable on ppc64
Stable on amd64.
CAN number was asked.
====================================================== Candidate: CAN-2005-2718 URL: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-2718 Reference: FULLDISC:20050824 mplayer overflow Reference: URL:http://marc.theaimsgroup.com/?l=full-disclosure&m=112484733122809&w=2 Reference: MISC:http://www.sven-tantau.de/public_files/mplayer/mplayer_20050824.txt Reference: CONFIRM:https://bugs.gentoo.org/show_bug.cgi?id=103555 Buffer overflow in ad_pcm.c in MPlayer 1.0pre7 and earlier allows remote attackers to execute arbitrary code via a video file with an audio header containing a large value in a strf parameter.
Stable on sparc - not flawless but it never was anyway.
Sorry about the wait, x86 will be done in a few houres.
Stable on x86.
Alpha was apparently marked stable without comment.
GLSA 200509-01
IMHO none of the advisories/whatever describes the issue 100% correctly. > Buffer overflow in ad_pcm.c in MPlayer 1.0pre7 and earlier allows > remote attackers to execute arbitrary code via a video file with an > audio header containing a large value in a strf parameter. It is not a strf parameter, it is a strf chunk. And in this case the one for the audio that contains the WAVEHEADEREX struct. High values in nChannels and wBitsPerSample in that struct can be used to exploit it. Also it should be possible to exploit with any container, i.e. wav, mov, etc. Anything that can contain raw PCM and allows to set either sample size or channel count to arbitrary numbers. Correct me if you think I'm wrong.
You must be correct, as I'm getting lost in chunks, structs and headers... Would the following change in our GLSA describe the issue more correctly : "Sven Tantau discovered a heap overflow in the code handling the WAVEHEADEREX struct of raw PCM audio streams." Do you see any other needed change (like in the Title or Synopsis) ?
I'd suggest "Sven Tantau discovered a heap overflow in the code handling raw PCM audio streams with large channel count or sample size." Mentioning WAVEHEADEREX is confusing IMHO, since it does not really matter how the number of channels/samplesize was specified.