Skip to content

Heap-Buffer-Overflow in SSLClientHelloMessage::getHandshakeVersion() #2151

@TYGLS

Description

@TYGLS

Bug description

Describe the bug

A heap-buffer-overflow vulnerability was found in pcpp::SSLClientHelloMessage::getHandshakeVersion() const in Packet++/src/SSLHandshake.cpp:1453.

The function calls getClientHelloHeader()->handshakeVersion without checking if the packet data is large enough to contain a full TLS Client Hello header. When parsing a truncated/malformed TLS Client Hello packet, this causes an out-of-bounds read of 2 bytes on the heap.

To Reproduce
Steps to reproduce the behavior:

  1. 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'
  1. Run the PoC using FuzzTarget:

poc.zip

The PoC is provided as a zip archive. After extracting, run:

./FuzzTarget ./poc

ASAN Report

~/fuzz$ ./fuzzers/FuzzTarget ./crashes/poc 
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3241109910
./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:12:3f:97:92:01, Dst: 33:33:00:00:00:16
IPv6 Layer, Src: fe80::9c09:b416:768:ff42, Dst: ff02::16, Options=[Hop-By-Hop]
ICMPv6 Layer, Message type: 143
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 01:00:5e:00:00:02
IPv4 Layer, Src: 169.254.255.66, Dst: 224.0.0.2
IGMPv2 Layer, Leave Group message
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 33:33:00:00:00:16
IPv6 Layer, Src: fe80::9c09:b416:768:ff42, Dst: ff02::16, Options=[Hop-By-Hop]
ICMPv6 Layer, Message type: 143
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 01:00:5e:00:00:fc
IPv4 Layer, Src: 169.254.255.66, Dst: 224.0.0.252
IGMPv2 Layer, Membership Report message
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 33:33:00:01:00:03
IPv6 Layer, Src: fe80::9c09:b416:768:ff42, Dst: ff02::1:3
UDP Layer, Src port: 52507, Dst port: 5355
DNS query, ID: 53448; queries: 1, answers: 0, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 01:00:5e:00:00:fc
IPv4 Layer, Src: 169.254.255.66, Dst: 224.0.0.252
UDP Layer, Src port: 61575, Dst port: 5355
DNS query, ID: 53448; queries: 1, answers: 0, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 01:00:5e:00:00:fc
IPv4 Layer, Src: 169.254.255.66, Dst: 224.0.0.252
IGMPv2 Layer, Membership Report message
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 33:33:00:00:00:16
IPv6 Layer, Src: fe80::9c09:b416:768:ff42, Dst: ff02::16, Options=[Hop-By-Hop]
ICMPv6 Layer, Message type: 143
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 33:33:00:01:00:03
IPv6 Layer, Src: fe80::9c09:b416:768:ff42, Dst: ff02::1:3
UDP Layer, Src port: 52507, Dst port: 5355
DNS query, ID: 53448; queries: 1, answers: 0, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 01:00:5e:00:00:fc
IPv4 Layer, Src: 169.254.255.66, Dst: 224.0.0.252
UDP Layer, Src port: 61575, Dst port: 5355
DNS query, ID: 53448; queries: 1, answers: 0, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 33:33:00:01:00:03
IPv6 Layer, Src: fe80::9c09:b416:768:ff42, Dst: ff02::1:3
UDP Layer, Src port: 57487, Dst port: 5355
DNS query, ID: 32204; queries: 1, answers: 0, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 01:00:5e:00:00:fc
IPv4 Layer, Src: 169.254.255.66, Dst: 224.0.0.252
UDP Layer, Src port: 63237, Dst port: 5355
DNS query, ID: 32204; queries: 1, answers: 0, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:22:19:22:54:9e, Dst: 00:12:3f:97:92:01
IPv4 Layer, Src: 169.254.100.98, Dst: 169.254.255.66
UDP Layer, Src port: 5355, Dst port: 63237
DNS query response, ID: 32204; queries: 1, answers: 1, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 01:00:5e:00:00:fc
IPv4 Layer, Src: 169.254.255.66, Dst: 224.0.0.252
UDP Layer, Src port: 58000, Dst port: 5355
DNS query, ID: 37003; queries: 1, answers: 0, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:22:19:22:54:9e, Dst: 00:12:3f:97:92:01
IPv4 Layer, Src: 169.254.100.98, Dst: 169.254.255.66
UDP Layer, Src port: 5355, Dst port: 58000
DNS query response, ID: 37003; queries: 1, answers: 0, authorities: 1, additional record: 0
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 33:33:00:01:00:03
IPv6 Layer, Src: fe80::9c09:b416:768:ff42, Dst: ff02::1:3
UDP Layer, Src port: 59133, Dst port: 5355
DNS query, ID: 63084; queries: 1, answers: 0, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 01:00:5e:00:00:fc
IPv4 Layer, Src: 169.254.255.66, Dst: 224.0.0.252
UDP Layer, Src port: 50745, Dst port: 5355
DNS query, ID: 63084; queries: 1, answers: 0, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:22:19:22:54:9e, Dst: 00:12:3f:97:92:01
IPv4 Layer, Src: 169.254.100.98, Dst: 169.254.255.66
UDP Layer, Src port: 5355, Dst port: 50745
DNS query response, ID: 63084; queries: 1, answers: 1, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 01:00:5e:00:00:fc
IPv4 Layer, Src: 169.254.255.66, Dst: 224.0.0.252
UDP Layer, Src port: 57762, Dst port: 5355
DNS query, ID: 6452; queries: 1, answers: 0, authorities: 0, additional record: 0
Ethernet II Layer, Src: 00:22:19:22:54:9e, Dst: 00:12:3f:97:92:01
IPv4 Layer, Src: 169.254.100.98, Dst: 169.254.255.66
UDP Layer, Src port: 5355, Dst port: 57762
DNS query response, ID: 6452; queries: 1, answers: 0, authorities: 1, additional record: 0
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 00:22:19:22:54:9e
IPv4 Layer, Src: 169.254.255.66, Dst: 169.254.100.98
TCP Layer, [SYN], Src port: 52926, Dst port: 443
Ethernet II Layer, Src: 00:22:19:22:54:9e, Dst: 00:12:3f:97:92:01
IPv4 Layer, Src: 169.254.100.98, Dst: 169.254.255.66
TCP Layer, [SYN, ACK], Src port: 443, Dst port: 52926
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 00:22:19:22:54:9e
IPv4 Layer, Src: 169.254.255.66, Dst: 169.254.100.98
TCP Layer, [ACK], Src port: 52926, Dst port: 443
Ethernet II Layer, Src: 00:12:3f:97:92:01, Dst: 00:22:19:22:54:9e
IPv4 Layer, Src: 169.254.255.66, Dst: 169.254.100.98
TCP Layer, [ACK], Src port: 52926, Dst port: 443
TLS 1.0 Layer, Handshake: Client Hello message
Ethernet II Layer, Src: 00:22:19:22:54:9e, Dst: 00:12:3f:97:92:01
IPv4 Layer, Src: 169.254.100.98, Dst: 169.254.255.66
TCP Layer, [ACK], Src port: 443, Dst port: 52926
TLS 1.0 Layer, Handshake: Server Hello message, Certificate message, Client Hello message
=================================================================
==2704324==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5180000003b8 at pc 0x55d9e8815470 bp 0x7ffcb9e1e400 sp 0x7ffcb9e1e3f8
READ of size 2 at 0x5180000003b8 thread T0
    #0 0x55d9e881546f in pcpp::SSLClientHelloMessage::getHandshakeVersion() const /home/hexijie/fuzz/project/PcapPlusPlus/Packet++/src/SSLHandshake.cpp:1453:31
    #1 0x55d9e86c4b37 in readParsedPacket(pcpp::Packet, pcpp::Layer*) /home/hexijie/fuzz/project/PcapPlusPlus/Tests/Fuzzers/ReadParsedPacket.h:239:25
    #2 0x55d9e86c28e9 in LLVMFuzzerTestOneInput /home/hexijie/fuzz/project/PcapPlusPlus/Tests/Fuzzers/FuzzTarget.cpp:66:5
    #3 0x55d9e85cd0c4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x1160c4) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
    #4 0x55d9e85b61f6 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0xff1f6) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
    #5 0x55d9e85bbcaa in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x104caa) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
    #6 0x55d9e85e6466 in main (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x12f466) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
    #7 0x7fb86762a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #8 0x7fb86762a28a in __libc_start_main csu/../csu/libc-start.c:360:3
    #9 0x55d9e85b0dc4 in _start (/home/hexijie/fuzz/fuzzers/FuzzTarget+0xf9dc4) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)

