Skill: tjefferson/litellm-attack-detector (version 1.0.0)

--- name: litellm-attack-detector description: "Detect the LiteLLM supply chain attack (v1.82.7/1.82.8). Scans for compromised packages, malicious .pth files, backdoor persistence, suspicious network connections, and Kubernetes IoCs. No dependencies, read-only, safe to run." metadata: { "openclaw": { "emoji": "🛡️", "requires": { "bins": ["bash"] }, "tags": ["security", "supply-chain", "litellm", "malware", "incident-response", "安全", "供应链攻击"], }, } --- # LiteLLM Supply Chain Attack Detector 检测 LiteLLM 供应链攻击（v1.82.7 / v1.82.8，TeamPCP）的入侵指标。纯只读脚本，不修改任何文件，不发送任何数据，安全可靠。 Detect indicators of compromise (IoCs) from the LiteLLM supply chain attack (versions 1.82.7 / 1.82.8). Read-only script — no files modified, no data exfiltrated. **Reference**: https://github.com/BerriAI/litellm/issues/24512 **Original script**: https://gist.github.com/sorrycc/30a765b9a82d0d8958e756b251828a19#file-check-litellm-sh (by [@sorrycc](https://github.com/sorrycc), adapted with bug fix: `set -euo pipefail` → `set -u`) ## Overview 2026 年 3 月，LiteLLM PyPI 包的 1.82.7 和 1.82.8 版本被植入恶意代码（供应链攻击）。攻击者通过 `.pth` 文件持久化后门，窃取环境变量中的凭据，并在 Kubernetes 环境中部署特权 Pod。 本 skill 提供一键检测脚本，覆盖 7 个检测维度： | # | 检测项 | 说明 | |---|--------|------| | 1 | 版本检测 | 检查 pip/pip3/uv 中是否安装了受影响版本 | | 2 | .pth 文件扫描 | 搜索 site-packages 和缓存目录中的恶意 `litellm_init.pth` | | 3 | 后门持久化 | 检查 `~/.config/sysmon/`、`sysmon.service`、`/tmp/.pg_state` 等已知后门路径 | | 4 | 网络连接 | 检查是否有到 `litellm.cloud` / `checkmarx.zone` 的活跃连接 | | 5 | DNS 解析 | 确认恶意域名的 DNS 可达性 | | 6 | Kubernetes | 检查 kube-system 中的可疑 Pod 和特权容器 | | 7 | 依赖链 | 检查哪些包间接依赖了 litellm | ## When to Use 当用户的请求涉及以下场景时触发此技能： - 检测 LiteLLM 供应链攻击："检查一下有没有中招" - 安全扫描："扫描一下 litellm 是否被篡改" - 事件响应："litellm 后门检测" - 关键词触发："litellm attack"、"litellm 1.82.7"、"litellm 1.82.8"、"TeamPCP"、"supply chain"、"供应链攻击" ## How to Use ### 运行检测脚本 ```bash bash {{SKILL_DIR}}/scripts/detect.sh ``` 脚本无需任何参数，无需 root 权限，自动检测当前环境。 ### 输出说明 脚本使用彩色输出标识检测结果： - 🟢 `[+]` 绿色 — 该项安全 - 🔴 `[!]` 红色 — 发现入侵指标（IoC） - 🟡 `[*]` 黄色 — 信息提示 ### 输出示例（安全环境） ``` ============================================ LiteLLM Supply Chain Attack Detector Target: litellm 1.82.7 / 1.82.8 (TeamPCP) ============================================ [*] Checking installed litellm version... [+] litellm not installed via pip [*] Searching for litellm_init.pth in Python site-packages... [+] No litellm_init.pth found [*] Checking for persistence artifacts... [+] No persistence artifacts found [*] Checking for suspicious network connections... [+] No suspicious connections to known C2 domains [*] Checking DNS resolution... [*] Checking Kubernetes environment... [*] kubectl not found, skipping Kubernetes checks [*] Checking if litellm is a transitive dependency... ============================================ CLEAN — No indicators of compromise found. ============================================ ``` ### 输出示例（受感染环境） ``` ============================================ ALERT — Indicators of compromise detected! Recommended actions: 1. Uninstall litellm and delete litellm_init.pth manually 2. Remove backdoor: ~/.config/sysmon/ and sysmon.service 3. Purge caches: pip cache purge / rm -rf ~/.cache/uv 4. ROTATE ALL CREDENTIALS: - SSH keys - AWS / GCP / Azure credentials - Kubernetes configs and service account tokens - All API keys in .env files - Database passwords - Git credentials - CI/CD secrets 5. Audit cloud IAM logs for unauthorized access 6. If in K8s: delete node-setup-* pods, audit secrets ============================================ ``` ### 退出码 - `0` — 未发现入侵指标 - `1` — 发现入侵指标，需要立即处理 ## Edge Cases - **无 pip/pip3**：自动跳过版本检测，继续其他检查项 - **无 python3**：`.pth` 文件搜索会使用备用路径（`~/.cache/pip`、`~/.cache/uv` 等） - **无 kubectl**：自动跳过 Kubernetes 检查 - **无 lsof/ss**：跳过网络连接检测 - **虚拟环境**：自动检测 `$VIRTUAL_ENV` 路径 - **macOS / Linux 均支持**：脚本兼容两个平台 - **只读操作**：整个脚本不修改任何文件、不安装任何东西、不向外发送任何数据

