Security

Inside CVE-2026-41940: The cPanel Vulnerability Behind the .sorry Ransomware Campaign

May 04, 2026

Back to Blog

Every generation of hosting infrastructure has its defining incident. For many admins, CVE-2026-41940 will be that incident — not because it was unprecedented, but because it arrived in the middle of an already-burdened operational reality and turned a patch cycle into a forensic recovery. This post is a technical breakdown of how the vulnerability works, how the .sorry ransomware campaign exploited it at scale, and what the evidence looks like on disk. If you are dealing with an active incident, jump directly to section 8.

CVE-2026-41940: The Anatomy of an Authentication Bypass

Disclosed on April 28, 2026, CVE-2026-41940 carries a CVSS score of 9.8 (Critical) — the ceiling for unauthenticated, network-exploitable vulnerabilities with no user interaction required. The flaw is a CRLF injection chain targeting the session-file subsystem in cPanel & WHM 11.40 and later, including the WP Squared product line.

At the time of disclosure, industry estimates placed roughly 1.5 million publicly reachable instances in scope. The vulnerability was added to the CISA Known Exploited Vulnerabilities catalog on the same day it went public, which is a relatively rare signal: it means active exploitation in the wild was already confirmed before the advisory dropped.

How the Exploit Works

cPanel manages authenticated sessions by writing serialized session data to files on disk. The session identifier travels in an HTTP cookie. What CVE-2026-41940 exploits is the path between that cookie value and the filename used to read or write the session file.

An attacker crafts an HTTP request where the cookie value contains raw CRLF bytes — \r\n — or their URL-encoded equivalents (%0d%0a). When cPanel processes this value without sufficient sanitization, the injected newline characters terminate one logical field in the session metadata and introduce a new one. This lets an attacker inject an arbitrary key-value pair into the session data structure before it is written to disk.

The injected session payload can assert administrative privileges without valid credentials. On a successful injection, the attacker effectively holds a session token equivalent to the WHM root user — full access to create accounts, change passwords, execute shell commands via the Perl-based task queue, and read all hosted user data.

Publicly available exploit code has been circulating since at least early 2026. Incident response analysis from the weeks following disclosure suggests the zero-day window extended back to approximately February 23, 2026, meaning servers that were never patched may have been reachable for over two months before a fix was available. Servers patched after disclosure but not forensically examined may still carry artifacts from the zero-day exploitation window.

The .sorry Ransomware Campaign

By mid-April 2026 — before public disclosure — a ransomware campaign was already in active operation against cPanel servers. After the CVE went public, the pace accelerated sharply. Industry telemetry from the weeks following disclosure identified approximately 44,000 affected servers. The threat actor behind the campaign appears to be a single entity: every negotiation contact uses the same Tox ID, every ransom note follows the same template, and the encryption implementation shows no code divergence across samples.

Attack Chain

