Two repositories on Hugging Face each hold a single file named to look like a compiled model, rce-model.onnx and rce-model.gguf. Neither is a model. Both are Python pickle streams that execute a shell command the moment a loader deserializes them.
The command in each is id, a harmless query that prints the current user. That choice marks these as proof-of-concept demonstrations of an evasion technique rather than weaponized payloads. Both files are the work of a single author. Whether the work is defensive research or early reconnaissance for a supply-chain operation is something the files alone cannot settle.
The artifacts are pickles, not models
The two files live in separate Hugging Face repositories, one published under an ONNX extension and one under a GGUF extension. The repository names advertise evasion of a serialized-model security scanner. Each repository contains nothing but the single payload file and a default attributes file, so neither carries the weight or tokenizer data a real model ships. The sizes give them away on their own: 44 bytes for the ONNX-named file and 21 bytes for the GGUF-named file, orders of magnitude below any genuine model. Hugging Face’s own content scan flagged both. A scanner that decides what to inspect from the file extension would not.
The payload runs when the file is loaded
A pickle is a serialization format that records the steps to rebuild a Python object. One opcode, GLOBAL, names a callable to import. Another, REDUCE, calls it with arguments pulled from the stack. Both payload files use that pair to import os.system and call it. The ONNX-named file runs id and redirects the output to /tmp/onnx_rce_ok.txt, a marker the author uses to confirm execution. The GGUF-named file runs id with no marker.
Execution happens on deserialization, before any later use. Any code path that unpickles the file runs the command, including torch.load and the loader helpers that call it underneath. The file does not need to be a valid model for the payload to fire. A loader that begins by unpickling the stream executes the command before it discovers the bytes are not a model at all.
The evasion rests on a mismatch between how a scanner decides what to inspect and how a loader decides what to execute. A scanner that treats a file as a pickle only when its extension is a known pickle or weight suffix skips a file ending in .onnx or .gguf. A loader hands the same bytes to the unpickler regardless of the extension. The file sits in that gap, inert to the scanner and executable to the loader.
These files are also protocol-0 pickles, the oldest text-form variant, which begins with a printable opcode instead of the protocol-2 binary marker most tooling expects. A scanner that sniffs for the binary marker before disassembling misses them a second way.
One author, two formats, intent unresolved
The two files are the work of a single author, published together, with identical payload structure and parallel naming across two model formats. On that evidence the artifacts link to one operation with high confidence. The intent behind it is the part that does not resolve.
The benign command and the framing of the repositories around scanner evasion point to a demonstration, with no credential theft or persistence behavior present. The same artifacts are also live on Hugging Face, indexed, and loadable by any pipeline that pulls a model by name, which is real exposure regardless of why they were posted. From the file alone, a demonstration and a staging ground look the same. What tells them apart is who published it and what else they have published, which static analysis cannot see.
A single author producing variants of one evasion technique across formats could be a researcher building a test corpus or an adversary preparing payload delivery. Either way, treating the two files as one body of work is what lets a defender reason about the next one before it appears.
Attribution blocks the adversary, not just the file
A single malicious model is a single block. The operation behind it is the whole catalogue, including the files not yet posted. When the two payload files link to one operation, a defender can act against the operation rather than the artifact in front of them, which covers a republish under a new repository name and the same technique carried into a new format. The block survives the rename.
For a demonstration this is triage value. For an operation it is the difference between removing one file and closing the source.
Treat a serialized model as code
Loading a serialized model can run arbitrary commands, so a model from an unverified source deserves the same caution as an unverified executable. Prefer the safetensors format, which carries no executable opcodes. Reject pickle-based weights from sources you do not trust. Inspect a file by its content rather than its extension, since the extension is attacker-controlled. Load models under least privilege, without ambient credentials or network access a payload could reach.
None of this tells you a given file is hostile before you load it. A 44-byte pickle and a benign demonstration look identical to a static check until you know who produced it and what else they have produced. That is the intelligence gap.
Indicators of compromise
| Type | Indicator |
|---|---|
| File name | rce-model.onnx (44 bytes, Python pickle) |
| File name | rce-model.gguf (21 bytes, Python pickle) |
| Host artifact | /tmp/onnx_rce_ok.txt (execution marker written by ONNX-named payload) |
Where Aephix fits
Aephix works on exactly that gap. It is threat intelligence for the AI agent supply chain, not a patch or a sandbox. Before you load a model or install a package, Aephix Vantage gives you a free, cross-ecosystem view of what is already known to be malicious, so a file with a hostile history is something you recognize before you connect. When you are looking at a malicious package, model, skill, MCP server, extension, or container, Aephix Sleuth links it to the wider operation behind it, with a confidence level and supporting evidence, so you can act against the whole operation rather than the single artifact.
The file format runs code on load, and the extension hides that from a scanner. Whether the next file from this author carries id or something worse is a question only the adversary behind it answers.