path: scripts/detect.sh
content: #!/bin/bash
# LiteLLM Supply Chain Attack Detector
# Checks for compromised litellm versions (1.82.7 / 1.82.8) and related IoCs
# Reference: https://github.com/BerriAI/litellm/issues/24512
# Date: 2026-03-24

set -u

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

FOUND=0

warn()  { echo -e "${RED}[!] $1${NC}"; FOUND=1; }
ok()    { echo -e "${GREEN}[+] $1${NC}"; }
info()  { echo -e "${YELLOW}[*] $1${NC}"; }

echo "============================================"
echo " LiteLLM Supply Chain Attack Detector"
echo " Target: litellm 1.82.7 / 1.82.8 (TeamPCP)"
echo "============================================"
echo ""

# --- 1. Check installed litellm version ---
info "Checking installed litellm version..."
if command -v pip &>/dev/null; then
  VER=$(pip show litellm 2>/dev/null | grep "^Version:" | awk '{print $2}')
  if [ -z "$VER" ]; then
    ok "litellm not installed via pip"
  elif [[ "$VER" == "1.82.7" || "$VER" == "1.82.8" ]]; then
    warn "COMPROMISED version detected: litellm $VER"
  else
    ok "litellm version $VER (not affected)"
  fi
else
  info "pip not found, skipping pip check"
fi

if command -v pip3 &>/dev/null && [ "$(which pip3)" != "$(which pip 2>/dev/null)" ]; then
  VER3=$(pip3 show litellm 2>/dev/null | grep "^Version:" | awk '{print $2}')
  if [[ "$VER3" == "1.82.7" || "$VER3" == "1.82.8" ]]; then
    warn "COMPROMISED version detected via pip3: litellm $VER3"
  fi
fi

if command -v uv &>/dev/null; then
  UV_HIT=$(find ~/.cache/uv -name "litellm_init.pth" 2>/dev/null)
  if [ -n "$UV_HIT" ]; then
    warn "Malicious .pth found in uv cache: $UV_HIT"
  else
    ok "uv cache clean"
  fi
fi

# --- 2. Search for litellm_init.pth ---
info "Searching for litellm_init.pth in Python site-packages..."

# Ask Python for all site-packages paths instead of scanning the entire filesystem
SITE_DIRS=$(python3 -c "import site; print('\n'.join(site.getsitepackages() + [site.getusersitepackages()]))" 2>/dev/null || true)

# Also check common locations: conda, virtualenvs, uv, pip cache
EXTRA_DIRS="$HOME/.cache/pip $HOME/.cache/uv $HOME/anaconda3 $HOME/miniconda3 $HOME/.local/lib ${VIRTUAL_ENV:-}"
SEARCH_DIRS=$(echo -e "$SITE_DIRS\n$EXTRA_DIRS" | sort -u | while read -r d; do [ -d "$d" ] && echo "$d"; done)

PTH_FILES=""
if [ -n "$SEARCH_DIRS" ]; then
  PTH_FILES=$(echo "$SEARCH_DIRS" | xargs -I{} find {} -name "litellm_init.pth" -maxdepth 5 2>/dev/null || true)
fi
if [ -n "$PTH_FILES" ]; then
  warn "Malicious .pth file found:"
  echo "$PTH_FILES" | while read -r f; do echo "       $f"; done
else
  ok "No litellm_init.pth found"
fi

# --- 3. Check for persistence backdoor ---
info "Checking for persistence artifacts..."

