critical

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 packageReported versionLegitimate project it impersonatesReported execution boundary
openaii1.55.3openaiPython startup through openaii-setup.pth
ollamaa0.4.2ollamaPython startup through ollamaa-setup.pth
langgrap0.2.45langgraphPython startup through langgrap-setup.pth
transfomers4.44.2transformersPython 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:

  • openai is the official Python library for the OpenAI API
  • ollama is the official Python client for Ollama
  • langgraph is a widely used orchestration framework for stateful agents
  • transformers is 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.pth
  • ollamaa-0.4.2.data/purelib/ollamaa-setup.pth
  • langgrap-0.2.45.data/purelib/langgrap-setup.pth
  • transfomers-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 install happened 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.

  1. isolate the affected workstation, runner, or notebook server
  2. remove the package from dependency definitions and rebuild the environment from reviewed package names
  3. preserve the .pth files, wheel caches, and logs before cleanup if you need forensics
  4. rotate SSH keys, cloud credentials, API keys, package-manager tokens, and Git credentials from a clean machine
  5. 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