0x5180000003b8 is located 0 bytes after 824-byte region [0x518000000080,0x5180000003b8)
allocated by thread T0 here:
    #0 0x55d9e86bf911 in operator new[](unsigned long) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x208911) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
    #1 0x55d9e86cf002 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 0x55d9e86cf002 in pcpp::PcapFileReaderDevice::getNextPacket(pcpp::RawPacket&) /home/hexijie/fuzz/project/PcapPlusPlus/Pcap++/src/PcapFileDevice.cpp:475:23
    #3 0x55d9e86c29b4 in LLVMFuzzerTestOneInput /home/hexijie/fuzz/project/PcapPlusPlus/Tests/Fuzzers/FuzzTarget.cpp:71:19
    #4 0x55d9e85cd0c4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x1160c4) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
    #5 0x55d9e85b61f6 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0xff1f6) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
    #6 0x55d9e85bbcaa in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x104caa) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
    #7 0x55d9e85e6466 in main (/home/hexijie/fuzz/fuzzers/FuzzTarget+0x12f466) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)
    #8 0x7fb86762a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #9 0x7fb86762a28a in __libc_start_main csu/../csu/libc-start.c:360:3
    #10 0x55d9e85b0dc4 in _start (/home/hexijie/fuzz/fuzzers/FuzzTarget+0xf9dc4) (BuildId: a4a415ba67789b2d8c736acb1b373274c76440c3)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/hexijie/fuzz/project/PcapPlusPlus/Packet++/src/SSLHandshake.cpp:1453:31 in pcpp::SSLClientHelloMessage::getHandshakeVersion() const
Shadow bytes around the buggy address:
  0x518000000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x518000000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x518000000200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x518000000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x518000000300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x518000000380: 00 00 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa
  0x518000000400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x518000000480: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x518000000500: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x518000000580: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x518000000600: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
==2704324==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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions