基于 pyzbar 与邮件安全网关的 QR 码钓鱼(Quishing)检测 API 实战指南
【免费下载链接】Anthropic-Cybersecurity-Skills817 structured cybersecurity skills for AI agents · Mapped to 6 frameworks: MITRE ATT&CK, NIST CSF 2.0, MITRE ATLAS, D3FEND, NIST AI RMF & MITRE F3 (Fight Fraud) · agentskills.io standard · Works with Claude Code, GitHub Copilot, Codex CLI, Cursor, Gemini CLI & 20+ platforms · 29 security domains · Apache 2.0项目地址: https://gitcode.com/GitHub_Trending/an/Anthropic-Cybersecurity-Skills
本指南以 api-reference.md 为核心,系统讲解 QR 码钓鱼(quishing)检测所依赖的关键 API:用 pyzbar 解码邮件图片中的二维码、用 Python email 模块解析 EML、对解码 URL 做钓鱼特征评分,并打通 Microsoft Defender for Office 365 与 VirusTotal 的威胁信誉核验。读完本文,你将能够在 Anthropic-Cybersecurity-Skills 仓库的 detecting-qr-code-phishing-with-email-security 技能框架下,独立构建"EML 解析 → QR 解码 → URL 评分 → 外部信誉核验"的完整检测管线。
为什么 QR 码是邮件安全的盲区
Quishing(QR code phishing)把恶意 URL 编码进图片里的二维码,传统邮件网关只扫描正文中的纯文本链接,无法读取图片内嵌内容;而当用户用手机扫码时,流量又发生在缺乏企业防护的个人设备上。该技能在 SKILL.md 中给出了量化背景:2025 年 8 月至 11 月间 quishing 事件从 46,000 起增长到 250,000 起,其中 89.3% 指向凭证窃取;攻击者还演化出分割 QR(split QR)、嵌套 QR(nested QR)以及用 ASCII 文本绘制的 QR 码(2026 年 1 月约 12% 的攻击采用该手法)来绕过图片分析。
从防御侧看,检测链条分为四段,每段都有明确的技术落点:
- 图片发现:从 EML 中提取所有
image/*附件与内联图(Pythonemail模块); - QR 解码:用 pyzbar 把图片中的二维码还原成文本 URL;
- URL 分析:对解码结果做 TLD、域名形态、协议、路径关键词的风险评分;
- 信誉核验:对接 Microsoft Defender for Office 365 / VirusTotal 等外部服务二次确认。
以下按这四段展开 API 层面的实战细节。
pyzbar:QR 码与条形码解码 API
安装与环境依赖
pyzbar 是 zbar 解码库的 Python 绑定,配合 Pillow 读取图片即可使用:
pip install pyzbar Pillow # On Linux: apt-get install libzbar0注意 Linux 下必须安装libzbar0系统库,否则 import 阶段会失败。仓库脚本对此做了优雅降级:在 agent.py 与 process.py 中均以try/except ImportError包裹导入,缺失时置HAS_QR = False/HAS_PYZBAR = False,随后在解码入口(如 process.py 的scan_image_for_qr)打印安装提示并返回空结果,保证检测流程不会因依赖缺失而崩溃。
核心解码函数
from pyzbar.pyzbar import decode from PIL import Image results = decode(Image.open("qr.png")) for r in results: print(r.type) # "QRCODE" print(r.data) # b"https://..." print(r.rect) # Rect(left=40, top=40, width=200, height=200)实际落地时很少直接解码磁盘文件——邮件里的图片是内存字节。仓库在 agent.py 提供了decode_qr_from_bytes:先用io.BytesIO把原始字节包装成文件对象,再交给Image.open与qr_decode,最后用errors="replace"容错解码避免非法 UTF-8 数据抛异常。
解码对象属性
| Attribute | Type | Description |
|---|---|---|
data | bytes | Decoded content(解码内容) |
type | str | Barcode type (QRCODE, EAN13, etc.) |
rect | Rect | Bounding rectangle(外接矩形) |
polygon | list | Corner points(角点坐标) |
quality | int | Decode quality score(解码质量分) |
实战中rect/polygon可用于定位二维码在邮件图片中的位置,辅助取证截图;quality可用于过滤低质量误检。注意解码出的data不一定是 URL,process.py 的处理策略是:仅当内容以http://、https://或www.开头才进入 URL 分析,否则标记为"QR code contains non-URL data"并给予低风险分 10。
Python email 模块:EML 解析与 MIME 遍历
解析 EML 文件
import email from email import policy with open("message.eml", "rb") as f: msg = email.message_from_binary_file(f, policy=policy.default) subject = msg["Subject"] sender = msg["From"]必须使用二进制模式打开并配合policy.default,才能正确保留 MIME 结构与头字段解码语义。仓库的extract_images_from_eml(agent.py)正是以此方式加载邮件,并同步提取Subject、From用于后续关键词打分。
遍历 MIME 部件
for part in msg.walk(): ctype = part.get_content_type() if ctype.startswith("image/"): payload = part.get_payload(decode=True) filename = part.get_filename()msg.walk()会递归遍历嵌套的multipart/*结构,get_payload(decode=True)返回传输编码解码后的原始字节,get_filename()取附件名(内联图通常为None)。仓库脚本对无名内联图回退为inline_image.{ext},扩展名从content_type.split("/")[1]推导(如image/png→png)。
针对 HTML 邮件中 base64 内嵌图(非附件)的场景,process.py 还实现了正则抓取Content-Type: image/...+Content-Transfer-Encoding: base64块、base64.b64decode还原字节、再送qr_decode的完整链路——这覆盖了"QR 嵌在正文而非附件"的常见变体。
URL 分析指标:解码之后的信誉初筛
可疑 TLD 列表
解码出的 URL 首先与高危后缀列表比对:.xyz、.top、.club、.work、.buzz、.tk、.ml、.ga、.cf、.gq。
仓库将列表扩展为集合常量SUSPICIOUS_TLDS(agent.py),追加了.info、.online、.site、.icu等攻击者常用廉价域名;process.py 则以正则\.tk$|\.ml$|\.ga$|\.cf$|\.gq$的形式参与 URL 特征匹配。
钓鱼 URL 特征评分表
| Pattern | Risk |
|---|---|
| IP address in domain(域名直接用 IP) | High |
| Domain > 40 chars(超长域名) | Medium |
| HTTP (no TLS)(无 HTTPS) | Medium |
| 3+ subdomains(子域过多) | Medium |
| URL shortener(短链服务) | High |
| Base64 in path(路径含 Base64) | High |
评分机制在两份脚本中都有实现,可作为参数取值的参考:
- agent.py 的
analyze_url(agent.py):命中一条指标记一次,risk_score = min(指标数 × 25, 100),即 1 条指标 = MEDIUM(25)、2 条 = HIGH(50)、3 条以上 = CRITICAL(75+)。 - process.py 的
analyze_url(process.py):按模式加权累加——可疑 URL 模式每条 +15,已知钓鱼基础设施(Firebase/Netlify/Glitch/Cloudflare Workers 免费托管滥用)每条 +25,短链服务 +20,纯 IP 域名 +30,子域 >3 +15,同形字(非 ASCII 域名字符) +25,非 HTTPS +10,最终risk_score = min(总分, 100)且 ≥30 判为is_suspicious。同时维护PHISHING_INFRA_PATTERNS(process.py)识别[a-z0-9]{20,}.web.app、*.netlify.app、*.glitch.me、*.workers.dev等被滥用托管平台。
外部信誉核验 API
初筛打分之外,生产环境还需要外部威胁情报兜底。原文档给出两类核验接口。
Microsoft Defender for Office 365 — Safe Links API
POST https://graph.microsoft.com/v1.0/security/tiIndicators Content-Type: application/json Authorization: Bearer {token} { "targetProduct": "Azure Sentinel", "threatType": "Phishing", "url": "https://suspicious-domain.xyz/login" }该调用将可疑 QR 解码 URL 作为威胁指标(tiIndicator)投递到 Azure Sentinel,使后续到达的同类邮件触发联动告警。SKILL 中将其归入"Step 2: Configure QR Code URL Analysis"——对 QR 提取 URL 应用与文本 URL 相同的扫描策略、启用实时沙箱与点击时(time-of-click)保护。
VirusTotal URL Scan API
POST https://www.virustotal.com/api/v3/urls x-apikey: {API_KEY} Content-Type: application/x-www-form-urlencoded url=https://suspicious-domain.xyz提交后轮询分析结果的响应字段:
| Field | Description |
|---|---|
data.attributes.last_analysis_stats.malicious | Engines flagging as malicious(报毒引擎数) |
data.attributes.last_analysis_stats.harmless | Engines flagging as clean(判定干净的引擎数) |
data.attributes.categories | URL categorization(URL 分类) |
端到端实现:仓库脚本如何串起整条管线
原文档给出了各 API 的独立用法,而仓库把四段链路固化成了两个可直接运行的脚本,这是理解各 API 协同关系的最佳源码证据。
agent.py —— 目录批量扫描 + JSON 报告
入口命令:
python skills/detecting-qr-code-phishing-with-email-security/scripts/agent.py <eml 文件或目录> --output report.json --verbose主流程(agent.py 的analyze_email):
extract_images_from_eml提取全部图片并记录Subject/From;- 对主题做
PHISHING_KEYWORDS(verify/account/urgent/password/invoice 等 15 个词)匹配,命中即记入phishing_indicators; decode_qr_from_bytes解码每张图片,过滤出 HTTP(S) URL 后逐个analyze_url;- 取所有 URL 风险分最大值映射风险等级:≥75 = CRITICAL、≥50 = HIGH、≥25 = MEDIUM、否则 LOW;
- 目录模式下用
os.walk递归收集全部.eml文件(agent.py),汇总报告统计qr_phishing_detected数并输出 JSON。
process.py —— 三子命令 + 邮件内容模式匹配
python skills/detecting-qr-code-phishing-with-email-security/scripts/process.py scan-image --image qr_image.png python skills/detecting-qr-code-phishing-with-email-security/scripts/process.py scan-email --eml-file message.eml python skills/detecting-qr-code-phishing-with-email-security/scripts/process.py check-url --url "https://example.com/login" # 三子命令均支持 --json 输出结构化结果除了解码与 URL 评分,scan_email_content(process.py)还在邮件正文层面做 quishing 语义检测:
QUISHING_EMAIL_PATTERNS(process.py)匹配"scan this QR code"、"scan to verify/authenticate"、"MFA setup/enrollment/reset"、"voicemail notification"、"document signing"、"security update required" 等典型话术;- 检测"图片丰富但纯文本极少"模式(去 HTML 标签后词数 <50 且含
<img或Content-Type: image/),这是 quishing 邮件的高频形态; - 综合 QR 可疑度与正文指标数给出处置建议:
BLOCK and alert SOC(critical)、QUARANTINE for manual review(high)、TAG with QR phishing warning banner(medium)、DELIVER normally(low)。
这一"话术 + 形态 + 解码"三重判定,正是 workflows.md 中"QR Code Email Detection Pipeline"的代码化实现:先标准文本扫描,再图片分析,命中后提取 URL 走信誉与沙箱,最终按 MALICIOUS / SUSPICIOUS / UNKNOWN / CLEAN 四档决策。
与技能框架的衔接:检测规则的落点
原文档的 API 能力最终要为检测规则服务。技能包中的 template.md 给出了可直接套用的规则清单,与本文 API 一一对应:
| Rule | Condition | 对应 API 环节 |
|---|---|---|
| QR in image | 内嵌图片检出二维码 | pyzbardecode+rect |
| QR in PDF | PDF 附件含二维码 | email模块取附件 + pyzbar |
| ASCII QR | 文本绘制 QR 形态 | 邮件正文正则(scan-email) |
| Image-only email | 图片多、正文少 | QUISHING_EMAIL_PATTERNS+ 词数统计 |
| MFA QR theme | QR + MFA/认证话术 | 正文关键词 + URL 评分 |
同时技能已在 SKILL.md 中声明了对 MITRE ATT&CK(T1566、T1598、T1036、T1027 等)与 MITRE F3 的映射,检测结果可按 mappings 目录下的框架映射进一步结构化归档,供 SIEM 关联与告警分级使用。
验证与上线建议
原文档的 Validation 标准可作为自测清单:受控测试中捕获 quishing 邮件、能命中分割 QR 与 ASCII QR 变体、QR 提取 URL 进入沙箱、移动端对恶意 QR 目标告警、用户上报率 >50%、QR 检测误报率 <1%。落实到本管线上,建议依次验证:构造含 QR 图片的.eml样本 →scan-email输出中qr_codes_found与overall_risk是否符合预期 → 高/中危样本的处置建议是否与 workflows.md 中 Block/Quarantine/Tag 分档一致 → 对接 Defender/VirusTotal 后的last_analysis_stats是否正确驱动最终放行决策。
需要说明的适用前提:pyzbar 解码依赖本地 zbar 库(Linux 需libzbar0);脚本仅做静态检测,不含沙箱执行能力,实时沙箱与点击时保护需依赖邮件安全网关(如 Microsoft Defender for O365、Proofpoint TAP、Barracuda Multimodal AI)的既有能力;移动端扫码防护(Palo Alto ALFA、Lookout/Zimperium 等)属于网关之外的独立层,详见 SKILL.md 的"Step 3: Deploy Mobile-Side Protection"。
【免费下载链接】Anthropic-Cybersecurity-Skills817 structured cybersecurity skills for AI agents · Mapped to 6 frameworks: MITRE ATT&CK, NIST CSF 2.0, MITRE ATLAS, D3FEND, NIST AI RMF & MITRE F3 (Fight Fraud) · agentskills.io standard · Works with Claude Code, GitHub Copilot, Codex CLI, Cursor, Gemini CLI & 20+ platforms · 29 security domains · Apache 2.0项目地址: https://gitcode.com/GitHub_Trending/an/Anthropic-Cybersecurity-Skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考