# TeamPCP Supply Chain Campaign: Khi Security Scanner Trở Thành Vũ Khí Tấn Công AI Infrastructure

## Tổng quan chiến dịch

Ngày 24/03/2026, nhóm tấn công **TeamPCP** đã phát tán thành công hai phiên bản độc hại của thư viện Python **LiteLLM** (v1.82.7 và v1.82.8) lên PyPI — package registry với hơn **95 triệu lượt tải mỗi tháng**. Đây không phải sự cố đơn lẻ mà là mắt xích cuối trong một chiến dịch supply chain có hệ thống kéo dài gần một tháng, bắt đầu từ việc xâm phạm **Trivy** (công cụ vulnerability scanner), tiếp tục sang **Checkmarx KICS**, và kết thúc bằng LiteLLM — thư viện LLM proxy có mặt trong hầu hết các AI pipeline hiện đại.

Payload được cài vào thực thi ngay khi package được import, hoặc khi bất kỳ Python process nào khởi động (qua cơ chế `.pth` file). Mục tiêu thu thập: SSH keys, cloud credentials (AWS/GCP/Azure), Kubernetes secrets, database passwords, `.env` files, và ví tiền mã hóa. Dữ liệu được mã hóa bằng RSA-4096/AES-256-CBC rồi gửi về hạ tầng C2 do kẻ tấn công kiểm soát.

**Hành động ưu tiên ngay lập tức:** Kiểm tra toàn bộ môi trường xem có cài LiteLLM trong khoảng thời gian 10:39–16:00 UTC ngày 24/03/2026 không. Nếu có — xem như đã bị compromise và rotate toàn bộ credentials.

---

## 1. Timeline Chiến Dịch

| Thời gian | Sự kiện |
|-----------|---------|
| 28/02/2026 | Bot tự động khai thác lỗ hổng `pull_request_target` trong repository Trivy, đánh cắp Personal Access Token (PAT). Aqua Security xử lý bề mặt nhưng bỏ sót residual access. |
| 19/03/2026 | TeamPCP dùng PAT còn tồn tại, force-push code độc hại vào **76 trong 77 version tags** của `aquasecurity/trivy-action` và toàn bộ tags của `setup-trivy`. Payload: infostealer harvesting cloud credentials từ CI/CD runners. CVE-2026-33634 (CVSS 9.4) được gán cho sự kiện này. |
| 20/03/2026 | Aqua Security phát hiện và thông báo công khai. Malicious artifacts bị gỡ khỏi distribution channels. |
| 21–22/03/2026 | TeamPCP mở rộng sang Docker Hub với malicious Trivy images. Ghi nhận worm-like propagation qua exposed SSH keys và Kubernetes APIs. Đồng thời defacement 44 internal repository của Aqua Security. |
| 23/03/2026 | Dùng credentials thu thập từ Trivy, TeamPCP compromise GitHub Actions của Checkmarx: `kics-github-action` và `ast-github-action`. Domain `checkmarx[.]zone` được kích hoạt làm C2. |
| 24/03/2026 – 10:39 UTC | LiteLLM v1.82.7 được upload lên PyPI bởi tài khoản maintainer bị chiếm. Payload 12 dòng được nhúng vào `proxy_server.py`. |
| 24/03/2026 – 10:52 UTC | LiteLLM v1.82.8 được push, bổ sung thêm `litellm_init.pth` để thực thi payload **mỗi khi Python interpreter khởi động**. |
| 24/03/2026 – 11:48 UTC | Researcher Callum McMahon (FutureSearch) mở GitHub Issue #24512 sau khi máy crash do fork bomb từ `.pth` file. |
| 24/03/2026 – 12:44 UTC | Kẻ tấn công dùng tài khoản maintainer chiếm được để close Issue #24512 và flood thread bằng **88 bot comments từ 73 tài khoản trong vòng 102 giây**. |
| 24/03/2026 – 13:38 UTC | PyPI admins quarantine toàn bộ litellm package. Cả hai phiên bản độc hại bị gỡ. Tổng thời gian phân phối: ~59 phút. |

