Bug description
Describe the bug
An out-of-bounds read vulnerability exists in the Telnet protocol parsing module of PcapPlusPlus. When processing truncated and malformed Telnet subnegotiation packets, the getSubCommand function accesses memory at offset 2 without rigorous buffer length verification. This invalid heap memory access triggers heap buffer overflow read error, which can cause program crash and lead to denial of service attack risk.
Cause
The function accesses pos[2] without validating sufficient buffer length (TelnetLayer.cpp:206-211):
int16_t TelnetLayer::getSubCommand(uint8_t* pos, size_t len)
{
if (len < 3 || pos[1] < static_cast<int>(TelnetCommand::Subnegotiation))
return TelnetOptionNoOption;
return pos[2]; // line 210: OUT-OF-BOUNDS READ
}
When a truncated Telnet packet is parsed:
len is 1 or 2
- The condition
len < 3 is not properly enforced
- The code reads
pos[2] out of bounds
To Reproduce
Steps to reproduce the behavior:
- Clone the pcapplusplus repository and build it refer to oss-fuzz.
export CC=clang \
CXX=clang++ \
CFLAGS='-fsanitize=address -O0 -g' \
CXXFLAGS='-fsanitize=address -O0 -g' \
LIB_FUZZING_ENGINE='-fsanitize=fuzzer'
- Run the PoC using FuzzTarget:
poc.zip
The PoC is provided as a zip archive. After extracting, run:
ASAN Report
~/fuzz$ ./fuzzers/FuzzTarget ./crashes/poc
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3766770891
./fuzzers/FuzzTarget: Running 1 inputs 1 time(s) each.
Running: ./crashes/poc
Read 0 packets successfully and 0 packets could not be read
Ethernet II Layer, Src: 00:00:c0:9f:a0:97, Dst: 00:a0:cc:3b:bf:fa
IPv4 Layer, Src: 192.168.0.1, Dst: 192.168.0.2
TCP Layer, [ACK], Src port: 23, Dst port: 1550
Telnet Control
Telnet command is 'Will Perform'
Telnet option is 'Suppress Go Ahead'
Telnet command is 'Do Perform'
Telnet option is 'Terminal Type'
Telnet command is 'Do Perform'
Telnet option is 'Negotiate About Window Size'
Telnet command is 'Do Perform'
Telnet option is 'Terminal Speed'
Telnet command is 'Do Perform'
Telnet option is 'Remote Flow Control'
Telnet command is 'Do Perform'
Telnet option is 'Line mode'
Telnet command is 'Subnegotiation'
Telnet option is 'Line mode'
Telnet command is 'Subnegotiation End'
Telnet option is 'No option for this command'
Telnet command is 'Reached end of packet while parsing'
Telnet option is 'No option for this command'
Ethernet II Layer, Src: 00:00:c0:9f:a0:97, Dst: 00:a0:cc:3b:bf:fa
IPv4 Layer, Src: 192.168.0.1, Dst: 192.168.0.2
TCP Layer, [ACK], Src port: 23, Dst port: 1550
Telnet Data
Telnet command is 'Will Perform'
Telnet option is 'Suppress Go Ahead'
Telnet command is 'Do Perform'
Telnet option is 'Terminal Type'
Telnet command is 'Do Perform'
=================================================================
==3543760==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50b000001b72 at pc 0x5634e6576295 bp 0x7fff743f1350 sp 0x7fff743f1348
READ of size 1 at 0x50b000001b72 thread T0
#0 0x5634e6576294 in pcpp::TelnetLayer::getSubCommand(unsigned char*, unsigned long) /home/hexijie/fuzz/project/PcapPlusPlus/Packet++/src/TelnetLayer.cpp:210:10
#1 0x5634e6576294 in pcpp::TelnetLayer::getOption() /home/hexijie/fuzz/project/PcapPlusPlus/Packet++/src/TelnetLayer.cpp:349:37
#2 0x5634e6405831 in readParsedPacket(pcpp::Packet, pcpp::Layer*) /home/hexijie/fuzz/project/PcapPlusPlus/Tests/Fuzzers/ReadParsedPacket.h:42:59
#3 0x5634e64048e9 in LLVMFuzzerTestOneInput /home/hexijie/fuzz/project/PcapPlusPlus/Tests/Fuzzers/FuzzTarget.cpp:66:5
#4 0x5634e630f0c4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x1160c4) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
#5 0x5634e62f81f6 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0xff1f6) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
#6 0x5634e62fdcaa in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x104caa) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
#7 0x5634e6328466 in main (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x12f466) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
#8 0x7f6534c2a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#9 0x7f6534c2a28a in __libc_start_main csu/../csu/libc-start.c:360:3
#10 0x5634e62f2dc4 in _start (/home/hexijie/fuzz/fuzzers/FuzzTarget+0xf9dc4) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
0x50b000001b72 is located 0 bytes after 98-byte region [0x50b000001b10,0x50b000001b72)
allocated by thread T0 here:
#0 0x5634e6401911 in operator new[](unsigned long) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x208911) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
#1 0x5634e6411002 in std::__detail::_MakeUniq<unsigned char []>::__array std::make_unique<unsigned char []>(unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:1085:30
#2 0x5634e6411002 in pcpp::PcapFileReaderDevice::getNextPacket(pcpp::RawPacket&) /home/hexijie/fuzz/project/PcapPlusPlus/Pcap++/src/PcapFileDevice.cpp:475:23
#3 0x5634e64049b4 in LLVMFuzzerTestOneInput /home/hexijie/fuzz/project/PcapPlusPlus/Tests/Fuzzers/FuzzTarget.cpp:71:19
#4 0x5634e630f0c4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x1160c4) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
#5 0x5634e62f81f6 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0xff1f6) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
#6 0x5634e62fdcaa in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x104caa) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
#7 0x5634e6328466 in main (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x12f466) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
#8 0x7f6534c2a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#9 0x7f6534c2a28a in __libc_start_main csu/../csu/libc-start.c:360:3
#10 0x5634e62f2dc4 in _start (/home/hexijie/fuzz/fuzzers/FuzzTarget+0xf9dc4) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/hexijie/fuzz/project/PcapPlusPlus/Packet++/src/TelnetLayer.cpp:210:10 in pcpp::TelnetLayer::getSubCommand(unsigned char*, unsigned long)
Shadow bytes around the buggy address:
0x50b000001880: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
0x50b000001900: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa
0x50b000001980: fa fa fa fa fa fa fd fd fd fd fd fd fd fd fd fd
0x50b000001a00: fd fd fd fa fa fa fa fa fa fa fa fa fd fd fd fd
0x50b000001a80: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa
=>0x50b000001b00: fa fa 00 00 00 00 00 00 00 00 00 00 00 00[02]fa
0x50b000001b80: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x50b000001c00: fd fd fd fd fd fa fa fa fa fa fa fa fa fa fd fd
0x50b000001c80: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa
0x50b000001d00: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x50b000001d80: fd fa fa fa fa fa fa fa fa fa 00 00 00 00 00 00
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
==3543760==ABORTING
PcapPlusPlus versions tested on
v25.05
Other PcapPlusPlus version (if applicable)
No response
Operating systems tested on
Linux
Other operation systems (if applicable)
No response
Compiler version
Ubuntu clang version 18.1.3 (1ubuntu1)
Packet capture backend (if applicable)
No response
Bug description
Describe the bug
An out-of-bounds read vulnerability exists in the Telnet protocol parsing module of PcapPlusPlus. When processing truncated and malformed Telnet subnegotiation packets, the
getSubCommandfunction accesses memory at offset 2 without rigorous buffer length verification. This invalid heap memory access triggers heap buffer overflow read error, which can cause program crash and lead to denial of service attack risk.Cause
The function accesses
pos[2]without validating sufficient buffer length (TelnetLayer.cpp:206-211):When a truncated Telnet packet is parsed:
lenis 1 or 2len < 3is not properly enforcedpos[2]out of boundsTo Reproduce
Steps to reproduce the behavior:
poc.zip
The PoC is provided as a zip archive. After extracting, run:
ASAN Report
PcapPlusPlus versions tested on
v25.05
Other PcapPlusPlus version (if applicable)
No response
Operating systems tested on
Linux
Other operation systems (if applicable)
No response
Compiler version
Ubuntu clang version 18.1.3 (1ubuntu1)
Packet capture backend (if applicable)
No response