What functions and functionality is relevant?

The Subject Alternative Names parsing functionality in ./libfreerdp/crypto/x509_utils.c, specifically x509_validate_subject_aternative_names.

Why is this vulnerable?

The code is vulnerable due to a mismatch between memory allocation and copying processes

Is this a replay and/or is inspired by anything?

This challenge was inspired by other parsing vulnerabilities within x509.

What makes it interesting?

This vulnerability should be difficult to fuzz or make a PoV for, however the fix for it is quite simple

Additional Information, Overview

FreeRDP is an open-source Remote Desktop Protocol (RDP) client that enables users to connect to Windows, Linux, and other RDP-compatible systems. It provides a lightweight, cross-platform, and extensible implementation of Microsoft’s RDP, allowing seamless remote access with support for advanced authentication, multimedia redirection, USB forwarding, and clipboard sharing.

An X.509 certificate is a digital certificate standard used for authentication, encryption, and digital signatures in TLS/SSL, PKI (Public Key Infrastructure), and secure communications. It binds a public key to an identity (such as a domain name, organization, or individual) and is issued by a Certificate Authority (CA). X.509 certificates contain metadata, including the subject, issuer, validity period, cryptographic algorithms, and extensions like certificate policies and Subject Alternative Names (SANs). They are widely used in HTTPS, VPNs, email encryption, and code signing to ensure data integrity and trust.

Certificate policies in an X.509 certificate define the rules and guidelines under which the certificate was issued and how it should be used. Represented as Object Identifiers (OIDs) in the certificatePolicies extension, they specify compliance with industry standards, regulatory frameworks, or specific Certificate Authority (CA) policies. Policies may include Extended Validation (EV) requirements, government or financial sector restrictions, and Certification Practice Statement (CPS) references. These policies help relying parties determine the trustworthiness and intended use of a certificate.

Vulnerability

###Subject Alternative Names (SAN) in X.509 Certificates

The Subject Alternative Name (SAN) extension in an X.509 certificate allows a certificate to be valid for multiple identities beyond the Common Name (CN). SAN can include DNS names, IP addresses, email addresses, and URIs, making it essential for multi-domain SSL/TLS certificates, wildcard certificates, and securing multiple services under one certificate. The SAN field is now the preferred method for hostname validation, as the CN field is deprecated for this purpose.

This vulnerability arises when memory is allocated using a length field calculated strlen(), which measures the length of a string without the null terminator, but later memcpy() is used with a different length as specified in the X.509 certificate format, resulting in copying more data than allocated. This is a common mismatch that leads to heap corruption.

While this wouldn’t be a difficult to find bug when fuzzing with a dedicated context-aware smart fuzzer, the requirement to follow fairly strict format specifications with the X.509 certificate parsing as well as with correct base 64 encoding makes it an interesting challenge for the LLM to overcome.

Example crash

=================================================================
==14==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5020000009b5 at pc 0x56539c800e44 bp 0x7ffec96d0320 sp 0x7ffec96cfae0
WRITE of size 20 at 0x5020000009b5 thread T0
SCARINESS: 45 (multi-byte-write-heap-buffer-overflow)
    #0 0x56539c800e43 in __asan_memcpy /src/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:63:3
    #1 0x56539c852e78 in x509_validate_subject_aternative_names /src/FreeRDP/libfreerdp/crypto/x509_utils.c:457:4
    #2 0x56539c84769e in freerdp_rsa_from_x509 /src/FreeRDP/libfreerdp/crypto/certificate.c:1259:7
    #3 0x56539c847ac1 in freerdp_certificate_new_from_x509 /src/FreeRDP/libfreerdp/crypto/certificate.c:1341:7
    #4 0x56539c847ac1 in freerdp_certificate_new_from /src/FreeRDP/libfreerdp/crypto/certificate.c:1358:25
    #5 0x56539c840ba8 in freerdp_certificate_data_new_from_pem /src/FreeRDP/libfreerdp/crypto/certificate_data.c:154:25
    #6 0x56539c840277 in LLVMFuzzerTestOneInput /src/FreeRDP/libfreerdp/core/test/TestFuzzCryptoCertificateDataSetPEM.c:13:9
    #7 0x56539c6f70f0 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
    #8 0x56539c6e2365 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:327:6
    #9 0x56539c6e7dff in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:862:9
    #10 0x56539c7130a2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #11 0x7f0ca2390082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0323ab4806bee6f846d9ad4bccfc29afdca49a58)
    #12 0x56539c6da54d in _start (/out/TestFuzzCryptoCertificateDataSetPEM+0xcb54d)

DEDUP_TOKEN: __asan_memcpy--x509_validate_subject_aternative_names--freerdp_rsa_from_x509
0x5020000009b5 is located 0 bytes after 5-byte region [0x5020000009b0,0x5020000009b5)
allocated by thread T0 here:
    #0 0x56539c802ebf in malloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:68:3
    #1 0x56539c852e2b in x509_validate_subject_aternative_names /src/FreeRDP/libfreerdp/crypto/x509_utils.c:452:15
    #2 0x56539c84769e in freerdp_rsa_from_x509 /src/FreeRDP/libfreerdp/crypto/certificate.c:1259:7
    #3 0x56539c847ac1 in freerdp_certificate_new_from_x509 /src/FreeRDP/libfreerdp/crypto/certificate.c:1341:7
    #4 0x56539c847ac1 in freerdp_certificate_new_from /src/FreeRDP/libfreerdp/crypto/certificate.c:1358:25
    #5 0x56539c840ba8 in freerdp_certificate_data_new_from_pem /src/FreeRDP/libfreerdp/crypto/certificate_data.c:154:25
    #6 0x56539c840277 in LLVMFuzzerTestOneInput /src/FreeRDP/libfreerdp/core/test/TestFuzzCryptoCertificateDataSetPEM.c:13:9
    #7 0x56539c6f70f0 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
    #8 0x56539c6e2365 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:327:6
    #9 0x56539c6e7dff in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:862:9
    #10 0x56539c7130a2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #11 0x7f0ca2390082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0323ab4806bee6f846d9ad4bccfc29afdca49a58)

DEDUP_TOKEN: __interceptor_malloc--x509_validate_subject_aternative_names--freerdp_rsa_from_x509
SUMMARY: AddressSanitizer: heap-buffer-overflow /src/FreeRDP/libfreerdp/crypto/x509_utils.c:457:4 in x509_validate_subject_aternative_names
Shadow bytes around the buggy address:
  0x502000000700: fa fa 00 03 fa fa 00 06 fa fa 00 00 fa fa 00 fa
  0x502000000780: fa fa fd fa fa fa fd fd fa fa fd fd fa fa fd fd
  0x502000000800: fa fa fd fa fa fa 00 00 fa fa 00 fa fa fa 06 fa
  0x502000000880: fa fa 05 fa fa fa 00 00 fa fa 00 00 fa fa 00 00
  0x502000000900: fa fa 00 00 fa fa 00 00 fa fa 05 fa fa fa 00 00
=>0x502000000980: fa fa 05 fa fa fa[05]fa fa fa fa fa fa fa fa fa
  0x502000000a00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000000a80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000000b00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000000b80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000000c00: 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
==14==ABORTING