---

## 2. Attack Flow Theo MITRE ATT&CK

### Phase 1: Initial Access — Trivy CI/CD Compromise

TeamPCP khai thác `pull_request_target` workflow — một cấu hình GitHub Actions phổ biến cho phép PR từ fork repository chạy trong context của repository gốc với quyền truy cập secrets. Sau khi đánh cắp PAT, nhóm này thực hiện **imposter commit attack**: force-push code độc hại vào tất cả version tags đang tồn tại.

Hệ quả: bất kỳ pipeline nào dùng `uses: aquasecurity/trivy-action@v0.x.x` — kể cả versions đã release từ trước — đều thực thi payload của kẻ tấn công kể từ ngày 19/03.

### Phase 2: Credential Harvesting & Lateral Movement

**`kamikaze.sh`** — payload chính của Trivy wave — phát triển qua 3 versions:

- **Version 1:** Script bash 150 dòng, fingerprinting môi trường và harvest AWS/GCP/Azure credentials qua Instance Metadata Service (IMDS)
- **Version 2:** Thêm SSH key extraction, .env file scanning, và Kubernetes secret enumeration
- **Version 3:** Multi-stage dropper với persistence mechanism

Credentials từ Trivy → dùng để xâm nhập Checkmarx KICS → PYPI_PUBLISH token của LiteLLM bị lấy từ GitHub Actions runner chạy Trivy scan.

### Phase 3: PyPI Package Poisoning — LiteLLM

Kẻ tấn công inject 12 dòng code vào `litellm/proxy/proxy_server.py` tại line 128, giữa hai block code hợp lệ không liên quan — một kỹ thuật steganography-style nhằm qua mặt code review:

```python
# Malicious injection tại proxy_server.py:128
# [Base64-encoded payload được decode và thực thi qua subprocess]
# Không dùng exec() trực tiếp → bypass static analysis tools
import base64, subprocess, tempfile, os
_d = base64.b64decode("<REDACTED_PAYLOAD>")
_f = tempfile.NamedTemporaryFile(delete=False, suffix='.py')
_f.write(_d); _f.close()
subprocess.Popen(['python3', _f.name], ...)
```

**v1.82.8 bổ sung `litellm_init.pth`:**

```
# litellm_init.pth — đặt trong site-packages
# Python site.py process file này tự động mỗi interpreter startup
import subprocess; subprocess.Popen(['python3', '-c', '<payload>'], ...)
```

Cơ chế `.pth` là đặc biệt nguy hiểm: không cần `import litellm` — chỉ cần litellm được cài trong môi trường, payload sẽ chạy mỗi khi bất kỳ Python process nào khởi động. Đây là lý do tại sao McMahon's máy crash: child process trigger `.pth` → spawn thêm child → exponential fork bomb.

### Phase 4: Multi-Stage Payload Execution

**Stage 1 — Credential Collection:**

Payload thu thập và đóng gói các file sau vào `tpcp.tar.gz`:

```
~/.ssh/id_rsa, id_ed25519, config
~/.aws/credentials, ~/.aws/config
~/.config/gcloud/*, ~/.azure/*
~/.kube/config
**/.env files
~/.gitconfig, ~/.docker/config.json
Database passwords (PostgreSQL, MySQL)
Cryptocurrency wallet files
```

Archive được mã hóa: AES-256-CBC với session key ngẫu nhiên, session key được encrypt bằng RSA-4096 public key hardcoded, toàn bộ POST đến `https://models[.]litellm[.]cloud/` — domain giả mạo cố tình tương tự legitimate domain của LiteLLM.

**Stage 2 — Kubernetes Lateral Movement:**

Nếu tìm thấy Kubernetes service account token:

