[FFmpeg-trac] #5992(avformat:new): Heap-overflow results Remote Code Execution

FFmpeg trac at avcodec.org
Mon Dec 5 04:57:40 EET 2016


#5992: Heap-overflow results Remote Code Execution
----------------------------------+--------------------------------------
             Reporter:  paulch    |                     Type:  defect
               Status:  new       |                 Priority:  critical
            Component:  avformat  |                  Version:  git-master
             Keywords:            |               Blocked By:
             Blocking:            |  Reproduced by developer:  0
Analyzed by developer:  0         |
----------------------------------+--------------------------------------
 '''Summary of the bug:'''

 We managed to find and successfully exploit critical security bug in
 libavformat/http.c that results Remote Code Execution in latest version of
 FFmpeg.

 '''Prerequisites:'''

 Attacker has to reproduce SSRF bug and send HTTP request to his remote
 host. There are multiple ways of doing this already described all over the
 Internet. (For ex. you can trigger SSRF using HLS playlists or the way I
 described earlier in this [https://trac.ffmpeg.org/ticket/5991#ticket
 ticket]  ).

 '''Overview:'''

 libavformat/http.c supports different types of HTTP responses, one of them
 is "Transfer-Encoding: chunked". Because
 [https://github.com/FFmpeg/FFmpeg/blob/1f5630af51f24d79053b6bef5b8b3ba93d637306/libavformat/http.c#L65
 "int64_t"] type is used to store size of the chunk and
 [https://github.com/FFmpeg/FFmpeg/blob/1f5630af51f24d79053b6bef5b8b3ba93d637306/libavformat/http.c#L1259
 strtoll] function to parse the value of next chunk size it is possible to
 pass negative value and it will be successfully stored in chunksize
 variable. Later FFMIN
 [https://github.com/FFmpeg/FFmpeg/blob/1f5630af51f24d79053b6bef5b8b3ba93d637306/libavformat/http.c#L1267
 function] is used to determine final size of chunk and now it turns
 negative and it is passed to
 [https://github.com/FFmpeg/FFmpeg/blob/1f5630af51f24d79053b6bef5b8b3ba93d637306/libavformat/http.c#L1273
 http_buf_read] function. Inside http_buf_read function our negative value
 is
 [https://github.com/FFmpeg/FFmpeg/blob/1f5630af51f24d79053b6bef5b8b3ba93d637306/libavformat/http.c#L1174
 assigned] to len variable and passed as argument to
 [https://github.com/FFmpeg/FFmpeg/blob/1f5630af51f24d79053b6bef5b8b3ba93d637306/libavformat/http.c#L1175
 memcpy] which results a crash.

 '''Steps to reproduce:'''

 I am attaching PoC file that reproduces the simple crash. Steps to
 reproduce bug:
 {{{
 $ python http_poc.py &
 $ ffmpeg -v trace -i "http://localhost:12345/1.avi" 1.avi
 $ gdb -q ffmpeg_g
 (gdb) r -v trace -i "http://localhost:12345/1.avi" 1.avi
 }}}

 I am also attaching gdb stack-trace.

 '''Recommended fix:'''

 The best fix for that should be completely rewrite http parser, because
 some sneaky bugs still can be found there. Good example of http parser can
 be found [https://github.com/nodejs/http-parser/blob/master/http_parser.c
 here], it is implemented with finite-state machine.

 But for now simple quick fix could be making chunksize unsigned long long.

 '''Final words:'''

 Our team is planning to release full exploit and blogpost with full
 details on exploitation in 30 days or as soon as you patch vulnerability.

 Contact me if you need more details on vulnerability.

--
Ticket URL: <https://trac.ffmpeg.org/ticket/5992>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list