关于 performing-paste-site-monitoring-for-credentials
用于监控粘贴站点和代码仓库中的泄露凭据与敏感数据的安全技能,涵盖关键词和模式匹配、告警生成及事件响应流程。
主要功能
- 01监控 Pastebin 和 GitHub Gists
- 02匹配凭据模式与组织关键词
- 03生成分级告警
- 04将发现接入事件响应
适用场景
- 01发现组织凭据泄露
- 02查找泄露的 API 密钥和私钥
- 03调查公开代码中的密钥暴露
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill performing-paste-site-monitoring-for-credentials安装后在 Claude Code 中输入/performing-paste-site-monitoring-for-credentials确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.py详细介绍
对凭据执行粘贴站点监控
概述
粘贴站点(Pastebin、GitHub Gists、Ghostbin、Dpaste、Hastebin)经常被用作泄露凭据、数据库转储、API 密钥和敏感数据的暂存区,随后再在暗网论坛和 Telegram 频道上更广泛地传播。监控这些站点可实现早期泄露检测,使组织能够在被盗数据被武器化之前做出响应。本技能涵盖使用 Pastebin Scraping API 构建自动化粘贴站点监控器、基于关键字的告警、凭据模式匹配,以及与事件响应工作流的集成。
何时使用
- 当开展涉及对凭据执行粘贴站点监控的安全评估时
- 当针对相关安全事件遵循事件响应流程时
- 当执行计划性安全测试或审计活动时
- 当通过动手测试验证安全控制措施时
前提条件
- Python 3.9+ 以及
requests、beautifulsoup4、regex、pymisp库 - 具有 Scraping API 访问权限的 Pastebin PRO 账户(程序化访问每月 49.95 美元)
- 用于 Gist 监控的 GitHub API 令牌
- 特定于你组织的关键字列表(域名、项目名称、内部术语)
- 用于粘贴内容存储和搜索的 Elasticsearch 或数据库
关键概念
粘贴站点威胁态势
每年有超过 300,000 个用户凭据被发布到 Pastebin 上,平均每次泄露涉及 1,000 个用户名/密码对。粘贴站点有三个主要威胁情报用途:早期泄露检测(凭据在进入暗网之前先出现在粘贴站点上)、威胁行为者画像(行为者利用粘贴站点进行 C2 配置、数据暂存、工具共享)以及恶意软件发现(编码载荷、配置文件、C2 地址)。
监控方法
主动监控会定期查询粘贴站点 API 或抓取端点。Pastebin Scraping API 提供对新的公开粘贴内容的实时访问。对于 GitHub,搜索 API 允许监控 Gist 和仓库提交中暴露的机密。被动监控使用 IntelX、Dehashed 或 Have I Been Pwned 等服务,这些服务会聚合粘贴站点数据。
凭据模式检测
有效的监控使用正则表达式模式来匹配 email:password 组合、API 密钥(AWS、Azure、GCP、Stripe、Twilio)、数据库连接字符串、私钥(SSH、PGP)、JWT 令牌以及内部主机名/URL。组织特定的关键字(域名、产品名称、员工姓名)可减少误报。
工作流
步骤 1:Pastebin Scraping API 监控器
import requests
import re
import json
import time
from datetime import datetime
class PastebinMonitor:
SCRAPING_URL = "https://scrape.pastebin.com/api_scraping.php"
RAW_URL = "https://scrape.pastebin.com/api_scrape_item.php"
def __init__(self, keywords, output_dir="paste_alerts"):
self.keywords = [k.lower() for k in keywords]
self.output_dir = output_dir
self.seen_keys = set()
self.credential_patterns = {
"email_password": re.compile(
r'[\w.+-]+@[\w-]+\.[\w.]+[\s:;|,]+[\S]{6,}', re.IGNORECASE),
"aws_key": re.compile(
r'AKIA[0-9A-Z]{16}'),
"aws_secret": re.compile(
r'[0-9a-zA-Z/+=]{40}'),
"github_token": re.compile(
r'ghp_[0-9a-zA-Z]{36}'),
"slack_token": re.compile(
r'xox[baprs]-[0-9a-zA-Z-]+'),
"private_key": re.compile(
r'-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----'),
"jwt_token": re.compile(
r'eyJ[A-Za-z0-9-_]+\.eyJ[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+'),
"connection_string": re.compile(
r'(?:mongodb|postgres|mysql|redis)://[^\s]+'),
"api_key_generic": re.compile(
r'(?:api[_-]?key|apikey|access[_-]?token)[\s]*[=:]\s*["\']?[\w-]{20,}',
re.IGNORECASE),
}
def fetch_recent_pastes(self, limit=100):
"""Fetch recent public pastes from Pastebin Scraping API."""
params = {"limit": limit}
try:
resp = requests.get(self.SCRAPING_URL, params=params, timeout=30)
if resp.status_code == 200:
pastes = resp.json()
print(f"[+] Fetched {len(pastes)} recent pastes")
return pastes
else:
print(f"[-] API error: {resp.status_code}")
return []
except Exception as e:
print(f"[-] Fetch error: {e}")
return []
def get_paste_content(self, paste_key):
"""Get the raw content of a paste."""
params = {"i": paste_key}
try:
resp = requests.get(self.RAW_URL, params=params, timeout=15)
if resp.status_code == 200:
return resp.text
return ""
except Exception:
return ""
def analyze_paste(self, content, paste_metadata):
"""Analyze paste content for credentials and keywords."""
findings = {
"keyword_matches": [],
"credential_matches": {},
"severity": "low",
}
content_lower = content.lower()
# Check keywords
for keyword in self.keywords:
if keyword in content_lower:
count = content_lower.count(keyword)
findings["keyword_matches"].append({
"keyword": keyword,
"count": count,
})
# Check credential patterns
for pattern_name, pattern in self.credential_patterns.items():
matches = pattern.findall(content)
if matches:
findings["credential_matches"][pattern_name] = {
"count": len(matches),
"samples": matches[:3],
}
# Calculate severity
cred_count = sum(
m["count"] for m in findings["credential_matches"].values()
)
if findings["keyword_matches"] and cred_count > 0:
findings["severity"] = "critical"
elif findings["keyword_matches"]:
findings["severity"] = "high"
elif cred_count > 10:
findings["severity"] = "high"
elif cred_count > 0:
findings["severity"] = "medium"
return findings
def monitor_loop(self, interval=120, iterations=None):
"""Continuous monitoring loop."""
count = 0
while iterations is None or count < iterations:
pastes = self.fetch_recent_pastes()
alerts = []
for paste in pastes:
paste_key = paste.get("key", "")
if paste_key in self.seen_keys:
continue
self.seen_keys.add(paste_key)
content = self.get_paste_content(paste_key)
if not content:
continue
findings = self.analyze_paste(content, paste)
if findings["severity"] != "low":
alert = {
"paste_key": paste_key,
"title": paste.get("title", "Untitled"),
"user": paste.get("user", "Anonymous"),
"date": paste.get("date", ""),
"size": paste.get("size", 0),
"url": f"https://pastebin.com/{paste_key}",
"findings": findings,
"detected_at": datetime.now().isoformat(),
}
alerts.append(alert)
print(f" [ALERT-{findings['severity'].upper()}] "
f"{paste_key}: {findings['keyword_matches']}")
if alerts:
self._save_alerts(alerts)
count += 1
if iterations is None or count < iterations:
time.sleep(interval)
return alerts
def _save_alerts(self, alerts):
"""Save alerts to JSON file."""
filename = f"{self.output_dir}/alerts_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
import os
os.makedirs(self.output_dir, exist_ok=True)
with open(filename, "w") as f:
json.dump(alerts, f, indent=2)
print(f"[+] Saved {len(alerts)} alerts to {filename}")
monitor = PastebinMonitor(
keywords=["mycompany.com", "internal-project", "employee-name"],
)
alerts = monitor.monitor_loop(interval=120, iterations=5)
步骤 2:GitHub Gist 和代码搜索监控
class GitHubSecretMonitor:
def __init__(self, github_token, org_keywords):
self.token = github_token
self.keywords = org_keywords
self.headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json",
}
def search_code(self, query, per_page=30):
"""Search GitHub code for leaked secrets."""
url = "https://api.github.com/search/code"
params = {"q": query, "per_page": per_page}
resp = requests.get(url, headers=self.headers, params=params)
if resp.status_code == 200:
results = resp.json().get("items", [])
print(f"[+] GitHub code search: {len(results)} results for '{query}'")
return results
return []
def search_gists(self, keyword):
"""Search public Gists for sensitive data."""
url = "https://api.github.com/gists/public"
params = {"per_page": 100}
resp = requests.get(url, headers=self.headers, params=params)
matches = []
if resp.status_code == 200:
gists = resp.json()
for gist in gists:
description = (gist.get("description") or "").lower()
files = gist.get("files", {})
for filename, file_info in files.items():
if keyword.lower() in description or keyword.lower() in filename.lower():
matches.append({
"gist_id": gist["id"],
"description": gist.get("description", ""),
"filename": filename,
"url": gist["html_url"],
"created_at": gist["created_at"],
})
return matches
def monitor_org_secrets(self, org_domain):
"""Monitor for organization secrets leaked on GitHub."""
queries = [
f'"{org_domain}" password',
f'"{org_domain}" api_key',
f'"{org_domain}" secret',
f'"{org_domain}" token',
f'"{org_domain}" credentials',
]
all_findings = []
for query in queries:
results = self.search_code(query)
for result in results:
all_findings.append({
"query": query,
"repo": result.get("repository", {}).get("full_name", ""),
"path": result.get("path", ""),
"url": result.get("html_url", ""),
"score": result.get("score", 0),
})
time.sleep(10) # GitHub rate limiting
return all_findings
gh_monitor = GitHubSecretMonitor("YOUR_GITHUB_TOKEN", ["mycompany.com"])
findings = gh_monitor.monitor_org_secrets("mycompany.com")
步骤 3:告警和事件响应集成
def generate_credential_leak_alert(alert_data):
"""Generate incident alert for credential leak detection."""
alert = {
"title": f"Credential Leak Detected - {alert_data.get('severity', 'unknown').upper()}",
"source": alert_data.get("url", ""),
"detected_at": alert_data.get("detected_at", ""),
"severity": alert_data.get("severity", "medium"),
"summary": f"Paste containing organization keywords and credentials found",
"keyword_matches": alert_data.get("findings", {}).get("keyword_matches", []),
"credential_types": list(alert_data.get("findings", {}).get("credential_matches", {}).keys()),
"recommended_actions": [
"Verify if leaked credentials are valid",
"Force password reset for affected accounts",
"Rotate exposed API keys and tokens",
"Check access logs for unauthorized usage",
"Report paste for takedown",
"Update monitoring keywords if new patterns found",
],
}
return alert
验证标准
- 在限流条件下成功查询 Pastebin Scraping API
- 检测到凭据模式(email:password、API 密钥、私钥)
- 组织特定的关键字在上下文中匹配成功
- GitHub 代码搜索识别出暴露的机密
- 生成带有严重性分类的告警
- 与事件响应工作流集成