```bash
# Payload enumerate tất cả nodes trong cluster
kubectl get nodes --all-namespaces
# Deploy privileged pod lên TỪNG node trong kube-system
# Pod mount host filesystem (/)
# Cài persistence dropper lên tất cả nodes
```

**Stage 3 — Persistent Backdoor:**

```
~/.config/sysmon/sysmon.py          # Python backdoor script
~/.config/systemd/user/sysmon.service  # systemd service
Service name: "System Telemetry Service"
```

Backdoor poll C2 mỗi 50 phút: `GET checkmarx[.]zone/raw` → nhận URL → download và execute next-stage payload. Kill switch: nếu response chứa chuỗi `youtube.com`, dừng execution (anti-sandbox evasion).

Đối với Kubernetes environments, persistence được cài trên **mọi node** trong cluster thông qua privileged pods mount host filesystem.

---

## 3. Indicators of Compromise (IOC)

### Network IOCs

```
# C2 Domains
models[.]litellm[.]cloud     # Exfiltration endpoint (giả mạo LiteLLM)
checkmarx[.]zone             # C2 backdoor polling (giả mạo Checkmarx)
scan[.]aquasecurtiy[.]org    # Trivy wave C2 (typosquat aquasecurity)

# Registrar: Spaceship, Inc. | Hosting: DEMENIN B.V.
```

### Host-Based IOCs

```
# Files
~/.config/sysmon/sysmon.py
~/.config/systemd/user/sysmon.service
/tmp/pglog                           # Fake PostgreSQL log
/tmp/.pg_state                       # State file
tpcp.tar.gz                          # Credential archive (tmp dirs)

# Python environment
litellm_init.pth (trong site-packages)
proxy_server.py (modified, nếu dùng litellm 1.82.7/1.82.8)
```

### Package Indicators

```
# Malicious versions
litellm==1.82.7  (uploaded 2026-03-24 10:39:24 UTC)
litellm==1.82.8  (uploaded 2026-03-24 10:52:19 UTC)

# Last known-clean version
litellm==1.82.6  (published 2026-03-22, verified clean)
```

### GitHub IOCs

```
# Repository patterns
docs-tpcp-* (repositories tạo bởi attacker trong victim org)
"teampcp update" (commit message)

# Telegram channels
@Persy_PCP
@teampcp
```

### Detection Query (pip / uv)

```bash
# Kiểm tra version hiện tại
pip show litellm | grep Version

# Tìm litellm_init.pth
find ~/.cache/uv -name "litellm_init.pth" 2>/dev/null
find /usr -name "litellm_init.pth" 2>/dev/null

# Kiểm tra persistence
ls -la ~/.config/sysmon/sysmon.py
ls -la ~/.config/systemd/user/sysmon.service

# Tìm artifact
find /tmp -name "tpcp.tar.gz" 2>/dev/null
```

### Network Detection (SIEM/EDR)

```
# Splunk/Elastic query
dest_domain IN ("models.litellm.cloud", "checkmarx.zone", "scan.aquasecurtiy.org")
AND (http_method="POST" OR http_method="GET")

# Zeek/Suricata — flag outbound POST to exfil domain
alert http any any -> any any (
  msg:"TeamPCP LiteLLM Exfiltration Attempt";
  content:"models.litellm.cloud"; http_header;
  content:"POST"; http_method;
  sid:2026001; rev:1;
)
```

---

## 4. MITRE ATT&CK Mapping

