
Crash-only laboratory reproducer for CVE-2025-69420 in OpenSSL. The PoC loads a valid RFC 3161 TimeStamp Response, changes the signed ESS attribute from V_ASN1_SEQUENCE to V_ASN1_NULL in memory, and calls TS_RESP_verify_response().
On an affected build, ossl_ess_get_signing_cert_v2() or ossl_ess_get_signing_cert() accesses the ASN1_TYPE union as a sequence without validating the active type. UBSan reports member access through a null ASN1_STRING pointer. The expected impact is process termination / denial of service; this repository contains no code-execution logic.
The supplied test output confirms the issue:
runtime error: member access within null pointer of type 'struct ASN1_STRING'
#0 ossl_ess_get_signing_cert_v2
#1 ts_check_signing_certs
#2 TS_RESP_verify_signature
#3 int_ts_RESP_verify_token
#4 TS_RESP_verify_response
This matches the vulnerability description: a malformed TimeStamp Response reaches TS_RESP_verify_response(), and an ESS signing-certificate attribute of a type other than V_ASN1_SEQUENCE causes an invalid or NULL pointer dereference.
Test only in an isolated environment against an OpenSSL build you own or are authorized to assess. This is a crash-only reproducer.
Default build path:
/path/to/openssl-3.0.7-asan
Override it when needed:
export OPENSSL_BUILD=/path/to/openssl-asan-build
git clone https://github.com/Kha-Beleh/PoC-CVE-2025-69420.git
cd PoC-CVE-2025-69420
export OPENSSL_BUILD=/path/to/openssl-3.0.7-asan
make prepare
make build
make run
Or run everything separately:
./scripts/prepare.sh
./scripts/build.sh
./scripts/run.sh
prepare.sh uses the repository's minimal openssl.cnf, so it does not depend on a missing $OPENSSL_BUILD/ssl/openssl.cnf.
[+] Loaded valid TimeStamp Response
[+] Found attribute: id-smime-aa-signingCertificateV2
[+] Original ASN.1 type: 16
[+] Attribute changed to V_ASN1_NULL
[+] Calling TS_RESP_verify_response()
crypto/ts/ts_rsp_verify.c:...: runtime error: member access within null pointer of type 'struct ASN1_STRING'
#0 ... in ossl_ess_get_signing_cert_v2
#1 ... in ts_check_signing_certs
#2 ... in TS_RESP_verify_signature
#3 ... in int_ts_RESP_verify_token
#4 ... in TS_RESP_verify_response
The exact addresses and line numbers vary by build. With UBSAN_OPTIONS=halt_on_error=1, the process terminates at the first detected undefined operation.
The malformed attribute should be rejected cleanly without a sanitizer finding or process crash. The PoC then prints:
[+] Malformed response rejected without a crash
The original attribute type value 16 is V_ASN1_SEQUENCE. The PoC changes it to V_ASN1_NULL. In the affected implementation, the code subsequently treats the union member as value.sequence and dereferences it. Because the active member is not a sequence, UBSan detects member access through a null ASN1_STRING *.
This is a type-confusion / missing exceptional-condition check rather than a heap or stack buffer overflow.
poc.c — minimal reproducerscripts/prepare.sh — generates TSA key, certificate, request and valid responsescripts/build.sh — compiles against the ASan/UBSan OpenSSL buildscripts/run.sh — runs with sanitizer settingsopenssl.cnf — minimal provider/request configurationtsa.conf — local RFC 3161 TSA configurationevidence/confirmed-output.txt — shortened confirmed sanitizer trace4e254b48ad93cc092be3dd62d97015f33f73133a