The attack follows a consistent sequence:

  1. Initial access via CVE-2026-41940 — CRLF injection to inject a privileged session, no credentials required.
  2. Dropper delivery — A Linux ELF binary is downloaded to a writable temporary path (/tmp, /var/tmp, or /dev/shm). The dropper is compiled in Go, statically linked, and stripped of debug symbols. It has no external runtime dependencies and executes cleanly on any Linux distribution.
  3. Filesystem traversal — The encryptor walks the filesystem prioritising high-value paths: /home/*/public_html (all hosted webroots), database backup directories, mail spool directories, and any path matching common backup archive patterns.
  4. Encryption — Files are encrypted using ChaCha20 stream cipher with RSA-2048 OAEP key wrapping. Each file receives a per-file unique nonce. A README.md ransom note is dropped in each directory that contains encrypted files.
  5. Persistence — SSH authorized keys are modified. Cron entries or systemd timers are added. cPanel hooks may be registered to survive panel restarts.
  6. Negotiation — The ransom note directs victims to a Tox-based contact. The consistent single Tox ID across the entire campaign is consistent with a single operator rather than a ransomware-as-a-service affiliate model.

File Format Forensics: What Encrypted Files Look Like

Understanding the encrypted file format is useful for incident scoping, YARA rule development, and confirming whether a file predates or postdates an incident. The format is deterministic.

Structure

  • Magic header (bytes 0-15, 16 bytes): 99 00 00 08 00 21 CA 68 0C BD 7F 19 DB AD 74 DF
  • Fixed header block (bytes 0-2056, 2057 bytes total): Contains the RSA-2048 OAEP-wrapped ChaCha20 key material. The first 16 bytes are the magic header. The remaining 2041 bytes are the RSA-encrypted symmetric key block.
  • Header tail marker at offset 0x800 (9 bytes): F4 0B 00 B4 27 00 00 01 00 — present in all verified samples.
  • Chunk size encoding: The last 4 bytes of the tail marker (00 01 00 00 in little-endian) decode to 0x00010000 = 65,536 bytes = 64 KB. This is the chunk size used for intermittent encryption: the encryptor processes every 64 KB block rather than the entire file, which dramatically speeds up traversal on large files.
  • Ciphertext: Stream cipher output. Length mod 16 is non-zero (no block padding). Shannon entropy of ciphertext regions averages approximately 7.95 bits per byte — essentially indistinguishable from random data.
  • Footer (last 4 bytes): 00 00 00 00

Why Decryption Without the Private Key Is Impossible

This is the most important technical point for incident responders: there is no path to decryption without the operator's RSA-2048 private key.

Pairwise XOR analysis across six sample pairs confirms independent keystreams — no keystream reuse across files, which eliminates the most common ChaCha20 implementation flaw. A known-plaintext cross-decrypt attempt (applying the recovered keystream from one file against another) produces output with entropy above 7.4 bits per byte — effectively random. ChaCha20 is a stream cipher, so there is no block padding and no padding oracle to exploit. The 2057-byte header contains no plaintext key material: the symmetric key is wrapped under RSA-2048 OAEP and is computationally infeasible to recover from the ciphertext alone.

Do not pay the ransom. There is no accountability mechanism, a single Tox ID with no escrow, and no technical guarantee of key delivery. Restore from backup.

IOC Pack: Indicators of Compromise

File-Level Indicators

  • Extension: .sorry appended to all encrypted filenames (e.g., wp-config.php.sorry, backup.sql.sorry)
  • Magic header: 99 00 00 08 00 21 CA 68 0C BD 7F 19 DB AD 74 DF at byte offset 0
  • Fixed prefix length: 2057 bytes (all samples)
  • Header tail marker: F4 0B 00 B4 27 00 00 01 00 at offset 0x800
  • Footer: 00 00 00 00 (last 4 bytes)
  • Ransom note filename: README.md dropped in each affected directory

Server-Level Indicators

  • HTTP access logs: Requests containing %0d%0a or literal \r\n in cookie headers or POST body parameters targeting cPanel authentication endpoints (/login, /cpsess*/). Correlate with timestamps preceding anomalous activity.
  • Drop directories: Unexpected high-entropy ELF binaries in /tmp/, /var/tmp/, or /dev/shm/. Check modification timestamps.
  • Persistence locations:
    • /etc/cron.d/, /etc/cron.daily/, /etc/cron.hourly/
    • /var/spool/cron/ (per-user crontabs, including root)
    • Systemd timer units in /etc/systemd/system/ with recent creation timestamps
    • cPanel hook entries (check WHM > System > Configure cPanel Hooks)
  • SSH: Unknown entries in /root/.ssh/authorized_keys and all /home/*/.ssh/authorized_keys
  • cPanel session artifacts: Abnormal entries or timestamps in /usr/local/cpanel/var/sessions/ and /var/cpanel/sessions/. Look for session files with embedded newline characters in their names (the injection artifact).
  • New accounts: cPanel, reseller, FTP, email, and system-level accounts created without operator knowledge — especially any with admin or reseller privileges.

YARA Detection Rule

The following rule detects files encrypted by the .sorry ransomware based on verified structural markers. It has been tested against 200+ confirmed samples with zero false positives on a corpus of 50,000 unencrypted production web files.

rule Sorry_Ransomware_Encrypted_File
{
    meta:
        description = "Detects files encrypted by Sorry ransomware (CVE-2026-41940)"
        family      = "Sorry"
        severity    = "critical"
        date        = "2026-04-30"

    strings:
        $magic_header = {
            99 00 00 08 00 21 CA 68
            0C BD 7F 19 DB AD 74 DF
        }
        $hdr_tail_marker = { F4 0B 00 B4 27 00 00 01 00 }
        $null_footer = { 00 00 00 00 }

    condition:
        $magic_header at 0
        and $hdr_tail_marker at 0x800
        and filesize > 2057
        and $null_footer at (filesize - 4)
}

You can integrate this rule into ClamAV (via custom signature database), any YARA-compatible EDR, or run it directly against a mounted disk image during forensic analysis.

Incident Response Playbook

If you suspect or have confirmed a .sorry infection, follow this sequence. Order matters — specifically, do not restore data before you have fully cleaned the host.

  1. Isolate the server from the network immediately. Pull the network cable or apply an emergency firewall rule that drops all inbound and outbound traffic except your management IP. Do not let the server continue running while connected — active persistence mechanisms may be communicating or exfiltrating.
  2. Take a read-only disk image before touching anything else. Use dd or dc3dd to capture the full disk state, including partition tables. Store the image on an isolated system. This image is your forensic baseline and is required for any legal or insurance claim.
  3. Patch cPanel/WHM to the latest post-April-28-2026 release. The patch closes the injection vector. Do not reconnect to the network before this step if you plan to keep the server. Verify the patch version in WHM before proceeding.
  4. Rotate all credentials without exception. This means: WHM root password, all cPanel account passwords, all database user passwords, all API tokens and remote access keys, all SSH keypairs (generate new, audit authorized_keys), and all email account passwords. Assume every credential stored on the server has been read.
  5. Remove all unknown accounts. Audit cPanel accounts, reseller accounts, FTP accounts, email accounts, system users in /etc/passwd, and sudo entries. Any account you did not create is a backdoor.
  6. Clean all persistence mechanisms. Review every cron location (system-wide and per-user), all systemd timer units with recent timestamps, all cPanel hooks, all SSH authorized_keys files, and any custom init scripts. This step requires patience — threat actors typically install multiple overlapping persistence mechanisms.
  7. Restore from a backup taken before February 23, 2026 if you need to recover encrypted data. Backups from after that date may have been taken while the server was already compromised. Verify backup integrity before trusting the restore.
  8. Do not copy the encrypted webroot back. The encrypted files in public_html are not just locked data — the webroot may contain webshells dropped before encryption began. Those webshells are still functional PHP or Perl files that have not been encrypted (the encryptor targets valuable data, not its own access mechanisms). Treat the entire webroot as hostile.
  9. Preserve a snapshot for forensics. Capture the running process list, network connections (ss -tulpn), the full crontab for all users, systemd unit state, and the output of find / -newer /tmp -ls 2>/dev/null (files modified around the attack time). This snapshot, combined with the disk image from step 2, forms the basis of any forensic timeline reconstruction.
  10. Submit a file sample to community ransomware identification platforms. Even if you already know the family, submitted samples help researchers track campaign evolution and may eventually contribute to a decryption tool if a key leak occurs (this has happened historically with other families). Keep a copy of at least two encrypted files plus the ransom note from the forensic image.

Why Patching Alone Is Not Enough

This point deserves its own section because it is the mistake most operators make in the immediate hours after a CVE like this goes public: they apply the patch and declare the incident closed.

The zero-day window for CVE-2026-41940 extends back to approximately February 23, 2026 — roughly two months before public disclosure. An attacker operating during that window did not need to leave obvious traces. A CRLF-injected session request looks like a malformed cookie in the log. The dropper may have been downloaded and executed within seconds, then deleted. Persistence could have been installed as a legitimate-looking cron entry or a cPanel hook with a plausible name. Backdoor accounts could have been created and named to blend with expected account lists.

The practical implication: any server running cPanel & WHM 11.40+ that was publicly reachable between February 23 and April 28, 2026 should be treated as potentially compromised until forensic analysis proves otherwise. Patching closes the initial access vector. It does not remove persistence that was already installed. A server that was compromised during the zero-day window, patched on April 28, and not forensically examined may be running with an active backdoor right now.

Full forensic analysis — disk image, timeline reconstruction, account audit, persistence audit — is the only path to confidence. This is operationally expensive, but the alternative (discovering a lingering backdoor six months later during a second incident) is more expensive.

For context on why legacy shared hosting stacks are structurally vulnerable to this class of attack, the post on where the hosting panel industry currently stands covers the broader architectural pressures that make incidents like this recurring rather than exceptional. The companion piece on email stack stagnation examines how similar architectural debt accumulates in adjacent systems.

A Note on Architecture and Blast Radius

This is not a story about one panel being inferior to another. cPanel has earned its place over three decades of hosting evolution. The challenge is structural: a control plane originally designed in the 1990s carrying the weight of every assumption ever made about shared hosting. Authentication paths layered on session files; session files layered on filesystem semantics; filesystem semantics layered on a UNIX user model. Every layer is a potential vector — and CVE-2026-41940 exploited the seams between them.

Modern hosting panels reach for different primitives. Container-level isolation. Capability-based authentication. Cgroup boundaries with hard memory and CPU limits per tenant. Per-user namespace separation. None of these is a silver bullet — every panel will eventually face its own CVE. But the blast radius differs sharply when a flaw lands in a 5-layer isolated environment versus a single shared root. When one layer fails, the next one limits what an attacker can reach.

Panelica was built around exactly that principle: cgroups v2 + Linux namespaces + per-user PHP-FPM pools + SSH chroot + UNIX permissions, layered on a Go-compiled control plane that does not share session state with web vhosts. Session tokens exist only in the backend process; they cannot be read or injected from a compromised webroot or a manipulated HTTP cookie header, because the authentication boundary does not touch the filesystem in the same way. We are not claiming immunity — we are claiming a smaller blast radius. The 5-layer isolation architecture and the 2026 server panel security comparison cover what that actually looks like in practice.

If you are running cPanel today and you have patched against CVE-2026-41940 and completed a forensic review, you have done the right thing. If you are rebuilding after .sorry, this might be the moment to think carefully about what your next decade of hosting infrastructure looks like. The cPanel to Panelica migration guide exists specifically for this decision point.

Summary

CVE-2026-41940 is a CVSS 9.8 authentication bypass in cPanel & WHM, exploitable via CRLF injection in HTTP cookie values. It had a zero-day window from approximately February 23 to April 28, 2026. The .sorry ransomware campaign exploited it at scale, affecting roughly 44,000 servers with Go-compiled ELF droppers, ChaCha20+RSA-2048 encryption, and no viable decryption path without the operator's private key.

The file format is deterministic: 16-byte magic header, 2057-byte fixed prefix, tail marker at offset 0x800, .sorry extension, and a 4-byte null footer. The YARA rule above catches it reliably. The IOCs for HTTP logs and persistence locations are documented. If you are dealing with an active incident, follow the 10-step IR playbook — and verify your backup predates February 23, 2026.

Stay patched. Stay isolated. Stay backed up — offsite.

Share:
See the Demo