Skip to content

Instantly share code, notes, and snippets.

@christopherwoodall
Created March 24, 2026 15:24
Show Gist options
  • Select an option

  • Save christopherwoodall/db1275ca150181bf91a51ce6cae53132 to your computer and use it in GitHub Desktop.

Select an option

Save christopherwoodall/db1275ca150181bf91a51ce6cae53132 to your computer and use it in GitHub Desktop.
LiteLLM docker checker
#!/bin/bash
set -euo pipefail
REPO="litellm/litellm"
TAG="latest"
BASE_DIR="$(pwd)/litellm_inspect"
LAYERS_DIR="${BASE_DIR}/layers"
ROOTFS="${BASE_DIR}/rootfs"
EXTRACT_TMP="${BASE_DIR}/_extract_tmp"
REPORT="${BASE_DIR}/report.txt"
mkdir -p "$LAYERS_DIR" "$ROOTFS" "$EXTRACT_TMP"
: > "$REPORT"
echo "[+] Working directory: $BASE_DIR"
########################################
# 1. AUTH
########################################
echo "[+] Fetching auth token..."
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${REPO}:pull" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")
########################################
# 2. FETCH MANIFEST
########################################
echo "[+] Fetching manifest..."
RAW_MANIFEST=$(curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.docker.distribution.manifest.v2+json" \
"https://registry-1.docker.io/v2/${REPO}/manifests/${TAG}")
MEDIA_TYPE=$(echo "$RAW_MANIFEST" | python3 -c "import sys,json; print(json.load(sys.stdin).get('mediaType','unknown'))")
echo "[+] Manifest type: $MEDIA_TYPE"
########################################
# 3. RESOLVE ARCH (linux/amd64)
########################################
DIGEST=$(echo "$RAW_MANIFEST" | python3 -c "
import sys,json
m=json.load(sys.stdin)
if 'manifests' in m:
for entry in m['manifests']:
p=entry.get('platform',{})
if p.get('os')=='linux' and p.get('architecture')=='amd64':
print(entry['digest'])
break
elif 'layers' in m:
print('DIRECT')
")
if [ "$DIGEST" != "DIRECT" ]; then
echo "[+] Resolving platform digest: $DIGEST"
IMAGE_MANIFEST=$(curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
"https://registry-1.docker.io/v2/${REPO}/manifests/${DIGEST}")
else
IMAGE_MANIFEST="$RAW_MANIFEST"
fi
########################################
# 4. GET CONFIG (ENTRYPOINT / CMD)
########################################
CONFIG_DIGEST=$(echo "$IMAGE_MANIFEST" | python3 -c "import sys,json; print(json.load(sys.stdin)['config']['digest'])")
echo "[+] Fetching config blob..."
CONFIG_FILE="${BASE_DIR}/config_blob"
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
"https://registry-1.docker.io/v2/${REPO}/blobs/${CONFIG_DIGEST}" \
-o "${CONFIG_FILE}"
# Detect if gzip
if file "${CONFIG_FILE}" | grep -q "gzip"; then
echo "[+] Decompressing config blob..."
gunzip -c "${CONFIG_FILE}" > "${CONFIG_FILE}.json"
else
cp "${CONFIG_FILE}" "${CONFIG_FILE}.json"
fi
# Validate JSON safely
echo "=== IMAGE CONFIG ===" >> "$REPORT"
if python3 -m json.tool "${CONFIG_FILE}.json" >/dev/null 2>&1; then
python3 -m json.tool "${CONFIG_FILE}.json" >> "$REPORT"
else
echo "[!] Failed to parse config JSON" >> "$REPORT"
head -c 1000 "${CONFIG_FILE}.json" >> "$REPORT"
fi
########################################
# 5. DOWNLOAD LAYERS
########################################
echo "[+] Downloading layers..."
echo "$IMAGE_MANIFEST" | python3 -c "
import sys,json
for l in json.load(sys.stdin)['layers']:
print(l['digest'])
" | while read DIGEST; do
SAFE=$(echo "$DIGEST" | tr ':' '_')
OUT_FILE="${LAYERS_DIR}/${SAFE}.tar.gz"
if [ -f "$OUT_FILE" ]; then
echo " [=] Already downloaded: $DIGEST"
continue
fi
echo " [+] $DIGEST"
curl -s -L \
-H "Authorization: Bearer ${TOKEN}" \
"https://registry-1.docker.io/v2/${REPO}/blobs/${DIGEST}" \
-o "$OUT_FILE"
done
########################################
# 6. RECONSTRUCT ROOTFS (WITH WHITEOUTS)
########################################
echo "[+] Reconstructing root filesystem..."
rm -rf "$ROOTFS"
mkdir -p "$ROOTFS"
for LAYER in $(ls "$LAYERS_DIR"/*.tar.gz | sort); do
echo " [+] Applying $(basename "$LAYER")"
rm -rf "$EXTRACT_TMP"
mkdir -p "$EXTRACT_TMP"
tar -xzf "$LAYER" -C "$EXTRACT_TMP"
# Handle whiteouts
find "$EXTRACT_TMP" -name ".wh.*" | while read WH; do
TARGET=$(basename "$WH" | sed 's/^\.wh\.//')
DIR=$(dirname "$WH")
REL="${DIR#"$EXTRACT_TMP/"}"
rm -rf "$ROOTFS/$REL/$TARGET"
done
cp -a "$EXTRACT_TMP"/. "$ROOTFS"/
done
########################################
# 7. FIND .PTH FILES
########################################
echo "[+] Scanning for .pth files..."
echo "=== PTH FILES ===" >> "$REPORT"
find "$ROOTFS" -type f -name "*.pth" | while read PTH; do
echo "--- $PTH ---" >> "$REPORT"
head -c 2000 "$PTH" >> "$REPORT"
echo "" >> "$REPORT"
done
########################################
# 8. SUSPICIOUS PTH DETECTION
########################################
echo "[+] Checking for suspicious .pth..."
echo "=== SUSPICIOUS PTH ===" >> "$REPORT"
find "$ROOTFS" -name "*.pth" | while read PTH; do
if grep -E "import|exec|os\.|subprocess" "$PTH" >/dev/null; then
echo "[!] $PTH" >> "$REPORT"
cat "$PTH" >> "$REPORT"
echo "" >> "$REPORT"
fi
done
########################################
# 9. SCAN NESTED ARCHIVES
########################################
echo "[+] Scanning nested archives..."
echo "=== NESTED ARCHIVE PTH ===" >> "$REPORT"
find "$ROOTFS" -type f \( -name "*.whl" -o -name "*.zip" \) | while read ARCHIVE; do
python3 - <<EOF >> "$REPORT"
import zipfile
try:
with zipfile.ZipFile("$ARCHIVE") as z:
for n in z.namelist():
if n.endswith(".pth"):
print("FOUND:", "$ARCHIVE", "->", n)
print(z.read(n)[:500])
except:
pass
EOF
done
########################################
# 10. PYTHON STARTUP HOOKS
########################################
echo "[+] Checking Python startup hooks..."
echo "=== SITECUSTOMIZE ===" >> "$REPORT"
find "$ROOTFS" -name "sitecustomize.py" >> "$REPORT" || true
echo "=== USERCUSTOMIZE ===" >> "$REPORT"
find "$ROOTFS" -name "usercustomize.py" >> "$REPORT" || true
########################################
# 11. LITELLM PACKAGE EXTRACTION
########################################
echo "[+] Locating LiteLLM package..."
echo "=== LITELLM FILES ===" >> "$REPORT"
LITELLM_PATH=$(find "$ROOTFS" -type d -name "litellm" | head -n 1 || true)
if [ -n "$LITELLM_PATH" ]; then
echo "Found: $LITELLM_PATH" | tee -a "$REPORT"
echo "--- __init__.py ---" >> "$REPORT"
head -n 200 "$LITELLM_PATH/__init__.py" >> "$REPORT" 2>/dev/null || true
echo "--- suspicious patterns ---" >> "$REPORT"
grep -R "os.system\|subprocess\|exec(" "$LITELLM_PATH" >> "$REPORT" || true
else
echo "LiteLLM not found" >> "$REPORT"
fi
########################################
# DONE
########################################
echo ""
echo "[✓] Done."
echo "[+] Output directory: $BASE_DIR"
echo "[+] Report: $REPORT"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment