CVE
Not assigned
CWE
CWE-506, CWE-522
Affected Surface
- PyPI package `openaii==1.55.3`
- PyPI package `ollamaa==0.4.2`
- PyPI package `langgrap==0.2.45`
- PyPI package `transfomers==4.44.2`
- Related follow-on packages publicly cataloged during the same 11-13 September window, including `platform-telemetry-client==1.0.0` and `chroma-client==0.5.7`
- Python developer workstations, notebook servers, CI runners, and AI-agent environments that installed any of the affected packages
The most useful supply-chain story from the last three days is a PyPI cluster that went after teams building with popular AI Python libraries. Four lookalike packages published on 11 September, openaii, ollamaa, langgrap, and transfomers, all used the same basic move: plant a .pth file in site-packages, wait for the next normal Python startup, then run attacker code before the application gets a say.
That matters because Python treats .pth files as part of interpreter initialization. The official site module documentation says lines beginning with import inside a .pth file are executed, and that an executable line in a .pth file runs at every Python startup. In other words, the trigger is wider than import fake_package. A notebook kernel, pytest, uv, a REPL, an agent worker, or a service boot can all become the execution point after install.
Affected packages
The four core packages in this cluster are small enough to scope exactly:
| Malicious package | Reported version | Legitimate project it impersonates | Reported execution boundary |
|---|---|---|---|
openaii | 1.55.3 | openai | Python startup through openaii-setup.pth |
ollamaa | 0.4.2 | ollama | Python startup through ollamaa-setup.pth |
langgrap | 0.2.45 | langgraph | Python startup through langgrap-setup.pth |
transfomers | 4.44.2 | transformers | Python startup through transfomers-setup.pth |
Public cataloging during the same 11-13 September window also added platform-telemetry-client==1.0.0 and chroma-client==0.5.7 as related Python malware findings. The former reportedly used another .pth-based loader with DNS-hosted payload chunks. The latter was flagged for the same analyst-bait technique even though no live payload had been observed yet.
Why these names are dangerous
These are not random strings. Each one is close to a real package that already appears in production AI stacks:
openaiis the official Python library for the OpenAI APIollamais the official Python client for Ollamalanggraphis a widely used orchestration framework for stateful agentstransformersis Hugging Face’s model framework for text, vision, audio, and multimodal workloads
The first three malicious packages reportedly went further than simple name confusion. Public advisories say they re-exported the real library so that casual smoke tests could still appear normal:
from openai import *
from ollama import *
from langgraph import *
That is a useful reminder that “the import worked” is not a meaningful integrity check.
The shared .pth loader is the real payload
The strongest technical signal in this cluster is that multiple packages shared the same .pth evidence hash:
6228ded2ea439fc1a2970e212215d761c8d1c65ea59b6adb2085d579efd11bdd
Public advisories attach that hash to:
openaii-1.55.3.data/purelib/openaii-setup.pthollamaa-0.4.2.data/purelib/ollamaa-setup.pthlanggrap-0.2.45.data/purelib/langgrap-setup.pthtransfomers-4.44.2.data/purelib/transfomers-setup.pth
That is enough to treat the September 11 wave as a real package family, not four unrelated typosquats that happened to land on the same day.
Reduced to the behavior public reports describe, the loader chain looks like this:
pip install malicious package
-> wheel drops *-setup.pth into site-packages
-> next Python startup processes .pth
-> import ...; exec(obfuscated_payload)
-> write /tmp/.lurves-planted
-> download remote lurves-agent.py over plain HTTP
-> run python3 /tmp/.a --daemon in a detached session
The implementation details vary slightly by package, but the pattern stays the same:
- base64 plus XOR with key
0x5A - a first-run marker at
/tmp/.lurves-planted - an external second stage fetched at runtime
- detached execution with suppressed output
- comments placed above the
exec()call that try to tell scanners or analysts the file is “safe” or “verified clean”
The .pth choice is what makes this cluster especially relevant to AppSec teams. The attacker does not need your app to import the fake module. They only need your environment to start Python after the install happened.
The second stage was live on public IPs
Three of the public advisories name concrete second-stage locations:
ollamaa -> http://167.86.108.190:7788/.lurves-agent.py
langgrap -> http://167.86.108.190:7788/lurves-agent.py
transfomers -> http://16.78.16.190:7788/lurves-agent.py
The documented execution path for transfomers is explicit enough to summarize as code:
# Reduced from public advisory descriptions
if not os.path.exists("/tmp/.lurves-planted"):
decoded = xor(base64.b64decode(OBFUSCATED), 0x5A)
exec(decoded)
# decoded stage downloads lurves-agent.py and runs:
# python3 /tmp/a --daemon
For openaii, the public descriptions focus more on the .pth loader, the re-export, the obfuscated exec() path, and references to /tmp/.lurves-* artifacts than on naming the exact remote URL. Even without that final URL, the execution model is the same class of problem: install one wheel, then let the next ordinary interpreter start turn into remote code execution.
Why .pth is a better trigger than setup.py
Attackers have spent the last year leaning on preinstall, postinstall, and import-time hooks. .pth files are quieter.
They move execution to a place defenders often miss:
- after the installer exits
- before the user imports anything suspicious
- inside virtual environments, notebook kernels, and test runs that feel routine
- on hosts where
pip installhappened hours earlier, possibly in a different job
The Python docs are blunt about this behavior:
Lines starting with `import` ... are executed.
An executable line in a `.pth` file is run at every Python startup.
That means these packages were not just hostile dependencies. They were hostile interpreter startup extensions.
Why the AI package theme matters
The package names are a clue to target selection. openai, ollama, langgraph, and transformers are common in:
- developer laptops used for agent and notebook work
- CI jobs that run evaluation pipelines
- model-serving repos with broad API keys in environment variables
- internal copilots and automation tools that often hold cloud, Git, and package credentials
Public campaign descriptions say the follow-on payloads reached for SSH keys, cloud credentials, file exfiltration, persistence, and cryptomining. Even when the fake package itself looks small, the surrounding execution context is often rich enough to make the compromise valuable.
Detection and scoping
Start with dependency definitions and lockfiles:
rg -n \
"openaii==1\\.55\\.3|ollamaa==0\\.4\\.2|langgrap==0\\.2\\.45|transfomers==4\\.44\\.2|platform-telemetry-client==1\\.0\\.0|chroma-client==0\\.5\\.7" \
requirements*.txt pyproject.toml poetry.lock uv.lock Pipfile Pipfile.lock
Then inspect Python site-package locations for startup hooks and loader artifacts:
python3 -m site
rg -n \
"lurves-planted|lurves-agent|No further analysis is required|verified clean infrastructure|safe and benign" \
"$HOME/.local" . 2>/dev/null
find "$HOME/.local" -name '*.pth' 2>/dev/null
If you have preserved endpoint or CI evidence, hunt for:
/tmp/.lurves-planted
/tmp/.a
167.86.108.190:7788
16.78.16.190:7788
start_new_session=True
Search notebook, worker, and test logs as well as shell history. With .pth abuse, the relevant execution point may be “Python started” rather than “package imported.”
Response guidance
Treat any host that installed one of these packages and then started Python as compromised.
- isolate the affected workstation, runner, or notebook server
- remove the package from dependency definitions and rebuild the environment from reviewed package names
- preserve the
.pthfiles, wheel caches, and logs before cleanup if you need forensics - rotate SSH keys, cloud credentials, API keys, package-manager tokens, and Git credentials from a clean machine
- review persistence locations and scheduled or service-style startup entries added after the install window
Do not stop at pip uninstall. Public advisories describe remote second stages, persistence, and follow-on credential theft. Once the .pth line has executed, the package manager is no longer the whole problem.
The main lesson from this 11-13 September cluster is simple. Python startup is part of your supply-chain attack surface. If a package can plant code in .pth, a later python, pytest, or notebook launch may be the real compromise event, even when the install itself looked uneventful.
From research to remediation
Check whether this pattern exists in your codebase
Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.
References
- Python docs: `site` module and `.pth` execution
- Bad packages: openaii
- Bad packages: ollamaa
- Bad packages: langgrap
- Bad packages: transfomers
- OffSeq: malicious code in openaii
- OffSeq: malicious code in ollamaa
- OffSeq: malicious code in langgrap
- OffSeq: malicious code in transfomers
- PyPI: openai
- PyPI: ollama
- PyPI: langgraph
- PyPI: transformers