Cyberzen Dojo · No. 4

The print server that held the keys to the castle

What an AI agent swarm did to PaperCut, and how a design meeting years ago could have ended it at the printer.

Nobody puts the print server on the crown-jewels list. It prints. It charges the marketing team for colour. It is the beige filing cabinet of IT.

This September, an AI agent swarm treated it as the front door.

What happened

On 27 August (dates below are UTC), PaperCut, the Melbourne-made print management software found in schools, councils and offices, published fixes for two flaws: an authentication bypass (CVE-2026-81578) and a code-execution bug (CVE-2026-82078).

According to GreyNoise, on 31 August an attacker set AI agents loose, running on OpenAI’s Codex harness with a DeepSeek model. The agents read the advisory, compared the patched and unpatched versions, wrote working exploits, built themselves a test lab and drew up a list of 1,005 targets. About four hours later they had a foothold on a real victim. It was Australian. Two hours after that, they owned its whole domain.

On 1 September, hundreds of agents started the main run and got into 11 organisations in 26 seconds. By 2 September, at least 440 PaperCut servers at 395 organisations in 48 countries had been hit. About half were schools, and 15 were Australian.

Then the numbers get more interesting:

  • 280 servers gave up passwords.
  • Only 12 organisations lost full domain control. One took just seven minutes, at a US high school.
  • Cloudflare’s web firewall blocked at least one attack outright.
  • The attacker told the agents to leave 28 countries alone. In GreyNoise’s words, that restraint “failed in some instances”.

That last one deserves a moment. The attacker had root on its own agents and still couldn’t keep them in scope. If a criminal can’t govern its agents with a prompt, your approved copilot config is not going to manage it either.

Source: GreyNoise, published 9 September 2026: https://www.greynoise.io/blog/ai-orchestrated-campaign-against-papercut-ng-mf

The AI was fast. The architecture decided the ending.

440 break-ins became 12 domain takeovers, and the gap between them is design. Where the agents went all the way, they did it through old, boring doors: credentials cached on the print server, the noPac flaw patched back in 2021, or PaperCut running with domain-admin rights. None of that is AI. It’s a printer that had been made a citizen of the domain with a master key in its pocket.

So here is a thought experiment. Imagine I’m the security architect in the room before PaperCut, or any app like it, is built. What follows is a design like this, not a claim about PaperCut’s actual code.

If I’d been in the design meeting

The honest bar first: no design makes bugs impossible. The goal is that a bug in a print app stays a print-app incident.

Stage 0. Product inception: a one-page security charter

Before a line of code, the product owner signs three outcomes, written into the requirements as ship-blocking acceptance criteria:

  • A compromised server must never yield domain credentials.
  • The product must never need to face the internet raw.
  • The default install is the secure install.

If a default install breaks any of them, the release fails. Insecure-by-default is how one bug becomes 395 victims.

Stage 1. Architecture and threat modelling: take away the roads

Run STRIDE with the architects over a whiteboard data-flow diagram, and win three structural arguments.

  • Split the planes. The user print portal, the admin console and the print-release engine become separate components with separate processes and separate identities. The internet-facing piece is a thin, stateless front end with no admin functions compiled into it. The components talk to each other only over mutual TLS. A bypass of the user portal lands somewhere with nothing to steal and nowhere to go.
  • No SYSTEM, no domain admin, ever. The service runs as a virtual account or a group managed service account (gMSA) with no local admin rights. It reads users and groups over read-only LDAP, or Entra ID via Microsoft Graph scoped to User.Read.All and Group.Read.All. It stores no privileged credentials, and the installer refuses to run on a domain controller.
  • Out-of-band admin. The admin console listens on localhost or a management network only, behind SSO with phishing-resistant MFA such as FIDO2 keys. The installer simply has no “expose admin to the internet” checkbox.

Record each decision as an architecture decision record (ADR), one page per decision, naming the threat it kills. ADRs outlive the people who argued for them.

Stage 2. Detailed design: engineering standards the developers sign up to

  • Authentication in one place. Every route goes through a single central filter that denies by default. No per-page checks, so no page where someone forgot one. That is the class of bug an authentication bypass lives in.
  • No dynamic reflection or scripting on input paths. A banned-API list is enforced in CI. If scripting is a genuine feature, it runs in a sandboxed interpreter with no class loading and no file or network access.
  • Signed, allow-listed extensions only, and no web roots the service account can write to. An attacker who can drop a file into a served folder owns the box; this closes the custom/web/pcp_*.txt trick.
  • An outbound egress allow-list. The server may talk to printers, the directory and the update service, and nothing else. Reverse tunnels such as Ligolo, and certutil downloads from an attacker’s server, have nowhere to go.
  • Secrets that can’t be lifted. Any stored secret is encrypted with DPAPI-NG or a cloud KMS and scoped to the service identity, never readable by SYSTEM-wide tooling. A memory dump yields nothing reusable.
  • No Kerberos delegation at all. If single sign-on to printers is needed, use resource-based constrained delegation scoped to print devices only.
  • Tiering shipped, not suggested. The installer checks group membership and refuses to start if the service account sits in Domain Admins, Enterprise Admins or Server Operators.
  • Strict parsing. Untrusted input gets a strict schema, with Java deserialisation filters (JEP 290) on by default, because deserialisation is the same bug class as the reflection flaw.
  • Logging by design. Every admin action and every authentication decision goes to tamper-evident logs that forward to the customer’s SIEM out of the box. That is how a seven-minute domain takeover becomes a seven-minute alert.

Stage 3. Build and verify: test with an attacker’s goal

  • SAST rules for reflection and authentication bypass patterns, and fuzzing of every unauthenticated route.
  • An annual external penetration test with one red-team objective rather than a checklist: from the user portal, reach domain credentials.
  • A release gate: if any unauthenticated route can reach an admin code path, the build fails.
  • Supply chain: every release ships with an SBOM (a software bill of materials listing every component), built reproducibly and signed.

Stage 4. Deployment: hardening ships as defaults, not as a PDF

The secure configuration is the out-of-the-box configuration, backed by a built-in health check. The admin dashboard turns red when the service runs privileged, when the admin console is reachable from outside, or when the version is behind. Telemetry, with the customer’s consent, tells them when they are exposed before an internet scanner does.

Stage 5. Operate and respond

  • Security fixes auto-update by default: signed, staged and reversible. A patch nobody installs is a press release.
  • Every advisory ships with hunt content, such as Microsoft Sentinel and Defender queries and Sigma rules, so defenders can look for compromise the same day.
  • A kill switch lets an admin disable external access instantly from the vendor portal.

How I’d communicate it

Not as a 90-page standard nobody reads, but in three forms for three audiences: a one-page charter for executives, ADRs for architects, and security user stories in the backlog with acceptance tests, such as “As an attacker with a portal bypass, I cannot reach the admin API.” Every one of them ties back to a sentence the business understands: the print server is never a road to the castle.

The agent problem, both sides of the wire

The attacker’s own scope list leaked. A rule written into a prompt is advice. Real limits are identity, network and privilege boundaries enforced outside the agent. That is true for the attacker’s swarm, and it is true for the copilots you are rolling out on Monday.

Would it have stopped the swarm?

It would still have got in. It would have found a print queue, an unprivileged account and no way out. Its whole playbook, a SYSTEM shell, then dumping credentials, then passing them to the domain controller, assumed someone had handed the printer a master key.

Secure by design doesn’t out-run the attacker. It removes the road.