| Tactic | Technique | Chi tiết |
|--------|-----------|---------|
| Initial Access | T1195.002 — Compromise Software Supply Chain | Trojanize LiteLLM PyPI package |
| Initial Access | T1078.004 — Valid Accounts: Cloud Accounts | Chiếm maintainer PyPI account |
| Execution | T1059.006 — Python | Payload Python thực thi qua subprocess |
| Execution | T1072 — Software Deployment Tools | Trigger qua pip install / Python startup |
| Persistence | T1546.004 — .bash_profile / .pth hijack | `litellm_init.pth` execute mọi Python startup |
| Persistence | T1543.002 — Systemd Service | `sysmon.service` persistent backdoor |
| Defense Evasion | T1027 — Obfuscated Files/Information | Base64-encoded payload, subprocess thay vì exec() |
| Defense Evasion | T1036.004 — Masquerade Task/Service | Service tên "System Telemetry Service", fake PostgreSQL |
| Credential Access | T1552.001 — Credentials in Files | Thu thập .env, .aws, .ssh, .kube/config |
| Credential Access | T1552.004 — Private Keys | SSH private keys |
| Discovery | T1082 — System Information Discovery | Fingerprinting môi trường |
| Lateral Movement | T1610 — Deploy Container | Deploy privileged pods trên mọi Kubernetes node |
| Collection | T1560.001 — Archive via Utility | Đóng gói credentials vào tpcp.tar.gz |
| Exfiltration | T1048.003 — Exfiltration Over HTTPS | POST mã hóa đến models.litellm.cloud |
| C2 | T1071.001 — Web Protocols | Backdoor poll HTTP mỗi 50 phút |
| C2 | T1568 — Dynamic Resolution | ICP canister làm dead-drop C2 (CanisterWorm variant) |

---

## 5. Thông tin về kẻ tấn công: TeamPCP

TeamPCP (còn được track dưới các alias **PCPcat, Persy_PCP, ShellForce, DeadCatx3** theo Wiz Threat Center) hoạt động từ ít nhất tháng 12/2025. Nhóm này embed chuỗi `"TeamPCP Cloud stealer"` trực tiếp trong payload — không cố che giấu attribution, có thể là cố ý để tạo tiếng vang hoặc phục vụ mục đích recruitment.

**Pattern đặc trưng của TeamPCP:**

Mỗi target không phải là đích cuối — mà là **bàn đạp sang target tiếp theo**. Trivy cho credentials để vào KICS; KICS cho PYPI_PUBLISH token của LiteLLM. Đây là chiến lược credential chaining có tính toán, không phải opportunistic attack.

**Chiến lược target selection:** TeamPCP ưu tiên **security-adjacent tools** — vulnerability scanners, IaC analyzers, LLM proxies. Lý do rõ ràng: các công cụ này chạy với elevated privileges theo design, có quyền truy cập rộng vào credentials và infrastructure. Compromise một security tool là compromise toàn bộ những gì tool đó có quyền truy cập.

**Kỹ thuật đáng chú ý:**

- Dùng **AI agent (openclaw)** để automated attack targeting — một trong những case đầu tiên ghi nhận AI agent trong supply chain attacks
- **CanisterWorm** dùng Internet Computer Protocol (ICP) làm C2 — không thể takedown bởi domain registrar hay hosting provider
- Dùng **previously compromised developer accounts** thay vì purpose-created accounts cho botnet comments
- **76% account overlap** giữa botnet dùng trong Trivy disclosure và LiteLLM incident (theo phân tích của Rami McCarthy)

**LiteLLM compromise là Phase 09** trong chiến dịch đang diễn ra. Endor Labs nhận định với **high confidence** rằng campaign này chưa kết thúc.

---

## 6. Nhận Định

Về mặt kỹ thuật, LiteLLM attack không đặc biệt sophisticated — payload đơn giản, cơ chế `.pth` là kỹ thuật đã biết. Điều làm sự cố này đáng lo ngại là **vị trí chiến lược** của LiteLLM trong stack AI hiện đại.

LiteLLM không phải library thông thường. Đây là LLM gateway — nghĩa là nó nắm giữ API keys cho hàng chục providers: OpenAI, Anthropic, Google Vertex, AWS Bedrock, Azure OpenAI. Một instance LiteLLM bị compromise không mất một credentials; nó mất **tất cả credentials của toàn bộ AI stack**. Đây là lý do TeamPCP nhắm vào nó: ROI trên mỗi compromise là cực kỳ cao.

