How to Use the Python Malicious SSH Server for libssh2 Exploit (CVE‑2026‑55200)
The PoC Python server mimics a legitimate libssh2 handshake, derives identical encryption keys, and transmits a malformed encrypted packet with packet_length set to 0xffffffff to trigger an integer overflow and out-of-bounds write in vulnerable clients.
The bikini/exploitarium repository provides a complete proof-of-concept implementation for CVE‑2026‑55200, a critical vulnerability in libssh2 versions ≤ 1.11.1. This guide explains how to deploy the Python malicious SSH server to exploit the flawed arithmetic handling in libssh2's packet processing logic, enabling security researchers and penetration testers to reproduce the remote code execution vector in controlled environments.
Technical Overview of the Exploit
The Vulnerability (CVE‑2026‑55200)
The vulnerability exists in libssh2's packet length validation logic. When processing an encrypted SSH packet, the library accepts packet_length values ≥ 1, but the subsequent total-size calculation wraps in 32‑bit arithmetic. This produces an allocation of only 19 bytes while the actual packet_length remains 0xffffffff. Later processing uses the original uncapped length, causing an out-of-bounds write that can be leveraged for remote code execution.
The Attack Vector
The malicious server exploits this by sending a properly encrypted packet that decrypts to the malformed length field. Because the server implements the exact X25519 key exchange and ChaCha20‑Poly1305 encryption used by libssh2, the victim client accepts the packet as legitimate before triggering the vulnerable code path.
How the Malicious SSH Server Works
The implementation in libssh2-cve-2026-55200-poc/poc/libpwn_cve_2026_55200_server.py executes four distinct phases to compromise the target.
Phase 1: SSH Banner Exchange
The server initiates the connection by sending a SERVER_IDENT banner and reading the client's identification string. This establishes the SSH transport layer and prepares both sides for algorithm negotiation.
Phase 2: KEXINIT Negotiation
During key exchange initialization, the server advertises curve25519-sha256 for key exchange, RSA for host key authentication, and chacha20-poly1305@openssh.com for symmetric encryption. The protocol naturally selects the first mutually supported algorithm, ensuring compatibility with standard libssh2 clients.
Phase 3: Key Derivation
The server generates an ephemeral X25519 key pair and computes the shared secret with the client's public key. It constructs the exchange hash, signs it with a freshly generated RSA host key, and derives symmetric keys using libssh2's exact key-derivation formula implemented in derive_key(). This ensures the ChaCha20‑Poly1305 keys match what the victim client expects.
Phase 4: Trigger Packet Delivery
The server constructs the attack payload through two functions:
build_malformed_plain()– Creates a plaintext packet with the attacker-controlledpacket_lengthfield (default0xffffffff)build_malformed_wire()– Encrypts the payload usingchachapoly_encrypt()with the derived session keys
The encrypted fragment is sent as a standard SSH binary packet, followed by optional filler bytes to pad the TCP stream. When the vulnerable libssh2 client decrypts and processes this message, it allocates the undersized 19‑byte buffer and subsequently writes beyond its bounds.
Running the Python Malicious SSH Server
The script supports three operational modes for different testing scenarios.
Self-Test Mode
Verify that the cryptographic primitives and 32‑bit arithmetic model match the vulnerable libssh2 behavior without network interaction.
python poc/libpwn_cve_2026_55200_server.py --self-test
Loopback Test Mode
Run a complete end‑to‑end test using a local socketpair to confirm handshake compatibility and trigger delivery.
python poc/libpwn_cve_2026_55200_server.py --loopback-test --hold-open 0
Serve Mode (Remote Exploitation)
Launch the malicious server to accept connections from remote libssh2 clients, such as CTF challenges or HTB machines.
python poc/libpwn_cve_2026_55200_server.py --serve \
--listen-host 0.0.0.0 \
--listen-port 2222 \
--packet-length 0xffffffff \
--body-len 8 \
--filler-len 64
Command-Line Arguments
The server behavior can be fine-tuned using these parameters:
--packet-length– The 32‑bit value used for the maliciouspacket_lengthfield (default:0xffffffff)--body-len– Length of the encrypted payload after the 4‑byte length field (default: 8)--filler-len– Extra bytes appended after the valid encrypted fragment to pad the TCP stream (default: 64)--timeout– Socket timeout in seconds (default: 10.0)--hold-open– Duration the server remains open after sending the trigger, allowing the client to process the response (default: 1.0)
Code Examples
Customize the exploit parameters to evade detection or test specific boundary conditions:
Modify the packet length to test different overflow conditions:
python poc/libpwn_cve_2026_55200_server.py --serve \
--listen-host 127.0.0.1 \
--listen-port 2222 \
--packet-length 0xdeadbeef
Increase filler size to blend with legitimate traffic:
python poc/libpwn_cve_2026_55200_server.py --serve \
--listen-host 0.0.0.0 \
--listen-port 2222 \
--filler-len 256
Key Source Files
The repository contains several critical components for understanding and executing the exploit:
libpwn_cve_2026_55200_server.py– The main Python malicious SSH server implementing the handshake and trigger generationcve_2026_55200_probe.c– C arithmetic verifier that reproduces the vulnerable allocation logic for validationlibpwn_local_rce_harness.c– Controlled target binary used by the local exploit driverlibpwn_local_rce_exploit.py– Python driver demonstrating full remote code execution against the harness
Summary
- The Python malicious SSH server exploits CVE‑2026‑55200 by sending a malformed encrypted packet with
packet_lengthset to0xffffffff - The server implements authentic X25519 key exchange and ChaCha20‑Poly1305 encryption to establish a valid SSH session before triggering the vulnerability
- Three operational modes support self-testing, loopback validation, and remote exploitation against libssh2 clients ≤ 1.11.1
- The integer overflow causes a 19‑byte allocation against a 4‑GB logical packet size, resulting in a controllable out-of-bounds write
- All cryptographic operations use the cryptography library to match libssh2's exact key derivation formulas
Frequently Asked Questions
What versions of libssh2 are vulnerable to this exploit?
Versions of libssh2 up to and including 1.11.1 contain the vulnerable arithmetic handling in packet processing. The flaw exists in the 32‑bit size calculation that wraps around when processing large packet_length values, specifically accepting values ≥ 1 while failing to validate against realistic buffer constraints.
How does the server derive the same encryption keys as the client?
The implementation uses the standard SSH key exchange protocol (curve25519-sha256) and derives symmetric keys using the exact formula specified in RFC 4253 and implemented in libssh2's derive_key() function. The server generates a fresh RSA host key for each session, computes the X25519 shared secret, and applies the same hash-based key derivation to produce identical ChaCha20‑Poly1305 keys.
Can this exploit be detected by network monitoring tools?
The malicious traffic appears as standard SSH protocol data during the initial handshake. The trigger packet itself is properly encrypted with valid session keys, making deep packet inspection challenging unless the monitoring tool specifically decrypts the SSH stream or detects the anomalous packet size mismatch after decryption. The optional --filler-len parameter adds legitimate-looking padding to further obfuscate the attack.
What is the difference between loopback-test and serve mode?
The loopback-test mode creates an internal socketpair connection within a single Python process, allowing rapid validation of the cryptographic implementation and trigger mechanism without network exposure. The serve mode binds to a TCP address and accepts external connections from actual libssh2 clients, enabling exploitation of remote services or testing of specific client configurations in lab environments.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →