WebRTC - FEC Processing Overflow

EDB-ID:

45122

CVE:

N/A




Platform:

Multiple

Date:

2018-08-01


Become a Certified Penetration Tester

Enroll in Penetration Testing with Kali Linux and pass the exam to become an Offensive Security Certified Professional (OSCP). All new content for 2020.

GET CERTIFIED

There are several calls to memcpy that can overflow the destination buffer in webrtc::UlpfecReceiverImpl::AddReceivedRedPacket. The method takes a parameter incoming_rtp_packet, which is an RTP packet with a mac length that is defined by the transport (2048 bytes for DTLS in Chrome). This packet is then copied to the received_packet in several locations in the method, depending on packet properties, using the lenth of the incoming_rtp_packet as the copy length. The received_packet is a ForwardErrorCorrection::ReceivedPacket, which has a max size of 1500. Therefore, the memcpy calls in this method can overflow this buffer.

==204614==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61b000046670 at pc 0x00000059d958 bp 0x7ffcac5716f0 sp 0x7ffcac570ea0
WRITE of size 2316 at 0x61b000046670 thread T0
    #0 0x59d957 in __asan_memcpy /b/build/slave/linux_upload_clang/build/src/third_party/llvm/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23:3
    #1 0x1b6aacc in webrtc::UlpfecReceiverImpl::AddReceivedRedPacket(webrtc::RTPHeader const&, unsigned char const*, unsigned long, unsigned char) modules/rtp_rtcp/source/ulpfec_receiver_impl.cc:173:5
    #2 0x1b3cd5c in webrtc::RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:426:27
    #3 0x1b39a31 in webrtc::RtpVideoStreamReceiver::ReceivePacket(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:402:5
    #4 0x1b3a895 in webrtc::RtpVideoStreamReceiver::OnRtpPacket(webrtc::RtpPacketReceived const&) video/rtp_video_stream_receiver.cc:301:3
    #5 0x8c7a26 in webrtc::RtpDemuxer::OnRtpPacket(webrtc::RtpPacketReceived const&) call/rtp_demuxer.cc:157:11
    #6 0x8cec3d in webrtc::RtpStreamReceiverController::OnRtpPacket(webrtc::RtpPacketReceived const&) call/rtp_stream_receiver_controller.cc:55:19
    #7 0x12e8507 in webrtc::internal::Call::DeliverRtp(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) call/call.cc:1291:36
    #8 0x12e92a0 in webrtc::internal::Call::DeliverPacket(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) call/call.cc:1316:10
    #9 0x5da2a6 in webrtc::RtpReplay() video/replay.cc:635:31
    #10 0x5dd5fe in main video/replay.cc:700:3
    #11 0x7feaa1ee92b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

0x61b000046670 is located 0 bytes to the right of 1520-byte region [0x61b000046080,0x61b000046670)
allocated by thread T0 here:
    #0 0x5c9362 in operator new(unsigned long) /b/build/slave/linux_upload_clang/build/src/third_party/llvm/compiler-rt/lib/asan/asan_new_delete.cc:93:3
    #1 0x1b6a8c8 in webrtc::UlpfecReceiverImpl::AddReceivedRedPacket(webrtc::RTPHeader const&, unsigned char const*, unsigned long, unsigned char) modules/rtp_rtcp/source/ulpfec_receiver_impl.cc:165:35
    #2 0x1b3cd5c in webrtc::RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:426:27
    #3 0x1b39a31 in webrtc::RtpVideoStreamReceiver::ReceivePacket(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:402:5
    #4 0x1b3a895 in webrtc::RtpVideoStreamReceiver::OnRtpPacket(webrtc::RtpPacketReceived const&) video/rtp_video_stream_receiver.cc:301:3
    #5 0x8c7a26 in webrtc::RtpDemuxer::OnRtpPacket(webrtc::RtpPacketReceived const&) call/rtp_demuxer.cc:157:11
    #6 0x8cec3d in webrtc::RtpStreamReceiverController::OnRtpPacket(webrtc::RtpPacketReceived const&) call/rtp_stream_receiver_controller.cc:55:19
    #7 0x12e8507 in webrtc::internal::Call::DeliverRtp(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) call/call.cc:1291:36
    #8 0x12e92a0 in webrtc::internal::Call::DeliverPacket(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) call/call.cc:1316:10
    #9 0x5da2a6 in webrtc::RtpReplay() video/replay.cc:635:31
    #10 0x5dd5fe in main video/replay.cc:700:3
    #11 0x7feaa1ee92b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

SUMMARY: AddressSanitizer: heap-buffer-overflow /b/build/slave/linux_upload_clang/build/src/third_party/llvm/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23:3 in __asan_memcpy
Shadow bytes around the buggy address:
  0x0c3680000c70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3680000c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3680000c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3680000ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3680000cb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c3680000cc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[fa]fa
  0x0c3680000cd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3680000ce0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3680000cf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3680000d00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3680000d10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb


To reproduce this issue:

1) replace video/replay.cc with the attached version, and build it with asan (ninja -C out/asan video_replay). Note that this file adds the ability to load a full receiver config to the video replay tool, I'm hoping to eventually get this change committed to WebRTC.

2) Download the attached files config4.txt and fallbackoob1

3) run video_replay --input_file  fallbackoob1  --config_file config4.txt

Proof of Concept:
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/45122.zip