+ "details": "## Summary\n\nOn March 27, 2026, a threat actor used compromised PyPI credentials to publish malicious versions 4.87.1 and 4.87.2 of the `telnyx` Python package directly to PyPI. These versions contain credential-stealing malware and were not published through the legitimate GitHub release pipeline.\n\n## Exposure Window\n\n| Version | Published (UTC) | Quarantined (UTC) | Exposure |\n|---------|-----------------|-------------------|----------|\n| 4.87.1 (broken) | 2026-03-27 03:51 | 2026-03-27 10:13 | 6h 22m |\n| 4.87.2 (functional) | 2026-03-27 04:07 | 2026-03-27 10:13 | 6h 6m |\n\n\n**Both versions were quarantined by PyPI at 2026-03-27 10:13 UTC.**\n\n**Note:** Version 4.87.1 contained a typo that prevented the malware from executing. Only 4.87.2 was fully functional.\n\n## Who Is Affected\n\nYou may be affected if:\n- You installed or upgraded the `telnyx` Python package between 03:51 UTC and 10:13 UTC on March 27, 2026\n- You ran `pip install telnyx` without pinning a version and received 4.87.1 or 4.87.2\n- A dependency in your project pulled in `telnyx` as a transitive, unpinned dependency\n\nYou are NOT affected if:\n- You pinned to version 4.87.0 or earlier\n- You installed before March 27, 2026 and did not upgrade\n- You built from GitHub source (malicious code was never committed to the repository)\n\n## Attack Details\n\n### Root Cause\n\nThe attacker obtained the PyPI API token and uploaded malicious packages directly to PyPI, bypassing the GitHub release pipeline entirely. No malicious commits exist in the GitHub repository.\n\n### Malicious Behavior\n\nThe malware is injected into `telnyx/_client.py` (74 additional lines) and executes on `import telnyx`:\n\n**Linux/macOS:**\n1. Spawns detached subprocess to survive parent exit\n2. Downloads payload hidden inside WAV audio file (steganography) from C2\n3. Harvests credentials: SSH keys, AWS/GCP/Azure creds, Kubernetes tokens, Docker configs, .env files, database credentials, crypto wallets\n4. If Kubernetes access found, deploys privileged pods to all nodes for lateral movement\n5. Encrypts with AES-256-CBC + RSA-4096, exfiltrates to C2\n\n**Windows:**\n1. Downloads binary hidden inside WAV file from C2\n2. Drops as `msbuild.exe` in Startup folder for persistence\n3. Executes with hidden window\n\n### Version Differences\n\n| Version | Status | Notes |\n|---------|--------|-------|\n| 4.87.1 | Broken | Typo: `Setup()` instead of `setup()` caused NameError |\n| 4.87.2 | Functional | Attacker uploaded 16 minutes later to fix their own casing error; full attack chain operational |\n\n## Verified Safe Version\n\n| Version | File | SHA-256 |\n|---------|------|--------|\n| **4.87.0** | `telnyx-4.87.0-py3-none-any.whl` | `5aeb8172c29ade224e6c2d166713f304596aa21e3dbfa5b6b2b028e6997f6bd2` |\n| **4.87.0** | `telnyx-4.87.0.tar.gz` | `3f093a85c313c2b779594f99fc07f453f1a7fd8785878d963688c531ff94d03a` |\n\n## Recommended Actions\n\n### 1. Check If You Are Affected\n\n```bash\n# Check installed version\npip show telnyx | grep Version\n\n# Check pip cache for telnyx versions\npip cache list telnyx 2>/dev/null\n\n# Check when telnyx was installed (modification time)\nls -la $(python -c \"import site; print(site.getsitepackages()[0])\")/telnyx* 2>/dev/null\n```\n\n### 2. Remove Compromised Versions\n\n```bash\npip uninstall telnyx\n```\n\n### 3. Rotate All Potentially Exposed Secrets\n\nIf there is any possibility that version 4.87.1 or 4.87.2 was installed in your environment, treat all accessible secrets as compromised:\n\n- SSH keys\n- AWS/GCP/Azure credentials\n- Kubernetes tokens and service accounts\n- Docker registry credentials\n- Database passwords\n- API keys in .env files\n- Telnyx API keys\n\n### 4. Check for Persistence (Linux/macOS)\n\n```bash\n# Check for malicious systemd service\nsystemctl --user status audiomon 2>/dev/null\nls -la ~/.config/audiomon/ 2>/dev/null\n\n# Check state file\nls -la /tmp/.initd_state 2>/dev/null\n```\n\n### 5. Check for Persistence (Windows)\n\n```powershell\n# Check Startup folder\nGet-ChildItem \"$env:APPDATA\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\msbuild.exe\"\n```\n\n### 6. Pin to Safe Version\n\n\n```bash\npip install telnyx==4.87.0\n```\n\nOr in requirements.txt:\n```\ntelnyx==4.87.0\n```\n\n## Indicators of Compromise\n\n### Malicious Package Hashes\n\n| File | SHA-256 |\n|------|--------|\n| `telnyx-4.87.1-py3-none-any.whl` | `7321caa303fe96ded0492c747d2f353c4f7d17185656fe292ab0a59e2bd0b8d9` |\n| `telnyx-4.87.2-py3-none-any.whl` | `cd08115806662469bbedec4b03f8427b97c8a4b3bc1442dc18b72b4e19395fe3` |\n\n### Network\n\n| IoC | Type |\n|-----|------|\n| `83.142.209.203` | C2 IP address |\n| `http://83.142.209.203:8080/ringtone.wav` | Payload endpoint (Linux/macOS) |\n| `http://83.142.209.203:8080/hangup.wav` | Payload endpoint (Windows) |\n| `http://83.142.209.203:8080/raw` | Persistence polling endpoint |\n\n### Filesystem\n\n| Path | Platform | Purpose |\n|------|----------|--------|\n| `~/.config/audiomon/audiomon.py` | Linux/macOS | Persistence implant |\n| `~/.config/systemd/user/audiomon.service` | Linux | Persistence service |\n| `/tmp/.initd_state` | Linux/macOS | State tracking |\n| `%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\msbuild.exe` | Windows | Persistence binary |\n| `msbuild.exe.lock` | Windows | 12-hour cooldown lock |\n\n### Exfiltration\n\n- Archive name: `tpcp.tar.gz`\n- HTTP header: `X-Filename: tpcp.tar.gz`\n- Encryption: AES-256-CBC + RSA-4096 OAEP\n\n## Attribution\n\nThis attack is attributed to **TeamPCP** with high confidence based on:\n\n- Identical RSA-4096 public key as the LiteLLM compromise (March 24, 2026)\n- `tpcp.tar.gz` archive naming convention (TeamPCP signature)\n- Identical AES-256-CBC + RSA OAEP encryption scheme\n- Same credential harvesting targets and techniques\n\nRSA Key Hash:\n- PEM SHA-256: `4eceb569b4330565b93058465beab0e6d5ea09cfba8e7f29d7be1b5a2abd958a`\n\n## Resources\n\n- https://github.com/team-telnyx/telnyx-python/issues/235\n- https://www.endorlabs.com/learn/teampcp-strikes-again-telnyx-compromised-three-days-after-litellm\n- https://ramimac.me/teampcp",
0 commit comments