Files
hack/tools/scripts/llm-key-hunter/gist.sh
T

94 lines
3.8 KiB
Bash
Executable File

#!/bin/bash
# ═══════════════════════════════════════════════════════════════
# gist.sh — GitHub Gist 扫描模块
# 公开 Gist 是 API key 泄露重灾区,尤其是 Jupyter notebook dump
# ═══════════════════════════════════════════════════════════════
set -euo pipefail
TOKEN=""
REPORT_DIR="./results"
LIMIT=1000
CYAN='\033[0;36m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${CYAN}[*]${NC} $1"; }
log_found() { echo -e "${GREEN}[+]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[!]${NC} $1"; }
while [[ $# -gt 0 ]]; do
case "$1" in
--token) TOKEN="$2"; shift 2 ;;
--report) REPORT_DIR="$2"; shift 2 ;;
--limit) LIMIT="$2"; shift 2 ;;
*) shift ;;
esac
done
mkdir -p "$REPORT_DIR"
RESULTS_FILE="${REPORT_DIR}/gist_keys.txt"
> "$RESULTS_FILE"
# 正则模式
REGEX='(sk-[a-zA-Z0-9]{20,}|sk-proj-[a-zA-Z0-9_-]{20,}|sk-ant-[a-zA-Z0-9-]{20,}|AIza[0-9A-Za-z\-_]{35}|hf_[a-zA-Z0-9]{34}|gsk_[a-zA-Z0-9]{52}|r8_[a-zA-Z0-9]{37}|sk-or-[a-zA-Z0-9-]{20,}|pplx-[a-zA-Z0-9]{48,})'
# ── 扫描公开 gist ────────────────────────────────────────
log_info "列出公开 Gist (limit: $LIMIT)..."
# 用 gh 列出 gist
GIST_IDS=$(gh gist list --public --limit "$LIMIT" 2>/dev/null | awk '{print $1}')
if [[ -z "$GIST_IDS" ]]; then
log_warn "未找到公开 gist,尝试用 API 搜索..."
# 用 GitHub search API 搜 gist 中的 key
for query in "sk-proj-" "sk-ant-" "OPENAI_API_KEY" "ANTHROPIC_API_KEY" "GROQ_API_KEY" "HUGGINGFACE"; do
log_info "搜索 gist: $query"
gh api "search/code?q=${query}+extension:ipynb" --jq '.items[].html_url' 2>/dev/null | while read -r url; do
raw_url=$(echo "$url" | sed 's|github.com|raw.githubusercontent.com|;s|/blob/||')
content=$(curl -sL --max-time 10 "$raw_url" 2>/dev/null) || continue
[[ -z "$content" ]] && continue
echo "$content" | grep -oE "$REGEX" 2>/dev/null | while read -r key; do
echo "GistMatch|${key}|${url}|Gist leak" >> "$RESULTS_FILE"
log_found "Gist key: $key"
done
done
done
else
log_info "扫描 $(echo "$GIST_IDS" | wc -l | tr -d ' ') 个 gist..."
while read -r gist_id; do
[[ -z "$gist_id" ]] && continue
content=$(gh gist view "$gist_id" 2>/dev/null) || continue
[[ -z "$content" ]] && continue
echo "$content" | grep -oE "$REGEX" 2>/dev/null | while read -r key; do
echo "GistMatch|${key}|gist:${gist_id}|Gist leak" >> "$RESULTS_FILE"
log_found "Gist key: $key (gist: $gist_id)"
done
done <<< "$GIST_IDS"
fi
# ── 搜索 GitHub Gist API ─────────────────────────────────
log_info "通过 GitHub API 搜索 gist 中的 key 模式..."
for pattern in "sk-proj-" "sk-ant-" "AIza" "hf_" "gsk_" "r8_"; do
gh api "/gists/public" --paginate --jq '.[].id' 2>/dev/null | head -200 | while read -r gid; do
[[ -z "$gid" ]] && continue
content=$(gh gist view "$gid" 2>/dev/null) || continue
echo "$content" | grep -oE "$REGEX" 2>/dev/null | while read -r key; do
grep -q "${key}" "$RESULTS_FILE" 2>/dev/null || {
echo "GistAPI|${key}|gist:${gid}|Gist API leak" >> "$RESULTS_FILE"
log_found "Gist API key: $key"
}
done
done
done
count=$(wc -l < "$RESULTS_FILE" | tr -d ' ')
log_found "Gist 扫描完成: $count 个 key"
log_info "结果保存至: $RESULTS_FILE"