Data & Insight

ENCFORGE: the JADEPUFFER operator returns with AI-specific ransomware. The entry point never changed.

RobertUpdated Jul 21, 20267 min read
Attestd API response showing risk_state critical, actively_exploited true, and max_epss 0.9999 for Langflow version 1.2.0, the entry point for both the original JADEPUFFER campaign and the new ENCFORGE ransomware deployment

Sysdig has published a sequel to JADEPUFFER, the fully autonomous AI ransomware campaign it documented earlier this month. The same operator has returned to the same vulnerable Langflow server and deployed ENCFORGE, a compiled Go ransomware built specifically to encrypt AI model files across the host filesystem.

The entry point did not change. CVE-2025-3248, an unauthenticated remote code execution vulnerability in Langflow's /api/v1/validate/code endpoint, patched in version 1.3.0, in CISA's Known Exploited Vulnerabilities catalog since May 2025. The same flaw that gave the operator access in the first campaign gave it access again.

Attestd was returning risk_state: critical, actively_exploited: true, and authentication_required: false for vulnerable Langflow versions before either attack ran. The signal has not changed.

ENCFORGE: built for AI environments#

ENCFORGE is a UPX-packed static Go 1.22.12 ELF binary recovered from the attacker's command-and-control server, where it was hidden as /.lockd. The internal project name is encfile. A companion keygen tool named keyforge is referenced in the binary's error text. Both strings survive recompilation and serve as stable detection anchors.

The default extension list covers approximately 180 file types: PyTorch and TensorFlow checkpoints, Hugging Face SafeTensors, ONNX interchange format, GGUF and its predecessor GGML (the current and legacy standards for locally deployed LLMs), FAISS vector indexes, Parquet and Arrow training datasets, NumPy arrays, and TensorFlow records. The built-in help text uses LoRA fine-tuning adapters as an example of additional targets via the --include flag. A generic file locker would have no reason to enumerate LoRA adapters. The targeting is deliberate.

ENCFORGE uses AES-256-CTR for file data with the per-run symmetric key wrapped under an embedded RSA-2048 public key. It encrypts selected file regions rather than full files, the same speed optimization used by LockBit and BlackCat. Each processed file is renamed with a .locked extension. The binary kills processes holding files open, handles restarts without re-encrypting completed files, drops ransom notes as README, HOW_TO_DECRYPT, and README_DECRYPT, and deletes itself after running. No exfiltration capability is present.

The extortion contact is [email protected], the same address from the prior campaign. Sysdig identifies this as the strongest attribution link between the two operations.

The host breakout#

After confirming code execution through the Langflow RCE, the operator found the Docker socket at /var/run/docker.sock. Its initial attempt to pull ENCFORGE from the GCP command-and-control server failed. Rather than stopping, it adapted.

Over five minutes and 24 seconds, the operator built and revised six Python scripts through the same Langflow RCE channel until it had a working path to the host. Scripts were base64-encoded and decoded inside exec() calls to avoid shell-level detection. The final version used the Docker API to create a privileged container with Privileged: true, PidMode: host, NetworkMode: host, and the host root filesystem bind-mounted read-write, then used nsenter to run ENCFORGE on the host.

Before the live encryption run, the operator ran --try-run to scan the filesystem and count targets, then --lock for the live pass. The --task-id gcp_h1 flag suggests this host was one of multiple GCP targets being tracked in a broader campaign.

The same operator corrected a failed Nacos login in 31 seconds in the first campaign. It adapted a blocked delivery path into a host breakout in five minutes. The response time is consistent.

What Attestd returns across Langflow versions#

Three Langflow CVEs are now in CISA's Known Exploited Vulnerabilities catalog:

  • CVE-2025-3248: unauthenticated RCE, patched in 1.3.0, in KEV since May 2025
  • CVE-2026-33017: unauthenticated RCE, patched in 1.9.0, added to KEV March 25, 2026
  • CVE-2026-55255: cross-user authorization bypass, added to KEV July 7, 2026 The API response for each version reflects the cumulative CVE exposure:
bash
curl "https://api.attestd.io/v1/check?product=langflow&version=1.2.0" \
  -H "Authorization: Bearer $ATTESTD_API_KEY"
json
{
  "product": "langflow",
  "version": "1.2.0",
  "risk_state": "critical",
  "risk_factors": ["active_exploitation", "remote_code_execution", "no_authentication_required", "internet_exposed_service", "patch_available"],
  "actively_exploited": true,
  "authentication_required": false,
  "patch_available": true,
  "fixed_version": "1.10.2",
  "max_epss": 0.9999,
  "cve_ids": ["CVE-2025-3248", "CVE-2026-33017", "CVE-2026-55255", "..."]
}

The max_epss of 0.9999 at 1.2.0 means exploitation is assessed as essentially certain across all CVEs present at that version. The risk progression across versions:

VersionCVE-2025-3248CVE-2026-33017CVE-2026-55255max_epssrisk_state
1.2.0presentpresentpresent0.9999critical
1.4.0patchedpresentpresent0.9819critical
1.9.0patchedpatchedpresent0.0080critical
1.9.1patchedpatchedpresent0.0080critical

The max_epss drop from 0.98 at 1.4.0 to 0.008 at 1.9.0 reflects the removal of CVE-2026-33017, which was the high-severity driver between 1.3.0 and 1.8.x. The EPSS does not recover at 1.9.1 because CVE-2026-55255 alone does not carry the same exploitation certainty as the two RCE flaws.

A note on the patching guidance in press coverage#

Today's THN article recommends upgrading to Langflow 1.9.1. The Attestd API shows 1.9.1 returning risk_state: critical with CVE-2026-55255 still present and a fixed_version of 1.10.2 across all checked versions.

This may reflect a difference between when CVE-2026-55255 was fixed in practice and how that fix version has been recorded in the NVD and advisory data Attestd ingests. It may also reflect additional CVEs at 1.9.1 that are unrelated to CVE-2026-55255.

The confidence on these responses is 0.5, the lowest band, which means the version range data for Langflow's extensive CVE list carries meaningful uncertainty. What is consistent across all four checked versions is the fixed_version field returning 1.10.2. Until a version-level response returns risk_state: none, treating 1.10.2 as the safe target is the conservative position.

The machine speed observation#

This is the second documented attack by the same operator using the same entry point in the same month. CVE-2025-3248 has been public and patched for over a year. It has been in CISA KEV since May 2025. Organizations running Langflow below 1.3.0 in July 2026 are running a year-old unpatched RCE on an internet-exposed service that a documented threat actor has used twice.

The Attestd signal for CVE-2025-3248 has been available since before the first JADEPUFFER campaign. The response time for the attacker in adapting to a blocked delivery path was five minutes. The question is not whether the signal exists. It is whether the system consuming it operates in the same time domain as the attacker.

Credit and sources#

All attack details and ENCFORGE technical analysis are from Sysdig's Threat Research Team. Full report: JADEPUFFER Evolves: The Agentic Threat Actor Deploys Ransomware Built to Destroy AI Models.

Binary SHA-256: packed 8cb0c223b018cecef1d990ec81c67b826eb3c30d54f06193cf69969e9a8baea2, unpacked ea7822eac6cecef7746c606b862b4d3034856caf754c4cf69533662637905328.

What to do#

Upgrade Langflow. The Attestd API consistently returns 1.10.2 as the fixed_version across all checked versions. The THN article recommends 1.9.1 but the API shows 1.9.1 still returning risk_state: critical. Run your own version check and verify the response before treating any version as clean.

Remove /var/run/docker.sock from any container that does not require it. In both JADEPUFFER campaigns, the Docker socket was the pivot path from container to host. A Langflow deployment has no legitimate need for it.

Rotate credentials accessible to the Langflow process. Patching does not revoke credentials already harvested through a vulnerable instance.

Keep model weights, vector indexes, and training datasets in offline or immutable snapshots. Sysdig estimates rebuilding a production AI model after encryption costs $75,000 to $500,000 per model in GPU compute and engineering time.

API documentation: attestd.io/docs. Detection ledger: github.com/attestd-io/detection-ledger. Machine speed thesis: attestd.io/thesis. Original JADEPUFFER post: attestd.io/blog/langflow-jadepuffer.