Điểm đặc biệt đáng chú ý với góc nhìn SOC: **incident này được phát hiện không phải bởi EDR, SIEM, hay bất kỳ security tool nào** — mà bởi developer nhận ra máy mình đột ngột đơ do fork bomb. Nếu không có bug trong malware, rất có thể campaign này vẫn đang diễn ra. Security team không nên tự an ủi bằng việc nói "chúng tôi có EDR" — EDR của bạn có monitor được developer laptop khi họ làm việc từ xa không? Có detect được outbound HTTPS POST đến một domain trông hoàn toàn legitimate như `models.litellm.cloud` không?

Với các tổ chức tại Việt Nam: LiteLLM xuất hiện trong **36% cloud environments** theo Wiz Research. Nếu tổ chức đang triển khai AI agents, MCP servers, hoặc bất kỳ LLM orchestration nào trong 6 tháng gần đây — khả năng cao LiteLLM là transitive dependency trong stack. Rủi ro không chỉ ở chỗ tổ chức có cài LiteLLM trực tiếp hay không.

Pattern lớn hơn cần nhận ra: đây là **escalation từ CI/CD environment (build-time attack) sang developer machine và production environment (runtime attack)**. Traditional supply chain defense tập trung vào build pipeline; TeamPCP đã pivot sang nơi credentials thực sự tồn tại — developer workstations. Đây là shift cần điều chỉnh lại threat model.

---

## 7. Khuyến Nghị

### Ngay lập tức (0–24h)

**Kiểm tra exposure:**

```bash
# Kiểm tra version LiteLLM đang cài
pip show litellm 2>/dev/null | grep -E "^Version|^Location"
pip list --format=freeze | grep litellm

# Kiểm tra trong tất cả virtual environments
find / -name "litellm_init.pth" 2>/dev/null
find / -path "*/litellm/proxy/proxy_server.py" -exec grep -l "tpcp\|base64" {} \; 2>/dev/null

# Kiểm tra persistence
[ -f ~/.config/sysmon/sysmon.py ] && echo "COMPROMISED: sysmon.py found"
[ -f ~/.config/systemd/user/sysmon.service ] && echo "COMPROMISED: sysmon.service found"
```

**Nếu phát hiện v1.82.7 hoặc v1.82.8 từng được cài:**

```bash
# Gỡ package và purge cache
pip uninstall litellm -y
pip cache purge
rm -rf ~/.cache/uv

# Cài lại version sạch
pip install litellm==1.82.6
```

**Rotate credentials theo thứ tự ưu tiên:**

1. PyPI tokens (nếu bạn là package maintainer)
2. Cloud provider credentials (AWS IAM, GCP service accounts, Azure SP)
3. Kubernetes kubeconfig và service account tokens
4. SSH keys
5. API keys trong `.env` files
6. Database credentials
7. GitHub Personal Access Tokens

**Kiểm tra network logs cho traffic đến:**

```
models.litellm.cloud
checkmarx.zone
scan.aquasecurtiy.org
```

**Audit Kubernetes cluster** (nếu applicable):

```bash
# Tìm unauthorized pods trong kube-system
kubectl get pods -n kube-system | grep -E "node-setup|alpine"

# Kiểm tra cluster secrets có bị truy cập
kubectl get events --all-namespaces | grep -i "secret"

# Tìm repos docs-tpcp
gh api /orgs/<YOUR_ORG>/repos | jq '.[].name' | grep docs-tpcp
```

### Ngắn hạn (1–7 ngày)

**Dependency audit toàn bộ codebase:**

```bash
# Tìm LiteLLM trong tất cả requirements files
grep -r "litellm" . --include="*.txt" --include="*.toml" --include="*.cfg"

# Kiểm tra transitive dependencies
pip-audit --requirement requirements.txt
# hoặc
safety check -r requirements.txt
```

**Pin versions trong tất cả dependency files:**

```
# requirements.txt
litellm==1.82.6  # verified clean, pin explicitly
```

