webrtc vp9 processing useafterfree
▸▸▸ Exploit & Vulnerability >> dos exploit & multiple vulnerability
There is a use-after-free in VP9 processing in WebRTC. In the method RtpFrameReferenceFinder::ManageFrameVp9 the following code occurs: auto gof_info_it = gof_info_.find((codec_header.temporal_idx == 0) ? codec_header.tl0_pic_idx - 1 : codec_header.tl0_pic_idx); ... // snip info = &gof_info_it->second; } // Clean up info for base layers that are too old. uint8_t old_tl0_pic_idx = codec_header.tl0_pic_idx - kMaxGofSaved; auto clean_gof_info_to = gof_info_.lower_bound(old_tl0_pic_idx); gof_info_.erase(gof_info_.begin(), clean_gof_info_to); FrameReceivedVp9(frame->id.picture_id, info); tl0_pic_idx is extracted from the incoming packet, and it if is higher than any picture id that exists in gof_info_, the entire vector will be erased, and info will be used in the call FrameReceivedVp9 even though it has been freed. ASAN output: ==163231==ERROR: AddressSanitizer: heap-use-after-free on address 0x6060000031d0 at pc 0x0000014b0e1e bp 0x7ffe607dfd30 sp 0x7ffe607dfd28 READ of size 2 at 0x6060000031d0 thread T0 #0 0x14b0e1d in webrtc::video_coding::RtpFrameReferenceFinder::FrameReceivedVp9(unsigned short, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo*) modules/video_coding/rtp_frame_reference_finder.cc:569:31 #1 0x14ac2c5 in webrtc::video_coding::RtpFrameReferenceFinder::ManageFrameVp9(webrtc::video_coding::RtpFrameObject*) modules/video_coding/rtp_frame_reference_finder.cc:499:3 #2 0x14a7849 in ManageFrameInternal modules/video_coding/rtp_frame_reference_finder.cc:89:14 #3 0x14a7849 in webrtc::video_coding::RtpFrameReferenceFinder::ManageFrame(std::__1::unique_ptr<webrtc::video_coding::RtpFrameObject, std::__1::default_delete<webrtc::video_coding::RtpFrameObject> >) modules/video_coding/rtp_frame_reference_finder.cc:43 #4 0x148a87e in non-virtual thunk to webrtc::RtpVideoStreamReceiver::OnReceivedFrame(std::__1::unique_ptr<webrtc::video_coding::RtpFrameObject, std::__1::default_delete<webrtc::video_coding::RtpFrameObject> >) video/rtp_video_stream_receiver.cc:336:22 #5 0x1496f41 in webrtc::video_coding::PacketBuffer::InsertPacket(webrtc::VCMPacket*) modules/video_coding/packet_buffer.cc:130:31 #6 0x1487e59 in webrtc::RtpVideoStreamReceiver::OnReceivedPayloadData(unsigned char const*, unsigned long, webrtc::WebRtcRTPHeader const*) video/rtp_video_stream_receiver.cc:231:19 #7 0x12d9144 in webrtc::RTPReceiverVideo::ParseRtpPacket(webrtc::WebRtcRTPHeader*, webrtc::PayloadUnion const&, unsigned char const*, unsigned long, long) modules/rtp_rtcp/source/rtp_receiver_video.cc:109:26 #8 0x12cc80d in webrtc::RtpReceiverImpl::IncomingRtpPacket(webrtc::RTPHeader const&, unsigned char const*, unsigned long, webrtc::PayloadUnion) modules/rtp_rtcp/source/rtp_receiver_impl.cc:181:42 #9 0x1488e52 in webrtc::RtpVideoStreamReceiver::ReceivePacket(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:399:20 #10 0x1488b03 in webrtc::RtpVideoStreamReceiver::OnRecoveredPacket(unsigned char const*, unsigned long) video/rtp_video_stream_receiver.cc:245:3 #11 0x14b925c in webrtc::UlpfecReceiverImpl::ProcessReceivedFec() modules/rtp_rtcp/source/ulpfec_receiver_impl.cc:244:35 #12 0x148bd42 in webrtc::RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:421:23 #13 0x1488d51 in webrtc::RtpVideoStreamReceiver::ReceivePacket(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:390:5 #14 0x14899f8 in webrtc::RtpVideoStreamReceiver::OnRtpPacket(webrtc::RtpPacketReceived const&) video/rtp_video_stream_receiver.cc:290:3 #15 0x90c486 in webrtc::RtpDemuxer::OnRtpPacket(webrtc::RtpPacketReceived const&) call/rtp_demuxer.cc:157:11 #16 0x9131bd in webrtc::RtpStreamReceiverController::OnRtpPacket(webrtc::RtpPacketReceived const&) call/rtp_stream_receiver_controller.cc:55:19 #17 0x129940d in webrtc::internal::Call::DeliverRtp(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) call/call.cc:1321:36 #18 0x129a8d5 in webrtc::internal::Call::DeliverPacket(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) call/call.cc:1361:10 #19 0x61fe06 in webrtc::RtpReplay() video/replay.cc:279:31 #20 0x62337d in main video/replay.cc:343:3 #21 0x7f5ae03d82b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0) 0x6060000031d0 is located 48 bytes inside of 56-byte region [0x6060000031a0,0x6060000031d8) freed by thread T0 here: #0 0x61bbb2 in operator delete(void*) /b/build/slave/linux_upload_clang/build/src/third_party/llvm/compiler-rt/lib/asan/asan_new_delete.cc:150:3 #1 0x14ac26c in __libcpp_deallocate buildtools/third_party/libc++/trunk/include/new:279:10 #2 0x14ac26c in deallocate buildtools/third_party/libc++/trunk/include/memory:1802 #3 0x14ac26c in deallocate buildtools/third_party/libc++/trunk/include/memory:1556 #4 0x14ac26c in erase buildtools/third_party/libc++/trunk/include/__tree:2370 #5 0x14ac26c in erase buildtools/third_party/libc++/trunk/include/__tree:2379 #6 0x14ac26c in erase buildtools/third_party/libc++/trunk/include/map:1200 #7 0x14ac26c in webrtc::video_coding::RtpFrameReferenceFinder::ManageFrameVp9(webrtc::video_coding::RtpFrameObject*) modules/video_coding/rtp_frame_reference_finder.cc:497 #8 0x14a7849 in ManageFrameInternal modules/video_coding/rtp_frame_reference_finder.cc:89:14 #9 0x14a7849 in webrtc::video_coding::RtpFrameReferenceFinder::ManageFrame(std::__1::unique_ptr<webrtc::video_coding::RtpFrameObject, std::__1::default_delete<webrtc::video_coding::RtpFrameObject> >) modules/video_coding/rtp_frame_reference_finder.cc:43 #10 0x148a87e in non-virtual thunk to webrtc::RtpVideoStreamReceiver::OnReceivedFrame(std::__1::unique_ptr<webrtc::video_coding::RtpFrameObject, std::__1::default_delete<webrtc::video_coding::RtpFrameObject> >) video/rtp_video_stream_receiver.cc:336:22 #11 0x1496f41 in webrtc::video_coding::PacketBuffer::InsertPacket(webrtc::VCMPacket*) modules/video_coding/packet_buffer.cc:130:31 #12 0x1487e59 in webrtc::RtpVideoStreamReceiver::OnReceivedPayloadData(unsigned char const*, unsigned long, webrtc::WebRtcRTPHeader const*) video/rtp_video_stream_receiver.cc:231:19 #13 0x12d9144 in webrtc::RTPReceiverVideo::ParseRtpPacket(webrtc::WebRtcRTPHeader*, webrtc::PayloadUnion const&, unsigned char const*, unsigned long, long) modules/rtp_rtcp/source/rtp_receiver_video.cc:109:26 #14 0x12cc80d in webrtc::RtpReceiverImpl::IncomingRtpPacket(webrtc::RTPHeader const&, unsigned char const*, unsigned long, webrtc::PayloadUnion) modules/rtp_rtcp/source/rtp_receiver_impl.cc:181:42 #15 0x1488e52 in webrtc::RtpVideoStreamReceiver::ReceivePacket(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:399:20 #16 0x1488b03 in webrtc::RtpVideoStreamReceiver::OnRecoveredPacket(unsigned char const*, unsigned long) video/rtp_video_stream_receiver.cc:245:3 #17 0x14b925c in webrtc::UlpfecReceiverImpl::ProcessReceivedFec() modules/rtp_rtcp/source/ulpfec_receiver_impl.cc:244:35 #18 0x148bd42 in webrtc::RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:421:23 #19 0x1488d51 in webrtc::RtpVideoStreamReceiver::ReceivePacket(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:390:5 #20 0x14899f8 in webrtc::RtpVideoStreamReceiver::OnRtpPacket(webrtc::RtpPacketReceived const&) video/rtp_video_stream_receiver.cc:290:3 #21 0x90c486 in webrtc::RtpDemuxer::OnRtpPacket(webrtc::RtpPacketReceived const&) call/rtp_demuxer.cc:157:11 #22 0x9131bd in webrtc::RtpStreamReceiverController::OnRtpPacket(webrtc::RtpPacketReceived const&) call/rtp_stream_receiver_controller.cc:55:19 #23 0x129940d in webrtc::internal::Call::DeliverRtp(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) call/call.cc:1321:36 #24 0x129a8d5 in webrtc::internal::Call::DeliverPacket(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) call/call.cc:1361:10 #25 0x61fe06 in webrtc::RtpReplay() video/replay.cc:279:31 #26 0x62337d in main video/replay.cc:343:3 #27 0x7f5ae03d82b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0) previously allocated by thread T0 here: #0 0x61af72 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 0x14b664f in __libcpp_allocate buildtools/third_party/libc++/trunk/include/new:259:10 #2 0x14b664f in allocate buildtools/third_party/libc++/trunk/include/memory:1799 #3 0x14b664f in allocate buildtools/third_party/libc++/trunk/include/memory:1548 #4 0x14b664f in __construct_node<const short &, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo> buildtools/third_party/libc++/trunk/include/__tree:2191 #5 0x14b664f in std::__1::pair<std::__1::__tree_iterator<std::__1::__value_type<unsigned char, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo>, std::__1::__tree_node<std::__1::__value_type<unsigned char, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo>, void*>*, long>, bool> std::__1::__tree<std::__1::__value_type<unsigned char, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo>, std::__1::__map_value_compare<unsigned char, std::__1::__value_type<unsigned char, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo>, webrtc::DescendingSeqNumComp<unsigned char, (unsigned char)0>, true>, std::__1::allocator<std::__1::__value_type<unsigned char, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo> > >::__emplace_unique_impl<short const&, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo>(short const&, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo&&) buildtools/third_party/libc++/trunk/include/__tree:2203 #6 0x14ab9ca in __emplace_unique<const short &, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo> buildtools/third_party/libc++/trunk/include/__tree:1193:16 #7 0x14ab9ca in emplace<const short &, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo> buildtools/third_party/libc++/trunk/include/map:1041 #8 0x14ab9ca in webrtc::video_coding::RtpFrameReferenceFinder::ManageFrameVp9(webrtc::video_coding::RtpFrameObject*) modules/video_coding/rtp_frame_reference_finder.cc:445 #9 0x14a7849 in ManageFrameInternal modules/video_coding/rtp_frame_reference_finder.cc:89:14 #10 0x14a7849 in webrtc::video_coding::RtpFrameReferenceFinder::ManageFrame(std::__1::unique_ptr<webrtc::video_coding::RtpFrameObject, std::__1::default_delete<webrtc::video_coding::RtpFrameObject> >) modules/video_coding/rtp_frame_reference_finder.cc:43 #11 0x148a87e in non-virtual thunk to webrtc::RtpVideoStreamReceiver::OnReceivedFrame(std::__1::unique_ptr<webrtc::video_coding::RtpFrameObject, std::__1::default_delete<webrtc::video_coding::RtpFrameObject> >) video/rtp_video_stream_receiver.cc:336:22 #12 0x1496f41 in webrtc::video_coding::PacketBuffer::InsertPacket(webrtc::VCMPacket*) modules/video_coding/packet_buffer.cc:130:31 #13 0x1487e59 in webrtc::RtpVideoStreamReceiver::OnReceivedPayloadData(unsigned char const*, unsigned long, webrtc::WebRtcRTPHeader const*) video/rtp_video_stream_receiver.cc:231:19 #14 0x12d9144 in webrtc::RTPReceiverVideo::ParseRtpPacket(webrtc::WebRtcRTPHeader*, webrtc::PayloadUnion const&, unsigned char const*, unsigned long, long) modules/rtp_rtcp/source/rtp_receiver_video.cc:109:26 #15 0x12cc80d in webrtc::RtpReceiverImpl::IncomingRtpPacket(webrtc::RTPHeader const&, unsigned char const*, unsigned long, webrtc::PayloadUnion) modules/rtp_rtcp/source/rtp_receiver_impl.cc:181:42 #16 0x1488e52 in webrtc::RtpVideoStreamReceiver::ReceivePacket(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:399:20 #17 0x1488b03 in webrtc::RtpVideoStreamReceiver::OnRecoveredPacket(unsigned char const*, unsigned long) video/rtp_video_stream_receiver.cc:245:3 #18 0x14b925c in webrtc::UlpfecReceiverImpl::ProcessReceivedFec() modules/rtp_rtcp/source/ulpfec_receiver_impl.cc:244:35 #19 0x148bd42 in webrtc::RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:421:23 #20 0x1488d51 in webrtc::RtpVideoStreamReceiver::ReceivePacket(unsigned char const*, unsigned long, webrtc::RTPHeader const&) video/rtp_video_stream_receiver.cc:390:5 #21 0x14899f8 in webrtc::RtpVideoStreamReceiver::OnRtpPacket(webrtc::RtpPacketReceived const&) video/rtp_video_stream_receiver.cc:290:3 #22 0x90c486 in webrtc::RtpDemuxer::OnRtpPacket(webrtc::RtpPacketReceived const&) call/rtp_demuxer.cc:157:11 #23 0x9131bd in webrtc::RtpStreamReceiverController::OnRtpPacket(webrtc::RtpPacketReceived const&) call/rtp_stream_receiver_controller.cc:55:19 #24 0x129940d in webrtc::internal::Call::DeliverRtp(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) call/call.cc:1321:36 #25 0x129a8d5 in webrtc::internal::Call::DeliverPacket(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) call/call.cc:1361:10 #26 0x61fe06 in webrtc::RtpReplay() video/replay.cc:279:31 #27 0x62337d in main video/replay.cc:343:3 #28 0x7f5ae03d82b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0) SUMMARY: AddressSanitizer: heap-use-after-free modules/video_coding/rtp_frame_reference_finder.cc:569:31 in webrtc::video_coding::RtpFrameReferenceFinder::FrameReceivedVp9(unsigned short, webrtc::video_coding::RtpFrameReferenceFinder::GofInfo*) Shadow bytes around the buggy address: 0x0c0c7fff85e0: 00 00 00 00 00 00 00 fa fa fa fa fa fd fd fd fd 0x0c0c7fff85f0: fd fd fd fd fa fa fa fa 00 00 00 00 00 00 00 00 0x0c0c7fff8600: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa 0x0c0c7fff8610: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00 0x0c0c7fff8620: 00 00 00 00 fa fa fa fa fd fd fd fd fd fd fd fa =>0x0c0c7fff8630: fa fa fa fa fd fd fd fd fd fd[fd]fa fa fa fa fa 0x0c0c7fff8640: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0c7fff8650: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0c7fff8660: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0c7fff8670: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0c7fff8680: 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 Shadow gap: cc ==163231==ABORTING To reproduce the issue: 1) apply new.patch to your webrtc directory 2) build video_replay 3) download the attached filed into the same directory 4) run ./video_replay --input_file uaf Proof of Concept: https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/45443.zip
Webrtc vp9 processing useafterfree Vulnerability / Exploit Source : Webrtc vp9 processing useafterfree