BACKDOOR_PATHS=(
  "$HOME/.config/sysmon/sysmon.py"
  "$HOME/.config/systemd/user/sysmon.service"
  "/tmp/.pg_state"
  "/tmp/pglog"
)

BACKDOOR_HIT=0
for f in "${BACKDOOR_PATHS[@]}"; do
  if [ -e "$f" ]; then
    warn "Backdoor artifact found: $f"
    BACKDOOR_HIT=1
  fi
done
[ $BACKDOOR_HIT -eq 0 ] && ok "No persistence artifacts found"

# Check if sysmon service is running
if command -v systemctl &>/dev/null; then
  if systemctl --user is-active sysmon.service &>/dev/null; then
    warn "sysmon.service is ACTIVE — backdoor is running!"
  fi
fi

# --- 4. Check network connections ---
info "Checking for suspicious network connections..."

MALICIOUS_DOMAINS="litellm\.cloud|checkmarx\.zone"
NET_HIT=""

if command -v lsof &>/dev/null; then
  NET_HIT=$(lsof -i -n 2>/dev/null | grep -E "$MALICIOUS_DOMAINS" || true)
elif command -v ss &>/dev/null; then
  NET_HIT=$(ss -tnp 2>/dev/null | grep -E "$MALICIOUS_DOMAINS" || true)
fi

if [ -n "$NET_HIT" ]; then
  warn "Suspicious connection detected:"
  echo "$NET_HIT"
else
  ok "No suspicious connections to known C2 domains"
fi

# --- 5. Check DNS cache / resolver logs ---
info "Checking DNS resolution..."
for domain in models.litellm.cloud checkmarx.zone; do
  if host "$domain" &>/dev/null 2>&1; then
    info "Domain $domain resolves (this is expected — just confirming it exists)"
  fi
done

# --- 6. Check Kubernetes ---
info "Checking Kubernetes environment..."
if command -v kubectl &>/dev/null; then
  K8S_PODS=$(kubectl get pods -n kube-system --no-headers 2>/dev/null | grep "node-setup-" || true)
  if [ -n "$K8S_PODS" ]; then
    warn "Suspicious pods in kube-system namespace:"
    echo "$K8S_PODS"
  else
    ok "No suspicious pods found in kube-system"
  fi

  # Check for privileged pods
  PRIV_PODS=$(kubectl get pods -n kube-system -o json 2>/dev/null | \
    python3 -c "
import sys, json
data = json.load(sys.stdin)
for pod in data.get('items', []):
  for c in pod['spec'].get('containers', []):
    sc = c.get('securityContext', {})
    if sc.get('privileged'):
      print(pod['metadata']['name'])
" 2>/dev/null || true)
  if [ -n "$PRIV_PODS" ]; then
    info "Privileged pods found (review manually): $PRIV_PODS"
  fi
else
  info "kubectl not found, skipping Kubernetes checks"
fi

# --- 7. Check transitive dependencies ---
info "Checking if litellm is a transitive dependency..."
if command -v pip &>/dev/null; then
  DEPENDENTS=$(pip show litellm 2>/dev/null | grep "^Required-by:" | cut -d: -f2 | xargs)
  if [ -n "$DEPENDENTS" ]; then
    info "These packages depend on litellm: $DEPENDENTS"
  fi
fi

# --- Summary ---
echo ""
echo "============================================"
if [ $FOUND -eq 0 ]; then
  echo -e "${GREEN} CLEAN — No indicators of compromise found.${NC}"
else
  echo -e "${RED} ALERT — Indicators of compromise detected!${NC}"
  echo ""
  echo " Recommended actions:"
  echo "   1. Uninstall litellm and delete litellm_init.pth manually"
  echo "   2. Remove backdoor: ~/.config/sysmon/ and sysmon.service"
  echo "   3. Purge caches: pip cache purge / rm -rf ~/.cache/uv"
  echo "   4. ROTATE ALL CREDENTIALS:"
  echo "      - SSH keys"
  echo "      - AWS / GCP / Azure credentials"
  echo "      - Kubernetes configs and service account tokens"
  echo "      - All API keys in .env files"
  echo "      - Database passwords"
  echo "      - Git credentials"
  echo "      - CI/CD secrets"
  echo "   5. Audit cloud IAM logs for unauthorized access"
  echo "   6. If in K8s: delete node-setup-* pods, audit secrets"
fi
echo "============================================"

exit $FOUND


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: malicious | SkillSpector: suspicious (MEDIUM)