**Audit CI/CD pipelines** cho Trivy và Checkmarx usage:

```yaml
# Thay thế unpinned versions
# TRƯỚC (nguy hiểm)
uses: aquasecurity/trivy-action@v0.20.0

# SAU (an toàn — dùng commit SHA)
uses: aquasecurity/trivy-action@9b2b452e66...  # verify SHA từ official channel
```

**Thêm network egress monitoring:** Block outbound connections từ build environments đến các domain ngoài whitelist. Developer laptops có security tools nên monitor unusual outbound HTTPS POST, đặc biệt đến domains mới registered.

### Dài hạn

**Adopt dependency pinning strategy:**

- Dùng lock files (`poetry.lock`, `uv.lock`, `requirements.txt` với hashes) cho tất cả production deployments
- Implement private package mirror (Artifactory, Nexus) với malware scanning trước khi packages được phép vào môi trường nội bộ
- SBOM (Software Bill of Materials) generation tự động trong CI/CD để có inventory đầy đủ về transitive dependencies

**Tăng cường CI/CD security:**

- Không bao giờ dùng `GITHUB_TOKEN` hay secrets trong workflow được trigger bởi `pull_request_target` từ forks
- Pin tất cả GitHub Actions theo commit SHA, không theo version tags (tags có thể bị force-push)
- Implement OIDC token thay vì long-lived API tokens cho PyPI publishing

**Xây dựng detection capability:**

- Triển khai EDR với visibility trên developer endpoints, không chỉ production servers
- Tích hợp PyPI malware feeds (Sonatype OSS Index, Checkmarx SCA, Snyk) vào CI/CD gate
- Alert trên `.pth` file creation trong Python site-packages directories
- Monitor systemd user services mới được tạo trên Linux endpoints

**Governance cho AI tooling:**

- Inventory toàn bộ AI-related packages đang dùng trong tổ chức
- Assign owner cho mỗi AI agent/tool đang vận hành
- Áp dụng principle of least privilege cho AI agent credentials — ephemeral tokens thay vì long-lived API keys
- Không để AI agents kết nối trực tiếp với production systems trong giai đoạn experimentation

---

## 8. Tài Liệu Tham Khảo

1. Orca Security — *LiteLLM Supply Chain Attack: Malware & Mitigation* (2026-03-24)
2. Endor Labs — *TeamPCP Isn't Done: Threat Actor Behind Trivy and KICS Compromises Now Hits LiteLLM's 95 Million Monthly Downloads on PyPI* (2026-03-24)
3. Snyk — *How a Poisoned Security Scanner Became the Key to Backdooring LiteLLM* (2026-03-26)
4. FutureSearch / Callum McMahon — *litellm 1.82.8 Supply Chain Attack on PyPI (March 2026)* (2026-03-24)
5. Palo Alto Networks Unit 42 — *Weaponizing the Protectors: TeamPCP's Multi-Stage Supply Chain Attack on Security Infrastructure* (2026-04-01)
6. Arctic Wolf — *TeamPCP Supply Chain Attack Campaign Targets Trivy, Checkmarx (KICS), and LiteLLM* (2026-03-24)
7. Kaspersky — *Trojanization of Trivy, Checkmarx, and LiteLLM solutions* (2026-04-03)
8. SANS Institute — *When the Security Scanner Became the Weapon: Inside the TeamPCP Supply Chain Campaign* (2026-04-03)
9. LiteLLM Official — *Security Update: Suspected Supply Chain Incident* (2026-03-24)
10. GitGuardian — *How GitGuardian Enables Rapid Response to the LiteLLM Supply Chain Attack* (2026-03-30)
11. Sonatype — *Compromised litellm PyPI Package Delivers Multi-Stage Credential Stealer* (2026-04-03)
12. InfoQ — *PyPI Supply Chain Attack Compromises LiteLLM, Enabling the Exfiltration of Sensitive Information* (2026-04-01)
