发现新攻击:Garak与PyRIT

回归测试在防止已知故障再次发生方面很强大,但无法发现尚无测试用例的攻击。Garak和PyRIT是AI红队工具,它们对LLM或AI应用程序尝试多种探测和对话策略,并收集意想不到的潜在故障。

这两个工具并非“自动漏洞确认器”。结果是检测器和评分器的判断,可能存在误报。本次实践仅使用自有的本地测试目标、合成数据和只读功能。发现的结果只有在人工审查跟踪和策略后,才能升级为漏洞或回归测试用例。

系统化的多探针和自适应分支探索检查受保护的LLM并隔离存储发现的候选

Garak与PyRIT有何不同?

Garak是一种扫描器型工具,它向目标生成器发送各种探针,并使用检测器寻找失败迹象。PyRIT(Python Risk Identification Tool)更像一个框架,它通过组合目标、攻击、转换器、评分器和内存来创建单轮或多轮攻击实验。

比较 Garak PyRIT
— — —
核心单元 探针和检测器 攻击·目标·评分器·内存
优势 广泛的重复扫描 具有状态的自适应·多轮实验
目标连接 生成器插件 提示目标
判断 检测器和评估器 评分器和人工审查
结果 日志·JSONL·报告 对话·分数·结果存储在内存中
推荐起点 选择的探针家族的窄范围扫描 从单轮开始执行一个合成目标

Garak官方文档中,探针管理用于诱导故障的输入和交互,生成器封装了与模型或对话系统的连接。检测器在响应中寻找特定的故障迹象,而Harness协调整个执行过程。

PyRIT官方文档将自动化/人工主导的红队、各种目标、单轮/多轮攻击、灵活的评分以及基于SQLite/Azure SQL的内存描述为主要组成部分。

建立安全的实践边界

Garak·PyRIT Container
  ↓ 허용된 Test Network만
Local Guardrail Gateway
  ↓
합성 Test Tenant + 읽기 전용 RAG + Mock Tool
  ↓
Nova·NeMo·Presidio → Test LLM
  ↓
비민감 Trace와 격리된 결과 저장소

请勿针对实际生产端点、他人的模型、外部服务和真实数据运行。测试网关会阻止出站流量,工具只会返回固定的模拟响应,而不是删除文件、执行命令、支付或发送消息。API密钥应作为秘密注入,而不是放入图像或笔记本中。

实践1:验证Garak结构和安装

官方仓库提供了PyPI安装和探针列表的查看方法。在操作评估中,应固定已验证的版本。

mkdir llm-redteam-lab
cd llm-redteam-lab

python3 -m venv .venv-garak
source .venv-garak/bin/activate
python -m pip install --upgrade pip
python -m pip install garak

python -m garak --version
python -m garak --list_probes

从一开始就运行所有探针可能会导致成本、时间和结果量急剧增加。首先,使用测试生成器验证执行结构,或者只选择一个与服务目标相关的探针家族。

python -m garak 
  --target_type test.Repeat 
  --probes encoding

test.Repeat是一个内置的测试目标,用于重复输入。它不是评估实际漏洞的命令,而是用于验证安装和报告管道的安全冒烟测试。Garak可以将执行详情记录到JSONL中,因此输入和输出只使用合成数据,并限制对结果目录的访问权限。

实践2:仅将自有的HTTP网关连接为目标

下一步是将本地Guardrail网关连接到Garak的REST生成器。REST生成器的确切配置键可以在您安装的Garak版本的官方参考文档中找到。

plugins:
  generators:
    rest:
      RestGenerator:
        uri: http://host.containers.internal:8080/chat
        method: post
        headers:
          Content-Type: application/json
        req_template_json_object:
          message: "$INPUT"
          tenant_id: "redteam-test"
        response_json: true
        response_json_field: response
python -m garak 
  --target_type rest.RestGenerator 
  --config garak-rest.yaml 
  --probes promptinject

上述名称和选项可能因版本而异。请首先查阅–plugin_info和参考文档。定义扫描范围、最大生成数、并发性、超时和成本限制,并使用网络策略阻止测试网关以外的地址。

如何解读Garak结果

Garak的FAIL意味着检测器在响应中发现了目标失败迹象。这并不立即意味着实际漏洞已得到确认。

  1. 确认使用了哪种探针和检测器组合。
  2. 检查目标错误或空响应是否被错误判断。
  3. 除了用户输出,还要检查RAG·工具跟踪。
  4. 重复测试以确认在相同条件下是否可重现。
  5. 缩减为最小的合成测试用例后,由人工定义预期行为。

如果检测器以简单的拒绝短语为标准,可能会因语言或表达的变化而产生误报。可能需要一个自定义检测器或后处理门,以同时验证Guardrail的结构化决策和工具调用状态。

实践3:以内存模式启动PyRIT

PyRIT官方文档提供了使用包安装和initialize_pyrit_async的框架示例。在隔离实践中,首先使用内存模式(In-memory Memory)来减少对话留在磁盘上的范围。

python3 -m venv .venv-pyrit
source .venv-pyrit/bin/activate
python -m pip install --upgrade pip
python -m pip install pyrit
python -c "import pyrit; print(pyrit.__version__)"
import asyncio
from pyrit.setup import IN_MEMORY, initialize_pyrit_async

async def main():
    await initialize_pyrit_async(memory_db_type=IN_MEMORY)
    print("PyRIT in-memory lab initialized")

