How to Build the libssh2 CVE-2026-55200 C11 Arithmetic Verifier

Compile the cve_2026_55200_probe.c verifier with gcc -std=c11 and run it with --packet-length 0xffffffff --mac-len 0 --auth-len 16 to reproduce the 32-bit integer overflow that causes CVE-2026-55200.

The arithmetic verifier in the bikini/exploitarium repository provides a lightweight, standalone way to validate the integer-overflow vulnerability designated CVE-2026-55200 in libssh2. This tool does not require linking against libssh2 itself—it simply reimplements the exact arithmetic that the library performs in src/transport.c:ssh2_transport_read(). By building and running this C11 program, security researchers can confirm how a maliciously crafted packet triggers an undersized allocation despite appearing to pass bounds checks.

What CVE-2026-55200 Does to libssh2's Arithmetic

The vulnerability stems from how libssh2 computes buffer sizes before allocation.

In src/transport.c:ssh2_transport_read(), the code constructs the allocation size as follows:

total_num = 4
total_num += packet_length + mac_len + auth_len
if (total_num > LIBSSH2_PACKET_MAXPAYLOAD) reject
allocate total_num bytes

When packet_length = 0xffffffff, mac_len = 0, and auth_len = 16, the 32-bit addition wraps to 15. Adding the constant 4 yields an allocation of only 19 bytes, even though the original packet claims to be 4 GB. The upstream fix inserts a pre-check (packet_length > LIBSSH2_PACKET_MAXPAYLOAD) before the arithmetic occurs.

The Four Arithmetic Models in the Verifier

The cve_2026_55200_probe.c file implements four distinct models to isolate the bug:

  • vulnerable32 — Mirrors the original 32-bit arithmetic, reproducing the overflow.
  • fixed32 — Adds the pre-check from the upstream patch.
  • native_unpatched — Uses native size_t without the guard, showing the same overflow on 64-bit hosts when the intermediate expression wraps.
  • native_fixed — Uses native size_t with the pre-check, representing the safe code path.

Each model populates a struct calc_result containing packet_length, intermediate totals, final allocation length, and a return code (POC_OK, POC_ERROR_DECRYPT, or POC_ERROR_OUT_OF_BOUNDARY).

Build Instructions for the CVE-2026-55200 Verifier

The verifier requires only a C11-compliant compiler. No external dependencies are needed.

Linux, macOS, or WSL

gcc -std=c11 -Wall -Wextra -O0 -g -o cve_2026_55200_probe poc/cve_2026_55200_probe.c

Windows with MinGW

gcc -std=c11 -Wall -Wextra -O0 -g -o cve_2026_55200_probe.exe .\poc\cve_2026_55200_probe.c

The -O0 flag disables optimization to ensure the arithmetic behavior remains observable. -g adds debug symbols for source-level analysis.

Running the Arithmetic Verifier

The cve_2026_55200_probe binary accepts several command-line flags to exercise the different code paths:

Flag Purpose
(none) Defaults to a benign packet (safe values).
--benign Explicitly runs the benign case.
--native Uses native size_t arithmetic without the patch.
--check Uses size_t with the upstream fix applied.
--packet-length N Sets packet_length to a specific hex or decimal value.
--mac-len N Sets mac_len (default varies by test).
--auth-len N Sets auth_len (default varies by test).

Basic functionality test

./cve_2026_55200_probe

Reproduce the exact CVE-2026-55200 overflow

./cve_2026_55200_probe --packet-length 0xffffffff --mac-len 0 --auth-len 16

Exercise 64-bit native arithmetic (unpatched)

./cve_2026_55200_probe --native

Verify the fixed path rejects malicious input

./cve_2026_55200_probe --check

Expected Output for the Vulnerable Case

When you trigger the overflow, the verifier produces output similar to:


vulnerable32_decision=accepted
vulnerable32_allocation=19
fixed32_decision=rejected: out of boundary
native_unpatched_decision=accepted
native_note=source-shaped integer expression wraps before assignment into 64-bit size_t
result=PASS

This confirms that:

  • The vulnerable32 model accepts the packet and allocates only 19 bytes.
  • The fixed32 model correctly rejects it with POC_ERROR_OUT_OF_BOUNDARY.
  • The native_unpatched model exhibits the same flaw when the intermediate 32-bit expression wraps before widening to size_t.

Key Source Files in bikini/exploitarium

Understanding the repository layout helps navigate the full proof-of-concept:

File Role
poc/cve_2026_55200_probe.c The standalone C11 arithmetic verifier described in this article.
poc/libpwn_local_rce_harness.c A controlled local RCE harness demonstrating exploitability.
poc/libpwn_cve_2026_55200_server.py Minimal malicious SSH server emitting the malformed packet.
README.md (CVE-2026-55200 directory) Build instructions, theory of operation, and usage notes.

The arithmetic verifier lives in poc/cve_2026_55200_probe.c and is designed to run anywhere—its portability is a deliberate feature for security auditing across platforms.

Summary

  • CVE-2026-55200 is a 32-bit integer overflow in libssh2's packet length calculation.
  • The arithmetic verifier reproduces this bug without depending on libssh2 itself.
  • Build with gcc -std=c11 -O0 -g for faithful arithmetic behavior.
  • Use --packet-length 0xffffffff --mac-len 0 --auth-len 16 to trigger the overflow.
  • The vulnerable32 and native_unpatched models accept malicious input; fixed32 and native_fixed reject it.
  • All source files are available in the bikini/exploitarium repository under the libssh2-cve-2026-55200-poc directory.

Frequently Asked Questions

Does the verifier require libssh2 to be installed?

No. The cve_2026_55200_probe.c program is pure C11 with zero external dependencies. It reimplements only the arithmetic expressions found in libssh2's src/transport.c, making it portable to any system with a C compiler.

Why does the native_unpatched model overflow on 64-bit systems?

The expression packet_length + mac_len + auth_len is evaluated using the types of the operands before assignment. When these are uint32_t values, the addition wraps in 32-bit space; only afterward is the result widened to size_t. The verifier's native_note field explicitly flags this: "source-shaped integer expression wraps before assignment into 64-bit size_t."

Always use -O0 (no optimization). Higher optimization levels may constant-fold or eliminate the arithmetic in ways that obscure the overflow behavior. -Wall -Wextra catches potential issues, and -g enables debugging.

Can I use this verifier to test my own libssh2 patches?

Yes. The modular structure—four independent models with identical interfaces—allows you to add custom variants. Copy the fixed32 implementation, modify the guard logic, and compare outputs against vulnerable32 to validate your changes.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →