reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
151
vendor-new/rev-skills/.claude/skills/re-ai-attack/SKILL.md
Normal file
151
vendor-new/rev-skills/.claude/skills/re-ai-attack/SKILL.md
Normal file
@@ -0,0 +1,151 @@
|
||||
---
|
||||
name: re-ai-attack
|
||||
type: atomic
|
||||
description: >
|
||||
AI 模型安全评估与取证(行为层):extraction assessment(API 黑盒提取评估)、
|
||||
fingerprint verification(行为指纹与归属验证)、privacy leakage evaluation(成员推断/隐私泄露评估)、
|
||||
robustness evaluation(对抗鲁棒性评估)。
|
||||
触发词:API模型窃取、黑盒模型复制、模型指纹、成员推断、对抗样本、行为水印、模型安全评估、隐私泄露评估。
|
||||
guard: {"require_authorization": true, "forbidden": ["unauthorized_api_testing", "bypass_access_control", "model_theft_against_third_party"]}
|
||||
capabilities: [ai-model-analysis]
|
||||
---
|
||||
|
||||
# AI 模型安全评估与取证(行为层)
|
||||
|
||||
## CORE RULE:攻击面由可观测性决定,不由攻击名称决定
|
||||
|
||||
先问接口/资产给什么,再选攻击面——三者是三个世界:
|
||||
|
||||
| 可观测性 | 世界 |
|
||||
|---|---|
|
||||
| `logits available`(API 返回概率/logits) | 蒸馏(soft label)、指纹、成员推断全部可用 |
|
||||
| `labels only`(API 只返回标签) | 降级:决策边界采样、黑盒迁移、影子模型 |
|
||||
| `weights available`(拿到模型文件) | 白盒:梯度方法(FGSM/PGD)、直接比对、阈值成员推断 |
|
||||
|
||||
同一攻击名在不同可观测性下可行性与实现完全不同——先按「输入资产盘点」确认 API 输出字段/模型文件,再选路径。
|
||||
|
||||
## 任务分类器(intent → 路径)
|
||||
|
||||
用户目的识别,命中即走对应分支;未命中落入下方「何时使用」判断:
|
||||
|
||||
| 用户目的(intent) | 路径 |
|
||||
|---|---|
|
||||
| 怀疑模型被复制 / 模型被盗用 / 嫌疑副本比对 | → **fingerprint**(模型指纹/水印检测,步骤 2) |
|
||||
| 判断训练数据泄露 / 某样本是否在训练集 | → **membership**(成员推断,步骤 3) |
|
||||
| 测试 API 是否容易被复制 / 接口可提取性 | → **extraction**(模型提取,步骤 1) |
|
||||
| 测试鲁棒性 / 对抗样本效果 / 防御验证 | → **adversarial**(对抗样本评估,步骤 4) |
|
||||
|
||||
## 输入资产盘点(INPUT INVENTORY)
|
||||
|
||||
路径命中后先确认已有资产——不同资产组合决定可走路径,缺资产先向用户索要或说明局限:
|
||||
|
||||
| 资产 | 影响路径 |
|
||||
|---|---|
|
||||
| API endpoint(+ query budget) | **extraction**(步骤 1)必需——无 endpoint 无法提取 |
|
||||
| model file(本地模型/权重) | fingerprint 比对与成员推断(步骤 2/3)可用;无则只能走 API 侧 |
|
||||
| training dataset(疑似训练集样本) | **membership**(步骤 3)必需——无样本无法推断成员 |
|
||||
| suspected copy(嫌疑副本) | **fingerprint**(步骤 2)必需——无副本无从比对 |
|
||||
| baseline model(受害者/参考模型) | fingerprint 比对必需——无基线只有副本无法定指纹 |
|
||||
| watermark hypothesis(水印假设) | fingerprint 水印验证(步骤 2)——有具体假设(触发集/后门)可定向验证 |
|
||||
|
||||
**规则**:intent 命中后检查该路径所需资产;缺失 → 先向用户询问(有无/能否提供),用户无法提供则说明该路径不可执行并转可用路径。
|
||||
|
||||
## 何时使用 / 何时不用
|
||||
|
||||
- 用:模型泄露/窃取取证、API 模型攻击评估(提取/指纹)、训练数据泄露判定、模型鲁棒性评估(对抗样本)
|
||||
- 用:水印/指纹验证(嫌疑副本与受害者模型比对)
|
||||
- 用:模型 API 一致性审计(同输入多查询/多端点比对,找副本/代理)
|
||||
- 用:鲁棒性基线评估(上线前/防御验证前测一遍干净与扰动准确率)
|
||||
- 不用:模型文件格式解析与权重提取(转 [[re-ai-model]]);模型训练/微调(非逆向);部署加固(防御侧不在本技能)
|
||||
- 不用:无授权目标(红线:仅授权评估场景;授权边界见 [[gotchas]])
|
||||
- **RE_AUTH 前置(guard 联动)**:本技能 guard.require_authorization=true——执行前确认授权上下文(triage 第 0 步 `RE_AUTH`):owned / ctf / research 可执行;unknown 先询问目标归属(所有权 / 测试授权 / 研究环境),未说明只做静态评估不进入动态步骤
|
||||
- 不用:提示注入/提示泄露评估(LLM 侧攻击面)与 API 服务本身的注入/越权测试(应用侧漏洞不在本技能)
|
||||
|
||||
## 工具准备
|
||||
|
||||
### python3(核心运行时)
|
||||
|
||||
- 各平台安装见 [[re-python]] 工具准备
|
||||
|
||||
### 模型库(torch / tensorflow,按目标格式选)
|
||||
|
||||
- 多平台: `pip install torch` / `pip install tensorflow`(按硬件可选 CPU 版;按目标框架选一即可,蒸馏脚本只依赖其张量操作)
|
||||
- 验证: `python3 -c "import torch"`
|
||||
|
||||
### 攻击评估库(ART,可选)
|
||||
|
||||
- 多平台: `pip install adversarial-robustness-toolbox`(对抗鲁棒性工具箱,覆盖提取/指纹/对抗样本攻击模块)
|
||||
- 验证: `python3 -c "import art"`
|
||||
|
||||
### 查询接口客户端(API 目标)
|
||||
|
||||
- 多平台: `pip install requests`;验证: `python3 -c "import requests"`
|
||||
- 可视化(分布对比图,可选):`pip install matplotlib`
|
||||
|
||||
## 操作步骤
|
||||
|
||||
按顺序执行;仅限授权评估场景(红线:不针对未授权目标)。方法学依据:模型提取(API 查询蒸馏)、成员推断(影子模型)、对抗样本(FGSM/PGD)为公开研究框架,实现细节按目标模型域调整(见 [[decision-tree]] 分支)。
|
||||
|
||||
1. **模型提取攻击**(Overview:通过 API 查询重建近似模型——蒸馏):
|
||||
- Checklist:
|
||||
1. 确认授权与用途(评估/取证声明记录)
|
||||
2. 接口探测:读 API 文档/试查询 → 确认限额与输出字段(logits/概率或仅标签——可观测性决定策略,见 CORE RULE)
|
||||
3. 查询采样(输入分布覆盖:代表性输入 + 边界扰动 + 标签分布均衡)
|
||||
4. 蒸馏训练(以 API 输出为教师标签)
|
||||
5. 评估近似度(同输入集输出对比:一致率 + 标签分布对比,不是只看精度)
|
||||
- 实现经验(soft label 优先、边界扰动、评估一致性、蒸馏基线、查询日志等)见 [[implementation-notes]]
|
||||
- 仅标签时:降级为决策边界采样(输出分布重建受限,见 [[gotchas]] 接口坑);查询预算内先小批估计(坑 1)
|
||||
|
||||
2. **模型指纹/水印检测**(Overview:**行为级**水印——模型表现出来是什么:trigger 触发响应 / 查询响应 / 黑盒指纹;文件级水印(权重 pattern/metadata/tensor hash)走 [[re-ai-model]]):
|
||||
- Checklist:
|
||||
1. 嵌入检测:输入扰动(特定噪声/触发器)→ 输出特征比对(水印触发行为)
|
||||
2. 指纹提取:模型行为签名(代表性输入集输出向量)→ 与疑似副本比对
|
||||
3. 窃取取证:嫌疑模型与受害者模型的指纹距离 → 阈值判定相似(阈值校准见 [[decision-tree]] 证据分级)
|
||||
4. 产出:指纹向量 + 距离报告(距离值 + 阈值依据 + 置信度)
|
||||
- 实现经验(输入集难度分层、归一化、反例对照组、抹除对抗、时效、水印枚举)见 [[implementation-notes]]
|
||||
- 抹除对抗:剪枝/微调/蒸馏会削弱指纹——用鲁棒指纹并标注「可能被抹除」(见坑 3)
|
||||
|
||||
3. **成员推断**(Overview:判定某样本是否在训练集中):
|
||||
- Checklist:
|
||||
1. 确认输入形态:目标模型输出的概率向量 + 样本特征(可观测性见 CORE RULE)
|
||||
2. 选攻击类型:白盒(有 loss)用阈值法;黑盒(只有输出)用影子模型(同分布代理模型校准)
|
||||
3. 对照基线:同分布随机样本(非训练样本)的损失分布作基准线
|
||||
4. 输出:统计判定(ROC/阈值曲线、给定 FPR 下的 TPR、置信区间),不是确定性结论
|
||||
- 实现经验(基线设计、隐私脱敏、统计口径)见 [[implementation-notes]]
|
||||
- 局限:只能给出统计判定(误报控制:阈值校准;隐私保护训练目标可对抗,见 [[gotchas]])
|
||||
|
||||
4. **对抗样本基础**(Overview:鲁棒性评估与防御验证,非攻击部署):
|
||||
- Checklist:
|
||||
1. 选路径:白盒(模型权重可加载且 loss 可微)用梯度扰动(FGSM/PGD);黑盒用查询/迁移扰动(可观测性见 CORE RULE)
|
||||
2. 设扰动预算(epsilon)——评估口径可比
|
||||
3. 评估对照:先测干净样本基线(扰动前准确率),报告扰动前后对比
|
||||
- 实现经验(预算梯度、迁移性边界)见 [[implementation-notes]]
|
||||
- 边界:对抗样本迁移性差(白盒扰动对黑盒目标不保证有效,见 [[gotchas]])
|
||||
|
||||
5. **评估报告与存证**:
|
||||
- 三要素全记录:方法(采样集/蒸馏超参/距离阈值)、结果(指标)、参数(随机种子/框架版本)
|
||||
- 攻击脚本与评估产物 sha256 存档;结论按 [[re-analyze/analysis-contract]] 交付
|
||||
|
||||
## 跨域联合
|
||||
|
||||
- [[re-ai-model]]:**消费文件级证据**(文件级证据 → 行为级验证单向流)——有模型文件时先经 re-ai-model 提取结构/权重/文件级 fingerprint,再在本技能做行为一致性验证;仅 API(无文件)时无文件侧输入,直接黑盒评估
|
||||
- [[re-python]]:Python 工具链基础
|
||||
- [[re-feedback]]:攻击案例经验沉淀(脱敏后)
|
||||
- [[re-analyze/analysis-contract]]:评估结论交付格式
|
||||
|
||||
## 常见坑与陷阱
|
||||
|
||||
- **查询预算限制**:现象——API 限流/计费中断;原因——高查询量;对策——预算内采样设计(先小批估计),记录已用配额
|
||||
- **置信度不可得时降级**:现象——接口只返回标签;原因——服务端裁剪输出;对策——决策边界采样 + 标注局限,不硬造概率
|
||||
- **水印被抹除**:现象——指纹比对失败;原因——嫌疑方做了剪枝/微调/蒸馏;对策——用鲁棒指纹(多触发器)并标注「可能被抹除」;距离接近但未达阈值时输出「弱相似」而非「无关」
|
||||
- **成员推断误报**:现象——统计判定错误;原因——阈值偏差/影子模型分布不匹配;对策——影子模型校准 + 报告置信区间
|
||||
- **评估指标误导**:现象——提取模型「精度高」但输出分布完全不同;原因——只比精度不比分布;对策——一致率 + 标签分布 + 校准度多指标联合
|
||||
- **提取不收敛**:现象——蒸馏效果差;原因——采样分布与目标分布不匹配/接口输出裁剪;对策——按目标数据域重采样,标注数据分布假设
|
||||
- **输出解析错误**:现象——logits 与标签错位;原因——API 响应字段解析错;对策——先打印原始响应核对字段再批量
|
||||
- **结果不可复现**:现象——复跑结果不同;原因——随机种子/采样顺序未固定;对策——固定 seed 并记录
|
||||
- **对比对象口径错**:现象——指纹比对用了不同任务模型;原因——未确认任务口径;对策——比对前确认任务/标签空间一致
|
||||
- **多端点口径差异**:现象——同一模型不同端点输出不同;原因——A/B 路由/版本不同;对策——锁定端点做前后对比,标注端点标识
|
||||
- **批查询触发风控**:现象——正常速率查询被风控;原因——触发速率阈值;对策——查询节奏控制(限速/随机间隔),记录风控事件
|
||||
- **资源预算**:现象——蒸馏 OOM/长任务中断;原因——学生模型过大/时长估计不足;对策——分阶段 checkpoint(采样/训练分步存档),小批量/CPU 降级
|
||||
- **授权边界**:现象——对未授权 API 发起攻击测试;原因——范围未确认;对策——先确认授权(使用边界红线)
|
||||
- 场景分支与证据分级见 [[decision-tree]];边界与反例见 [[gotchas]]
|
||||
@@ -0,0 +1,69 @@
|
||||
# AI 攻击决策树与证据分级
|
||||
|
||||
攻击面由「目标形态 × 接口能力」决定,先侦察再动手。本文档与 SKILL.md 步骤 1-4 配套使用。
|
||||
|
||||
## 目标形态决策树
|
||||
|
||||
```
|
||||
评估目标
|
||||
├─ 黑盒 API(只能查询)→ 提取攻击 / 黑盒对抗样本 / 行为指纹
|
||||
├─ 模型文件(拿到权重)→ 白盒分析:权重指纹、成员推断(白盒)、FGSM/PGD
|
||||
│ (文件解析与格式还原走 [[re-ai-model]])
|
||||
└─ 嵌入/微调产物(LoRA/适配器)→ 与基础模型比对差异(指纹来源分析)
|
||||
```
|
||||
|
||||
## 接口能力分支
|
||||
|
||||
```
|
||||
API 查询
|
||||
├─ 返回完整 logits/softmax 概率 → 蒸馏优先(soft label 训练)
|
||||
├─ 返回 top-k 概率 → 蒸馏降级(截断概率,标注信息损失)
|
||||
├─ 仅返回标签 → 决策边界采样(边界 + 对抗扰动查询),不做概率重建
|
||||
└─ 带温度/归一化扰动 → 先校准再蒸馏(softmax 温度影响教师信号)
|
||||
```
|
||||
|
||||
## 取证目的分支
|
||||
|
||||
```
|
||||
取证请求
|
||||
├─ 「是不是复制品」→ 行为指纹提取 + 距离阈值判定
|
||||
│ ├─ 距离 < 阈值且多输入集稳定 → 强相似(高置信)
|
||||
│ ├─ 距离 < 阈值但单输入集 → 弱相似(标注输入集局限)
|
||||
│ └─ 距离 > 阈值 → 不相似;但先排除「指纹被抹除」(见 [[gotchas]])
|
||||
├─ 「某样本是否在训练集」→ 成员推断(影子模型/损失分布)
|
||||
│ ├─ 分布显著分离 + 校准 → 统计判定(带置信区间)
|
||||
│ └─ 分布重叠 → 无法判定(输出区间而非断言)
|
||||
└─ 「有没有被加水印」→ 触发器检测(已知/未知触发器枚举)
|
||||
```
|
||||
|
||||
## 证据分级表
|
||||
|
||||
| 证据 | 弱 | 中 | 强 |
|
||||
|---|---|---|---|
|
||||
| 指纹距离 | 单输入集接近 | 多输入集稳定接近 | 多输入集 + 独有行为特征一致 |
|
||||
| 成员推断 | 损失高于基线 | 分布分离 + 校准 | 多攻击面一致(白盒+黑盒) |
|
||||
| 水印触发 | 单触发器响应 | 多触发器响应 | 触发器 + 输出结构特征吻合 |
|
||||
| 对抗鲁棒性 | 单样本扰动有效 | 多样本/多方法一致 | 迁移到替代模型仍有效 |
|
||||
|
||||
任何「强」证据都要排除替代解释(同源训练/公开基础模型微调——基础模型相同会天然产生指纹接近,见 [[gotchas]])。
|
||||
|
||||
## 组合套路(提取评估流程)
|
||||
|
||||
1. 接口能力侦察(预算内小批)
|
||||
2. 采样集设计(代表 + 边界 + 标签均衡)
|
||||
3. 蒸馏训练 → 评估(一致率/分布/校准)
|
||||
4. 指纹提取(多输入集)→ 距离报告
|
||||
5. 结论按证据分级表定级 + 标注局限(授权、预算、数据分布假设)
|
||||
|
||||
## 实现教训(内化)
|
||||
|
||||
- 先问「接口给什么」,再选攻击面——logits 可得性是策略分水岭
|
||||
- 多指标评估:精度高 ≠ 提取成功,一致率 + 标签分布联合看
|
||||
- 指纹判定要排除「同源基础模型」假说(微调自同一公开模型会天然相似)
|
||||
- 报告永远是统计性/概率化陈述,成员推断与指纹判定都带置信度
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 仅授权评估场景(授权边界见 SKILL.md 红线与 [[gotchas]])
|
||||
- 结论按 [[re-analyze/analysis-contract]] 交付;攻击代码不部署到生产环境
|
||||
- 防御侧参考(对抗训练/输出裁剪)只作评估结论的旁注,不展开
|
||||
@@ -0,0 +1,36 @@
|
||||
# AI 攻击方法论坑与边界
|
||||
|
||||
## 提取攻击坑
|
||||
|
||||
- **接口裁剪**:服务端裁剪输出(温度缩放/截断 logits/量化)会削弱教师信号——先探测输出分布(相同输入多次查询看方差),再决定蒸馏策略
|
||||
- **查询限额**:限流/计费/风控会中断长查询任务——预算内设计采样(先小批估计分布,再决定规模);被风控时换查询节奏并记录
|
||||
- **数据分布不匹配**:查询分布与目标域分布不符时蒸馏模型「学会了查询集」而非「目标模型」——采样覆盖目标域,标注分布假设
|
||||
- **缓存与批处理**:API 前有缓存/批处理层时相同输入返回相同输出(正常),但去重/缓存会让查询统计失真——评估有效性时用随机扰动输入
|
||||
- **防提取对策**:水印(后门触发)、输出扰动、查询风控都可能存在——提取结果不可用时标注「存在防提取机制」,别当失败
|
||||
|
||||
## 指纹/水印坑
|
||||
|
||||
- **同源基础模型假说**:嫌疑模型与受害者模型都微调自同一公开基础模型时,行为指纹天然接近——判定前先比对「独有特征」(训练数据/任务特有的行为),排除同源解释
|
||||
- **指纹被抹除**:剪枝/量化/微调/蒸馏都会削弱指纹——用鲁棒指纹(多触发器/行为签名);距离「接近但未达阈值」输出「弱相似」而非「无关」
|
||||
- **触发器过拟合**:单触发器验证可能只是「该输入的特殊性」而非水印——多触发器 + 触发器族(结构/噪声/语义类)交叉验证
|
||||
- **阈值无普适值**:指纹距离阈值依赖模型家族与输入集——阈值按同族对照模型校准(训练 1-2 个对照模型量距离分布),不套用他人阈值
|
||||
|
||||
## 成员推断坑
|
||||
|
||||
- **过拟合 ≠ 成员**:高置信度输出可能只是模型对特定输入过拟合,不是「在训练集中」——用影子模型(同分布代理)校准分布,再判定
|
||||
- **影子模型同分布假设**:影子模型与目标训练分布不一致时校准失效——影子训练数据尽量贴近目标域(公开同域数据),标注假设
|
||||
- **隐私保护训练对抗**:DP-SGD/差分隐私训练的模型成员推断信号弱——分布不分离时输出「无法判定」,别硬给结论
|
||||
- **统计性质误读**:成员推断是统计判定(带 TPR/FPR),单样本断言「肯定在训练集」不成立——报告带置信区间
|
||||
|
||||
## 评估边界与反例
|
||||
|
||||
- **对抗样本迁移性**:白盒扰动迁移到黑盒目标不保证有效——迁移成功率是评估指标,不是攻击保证
|
||||
- **反例:误用「精度」**:提取模型在测试集精度接近目标 ≠ 功能等价(输出分布可能完全不同)——功能等价要看一致率与分布
|
||||
- **反例:模型版本差异**:同一模型的不同部署版本(量化/蒸馏部署版)指纹与训练版不同——比对前确认版本口径
|
||||
- **范围外**:提示注入/提示泄露(LLM 侧)不在本技能(面向分类/生成模型的提取、指纹、成员推断与对抗评估);训练数据版权判定是法律问题,本技能只出统计证据
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 仅授权评估场景(范围/目标/数据确认先行);不绕过付费/访问控制边界
|
||||
- 结论按 [[re-analyze/analysis-contract]] 交付,统计性陈述 + 置信度 + 局限
|
||||
- 相关文件分析衔接 [[re-ai-model]];经验沉淀转 [[re-feedback]](脱敏)
|
||||
@@ -0,0 +1,39 @@
|
||||
# AI 攻击实现笔记(Implementation Notes)
|
||||
|
||||
SKILL.md 操作步骤的流程(Overview + Checklist)之外的实现经验——按步骤分组,命中对应步骤时参考。
|
||||
|
||||
## 步骤 1:模型提取
|
||||
|
||||
- **soft label 优于 hard label**:API 输出带 logits/概率时蒸馏质量显著高于仅标签(决策边界信息更丰富);仅有标签时降级为决策边界采样,输出分布重建受限(标注局限)
|
||||
- **边界扰动**:输入空间小幅扰动(噪声/旋转/亮度)覆盖决策边界附近区域,提升蒸馏对边界形状的拟合
|
||||
- **评估一致性**:同一输入多次查询看 logits 方差——方差大说明输出随机化/防提取机制
|
||||
- **蒸馏训练要点**:学生模型容量与教师相近(过小欠拟合边界、过大过拟合采样噪声);训练轮次/学习率按小验证集调
|
||||
- **蒸馏评估基线**:随机初始化学生模型与目标模型同分布对比——排除「模型本身输出相似」的假象
|
||||
- **查询日志**:每次查询记录(输入指纹/输出/时间/配额消耗),供审计与复现
|
||||
- **查询预算**:预算内先小批估计(限流/计费中断处理见 SKILL.md 坑 1)
|
||||
|
||||
## 步骤 2:模型指纹/水印检测
|
||||
|
||||
- **指纹输入集设计**:覆盖类别/难度分层(简单+难例)——难例区分度更高
|
||||
- **比对前归一化**:输出向量先归一(softmax 温度/缩放差异)再算距离(L2/余弦)
|
||||
- **反例对照组**:触发器响应可能来自模型训练偏差而非水印——先测无触发器输入的基线响应
|
||||
- **抹除对抗**:剪枝/微调/蒸馏会削弱指纹——用鲁棒指纹(多触发器)并标注「可能被抹除」
|
||||
- **指纹时效**:模型热更新后指纹漂移——比对前确认版本/时间窗
|
||||
- **未知水印枚举**:触发器候选(特定输入模式/语义后门)逐个测,先小批探测再扩大
|
||||
|
||||
## 步骤 3:成员推断
|
||||
|
||||
- **对照基线**:同分布随机样本(非训练样本)的损失分布作基准线,再对比目标样本位置
|
||||
- **隐私敏感性**:成员推断涉及个人数据判定——结论脱敏,不公开样本身份
|
||||
- **统计口径**:输出 ROC/阈值曲线(给定 FPR 下的 TPR、置信区间),不是确定性结论;隐私保护训练目标可对抗(误报控制:阈值校准)
|
||||
|
||||
## 步骤 4:对抗样本
|
||||
|
||||
- **扰动预算(epsilon)**:FGSM/PGD 都设扰动上限——评估口径可比
|
||||
- **评估对照**:先测干净样本基线(扰动前准确率),报告扰动前后对比
|
||||
- **预算梯度**:epsilon 从 0 起递增,报告不同预算下的准确率曲线
|
||||
- **迁移性边界**:对抗样本迁移性差——白盒扰动对黑盒目标不保证有效
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 本文件是经验参考,不替代 SKILL.md 的步骤流程;实现细节与目标模型域冲突时以目标域为准(见 [[decision-tree]] 分支)
|
||||
Reference in New Issue
Block a user