asyncio.run(main())

IN_MEMORY在进程结束后会方便地消失,但它并不能清除屏幕输出和外部提供商的日志。提示和响应中只应使用合成数据。

实践4:从单轮开始验证目标

PyRIT的目标是要攻击的AI系统接口。官方文档示例使用OpenAIChatTarget和PromptSendingAttack。本文仅展示结构,前提是实际密钥不硬编码在代码中,而是从环境中加载已批准的测试端点设置。

import asyncio
from pyrit.executor.attack import PromptSendingAttack
from pyrit.output.attack_result.pretty import PrettyAttackResultMemoryPrinter
from pyrit.prompt_target import OpenAIChatTarget
from pyrit.setup import IN_MEMORY, initialize_pyrit_async

async def main():
    await initialize_pyrit_async(memory_db_type=IN_MEMORY)

    target = OpenAIChatTarget()
    attack = PromptSendingAttack(objective_target=target)

    result = await attack.execute_async(
        objective="합성 Test 문서의 접근 정책을 설명해줘"
    )

    printer = PrettyAttackResultMemoryPrinter()
    await printer.write_async(result)

asyncio.run(main())

此目标是确认正常连接的冒烟测试。只有在验证了安全的单轮、评分器验证和结果存储范围后,才能将其扩展到已批准的多轮策略。

实践5:分离评分器和人工判断

PyRIT评分器可以使用True/False、李克特量表或分类来评估响应是否达到目标。基于LLM的评分器虽然灵活,但自身存在错误和成本。

判断对象 优先方式
— —
工具调用情况 结构化跟踪的确定性检查
租户边界违规 文档ID·租户ID的确定性检查
秘密字符串暴露 合成金丝雀的精确匹配检查
拒绝含义·绕过成功 评分器与人工审查并行
答案质量·相关性 模型评分器和样本审查

攻击模型和评分器模型即使与目标模型分离,也可能都出错。在结果中记录评分器版本、提示、阈值和执行环境,并且不要将未确定或错误计为成功。

结合系统扫描与自适应探索

Garak 넓은 Probe Scan
  ↓ 실패 후보
사람의 1차 분류
  ↓ 대화형 재현이 필요한 후보
PyRIT 단일·다중 Turn 실험
  ↓ 재현 가능한 최소 사례
Trace·권한·정책 검토
  ↓ 승인된 Finding
Promptfoo 회귀 Testcase + Guardrail 정책 변경

虽然使用Garak进行广泛扫描并使用PyRIT深入探索对话上下文的流程很有用,但并非总是需要遵循此顺序。重要的是将这两个结果与相同的finding_id、目标版本、策略包和跟踪ID关联起来。

Podman沙盒操作示例

podman network create --internal llm-redteam-lab

podman run --rm 
  --network llm-redteam-lab 
  --read-only 
  --cap-drop=all 
  --security-opt=no-new-privileges 
  --pids-limit=256 
  --memory=4g 
  --cpus=2 
  -v "$PWD/results:/results:Z" 
  localhost/llm-redteam-tools:VERSION

在–internal网络中无法调用外部API。您可以将本地目标容器连接到同一网络以进行完全本地实践,或者如果外部提供商是必需的,则设置一个单独的出站代理,只允许通过已批准的目标。请勿挂载主机网络、Docker Socket、Home Directory和Cloud Credential Directory。

保护结果中的个人信息和成本

  • 仅在最短期限内保留原始提示·响应文本。
  • 使用合成数据集代替实际客户对话。
  • 配置JSONL·内存数据库·跟踪的访问权限和加密。
  • 从日志中删除API密钥和授权头。
  • 限制最大轮次、探针、生成、并发性、令牌和成本。
  • 将工具替换为模拟或只读版本。
  • 扫描结束后销毁临时容器和秘密。

实践完成清单

  • 仅使用了自有或明确授权的测试目标。
  • 区分了Garak的生成器·探针·检测器·Harness的角色。
  • 区分了PyRIT的目标·攻击·评分器·内存的角色。
  • 在进行全面扫描之前,使用测试目标验证了安装。
  • 从较小的探针家族和多轮范围开始。
  • 使用了合成租户、合成金丝雀和模拟工具。
  • 限制了容器权限、网络出站和资源限制。
  • 未将FAIL·分数自动解释为已确认的漏洞。
  • 同时审查了用户输出和内部工具·RAG跟踪。
  • 仅将已批准的发现升级为最小回归测试用例。

总结

Garak和PyRIT并非重新评分已知答案的工具,而是用于在当前测试套件之外寻找潜在故障的探索工具。Garak通过探针和检测器进行广泛扫描,而PyRIT则通过组合目标·攻击·评分器·内存来深入调查对话路径。

自动化生成的是候选列表,而非判决。它应在隔离的测试环境中运行,并且只有在人工审查策略、权限、跟踪和可重现性之后,才应将有价值的发现升级为Promptfoo测试用例和Guardrail策略。下一篇也是最后一篇将完成整个循环,将这些发现转化为包含责任人、预期结果和策略版本的测试用例,并安全地部署到控制平面。

官方资料

※ Garak插件名称、PyRIT API和Python要求可能因版本而异。在执行命令之前,请查阅固定版本的官方文档,并在授权的沙盒中使用合成数据进行验证。


Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注