ccc909/GradientQL

GitHub: ccc909/GradientQL

GradientQL 是一款基于 LLM agent 的自主式 GraphQL 漏洞扫描器,通过大模型推理自动完成从侦察到漏洞利用的完整安全评估流程。

Stars: 0 | Forks: 0

# GradientQL ![License: MIT](https://img.shields.io/badge/License-MIT-e8a317.svg) ![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg) GradientQL 是一款由单一语言模型驱动、主打直觉体验的 GraphQL 漏洞扫描器。你只需 提供一个 endpoint 和一个模型 API key,它就能自动完成整个评估流程:读取 schema, 在需要时注册并登录账户,并探测访问控制缺陷、 注入、服务端请求伪造 (SSRF)、JWT 伪造、请求走私、CSRF、凭证 暴力破解以及拒绝服务攻击。

GradientQL live dashboard — coverage map, activity feed, loot pane, and findings table during a scan

扫描期间的实时仪表板(示意数据)。

我大约在一年前开始了这个项目。最初的计划是购买一堆 Radeon MI50 GPU,并在本地为 GraphQL 查询生成微调一个模型,但计划落空了。当 Claude Opus 4.6 发布时,我改用云端模型重新启动了这个想法。由于时间紧迫,我几乎全部都是使用 LLM 构建的,同时仍在做一些我认为有趣的事情:自动化漏洞 挖掘。 第一个版本是 PrediQL 论文 (arXiv:2510.10407) 的实现。出于好奇,我 将其控制循环替换为完全 agentic 的循环,结果非常有趣,足以让我继续 下去。早期,我曾在一个漏洞披露计划中将其指向一个生产环境的 GraphQL API。在一个看似无害的查询中,模型注意到了响应中的数据库错误并进行了标记, 这最终演变成一个具有实际影响的盲注 SQL injection。该漏洞已通过该计划报告 并得到修复。 请注意:此工具会发送真实的攻击流量,并且没有内置的授权检查。它会 将你提供的任何 URL 作为目标。仅在你获准测试的系统上运行它:你自己的部署、 像 DVGA 这样的本地目标,或者你拥有的漏洞赏金或披露计划范围内的目标。未经许可对他人的系统 运行此工具很可能是非法的,保持在授权范围内是你的 责任。 ## 环境要求 - Python 3.10 或更高版本 - OpenRouter 上模型的 API key - 机器学习技术栈(FAISS、sentence-transformers 和 PyTorch)的空间,扫描器将其 用于 schema 搜索 ## 安装说明 克隆存储库并以可编辑模式安装: ``` pip install -e ".[dev]" ``` ## 设置模型 key 扫描器会在三个地方查找模型 API key,并使用它找到的第一个: 1. 设置文件中的 `llm.api_key` 字段。 2. `config/api_key.local` 文件(会被 git 忽略)。 3. 由 `llm.api_key_env` 命名的环境变量(默认为 `OPENROUTER_API_KEY`)。 ## 运行扫描 将扫描器指向你获准测试的 endpoint: ``` python -m gradientql --url https://your-target.example/graphql ``` 添加 `--trace` 以记录模型在运行期间所做的一切。这是 在扫描完成后了解扫描情况的主要方式: ``` python -m gradientql --url https://your-target.example/graphql --trace ``` `--url` 会覆盖配置文件中设置的目标,安装后,`gradientql` 命令也会 运行相同的操作。模式是自动选择的:在交互式终端中运行不带 `--url` 参数的 `gradientql` 将打开[界面](#interactive-interface);如果传入 `--url`、通过管道或 重定向输出,或者添加 `--no-tui`,它将打印纯文本日志。只要连接了终端,即使在设置了 `--url` 的情况下,`--tui` 也会强制开启界面。 ## 命令行参数 | 参数 | 效果 | | --- | --- | | `--url URL` | 目标 GraphQL endpoint。覆盖设置文件中的 `target.url`。 | | `--settings PATH` | 设置文件的路径。默认为 `config/settings.yaml`。 | | `--trace [PATH]` | 将每个步骤的 prompt、响应、观察结果和状态记录到 `.jsonl` 日志和匹配的 `.md` 摘要中。仅使用 `--trace` 会写入 `output/agent_trace_.*`;传入路径或前缀以写入其他位置。 | | `-v`, `--verbose` | 将每个步骤完整的、未截断的思考和观察结果打印到控制台(纯日志模式)。 | | `--tui` | 强制使用交互式界面。未连接终端时回退到纯日志。 | | `--no-tui` | 即使在交互式终端中也强制输出纯日志。 | | `-h`, `--help` | 显示用法并退出。 | ## 交互式界面 运行不带参数的 `gradientql` 即可打开 TUI,它由以下部分组成: - 一个菜单,显示当前目标、预算、模型、代理以及是否设置了 API key,并提供 用于启动扫描或打开设置的按钮。 - 一个设置界面,用于配置目标 URL、预算、模型、代理、请求延迟和超时,以及 fuzz payload 上限,此外还有一个针对各项攻击技术(注入、SSRF、拒绝 服务、请求走私、CSRF、JWT、暴力破解和访问控制测试)的开关子菜单。 - 一个实时仪表板,在扫描开始时显示。在扫描运行之前,它会检查 API key 是否 通过身份验证,如果 key 缺失或被拒绝,它会停止并显示一条明确的消息。在运行期间,它 会实时更新:统计行(步骤、已用时间、请求速率、发现、模型)、schema 的覆盖图、 实时显示模型决策的活动反馈、包含所有 已获取凭证的战利品窗格、当前会话 token 以及已记录的事实,还有一个发现结果表格。

GradientQL menu screen with target, budget, model, and key status

GradientQL settings screen

覆盖图将每个根字段标记为未测试、浅层探测、开放、有数据、无效或有发现,因此你可以随着 agent 的工作观察攻击面的填充情况。传入 `--tui` 以强制使用此界面并连同 `--url` 一起使用,或者使用 `--no-tui` 强制输出纯文本日志。 ### 使用方法 该界面由键盘和鼠标驱动;可用的按键显示在页脚。 - **菜单** — `s` 开始扫描,`g` 打开设置,`q` 退出。 - **设置和攻击** — 编辑字段和开关;Attacks 按钮可打开 针对特定技术的开关。`Esc`(或返回)保存并返回,更改将应用于下次扫描。 - **仪表板** — 在扫描开始时打开并实时更新。`Esc` 停止扫描并返回 菜单。 扫描需要目标 URL 和可用的 key;仪表板会在开始前验证 key,如果 key 缺失或被拒绝,它将停止并显示明确的消息。 ## 工作原理 扫描是一个简短的 pipeline。扫描器会内省 schema,快速检查常见的 配置错误,将控制权交给模型,等待任何带外回调到达, 删除重复的发现,并打印报告。 中间步骤是执行核心工作的地方。在每个回合,模型都会获得当前情况的压缩视图: schema、已尝试内容的摘要、已记录的事实,以及 它收集到的任何凭证或 token。它会回复一个 JSON 操作,例如: ``` {"thought": "...", "action": "sweep", "args": {}, "learned": "optional note", "verdict": {}} ``` `learned` 和 `verdict` 字段是可选的,可以附加到任何操作中。这是 模型写入自身记忆的方式。`learned` 记录值得保留的事实,而 `verdict` 将 字段标记为无效、开放或已利用。程序本身也会对每个响应进行分类,但 模型的 verdict 优先,因此模型负责判断,而当它保持沉默时则由一个简单的默认值 进行补充。 模型可以采取的操作包括 `graphql`、`sweep`、`search_schema`、`fuzz`、`set_identity`、 `temp_mail`、`forge_jwt`、`oob_url`、`dos`、`smuggle`、`csrf`、`auth_test`、`batch_brute`、`visit`、 `note`、`report_finding` 和 `done`。它们涵盖了 侦察、身份验证(包括注册账户、从临时邮箱读取确认电子邮件和登录)以及各种单独的攻击技术。 ## 配置说明 设置使用 YAML 编写。`config/settings.yaml` 是一个你可以复制和编辑的模板,你也可以 使用 `--settings` 让扫描器指向不同的文件。任何未提供的 key 都会回退到 内置默认值,因此配置文件只需要你想要更改的值。最重要的 字段: ``` target: url: "https://your-target.example/graphql" headers: {} # auth headers for an already-authenticated run csrf: { enabled: false } http: proxy: "" # route traffic through Burp or mitmproxy, e.g. "http://127.0.0.1:8080" delay: 0.0 # seconds between requests, for rate limiting verify_tls: true # set false for an intercepting proxy or self-signed certs llm: provider: "openrouter" attacker_model: "z-ai/glm-5.2" scanner: budget: 60 # the most steps a scan takes; each step is one model call and at most one request safe_mode: false # one switch to disable the destructive techniques attacks: # turn individual techniques on or off injection: true ssrf: true dos: false # resource exhaustion, off by default because it can knock a target over jwt: true bola: true # systematic BOLA/BFLA testing across identities oob: { enabled: true, provider: "interactsh", collaborator_domain: "oast.fun" } ``` `http` 块通过代理路由流量并设置超时和速率限制,`safe_mode` 和 `attacks` 映射控制单个技术,而 `config/settings.yaml` 记录了每个字段及其 默认值。 为了访问经过身份验证的对象(这也是破坏对象级授权等漏洞所在 之处),扫描器需要一个会话。你可以通过在 `target.headers` 中放入有效的 token 来 提供一个会话,或者你也可以让它通过使用 `temp_mail` 操作的注册、电子邮件确认和登录流程自行获取一个。 ## 输出 扫描器写入的所有内容都位于被 git 忽略的 `output/` 目录下: - `agent_trace_.jsonl` 和匹配的 `.md` 文件,在开启 `--trace` 时写入。每个 步骤记录了发送给模型的确切 prompt、原始回复、解析出的操作、 反馈回来的观察结果以及状态快照。`.md` 文件是可读版本。 - `vuln_stream.jsonl`,保存了发现的结果。它们在确认后即被写入,因此在运行过程中如果发生 崩溃也不会丢失它们。 ## 测试说明 ``` python -m pytest -q ``` 测试套件速度很快,并且完全离线运行。 ## 限制 没有授权门槛,这是故意设计的。范围界定是你的责任,因此在运行任何内容之前,请阅读 顶部的注意事项。 运行结果不是确定性的。由于由模型驱动,因此对同一目标进行两次扫描的结果将有所不同,并且 能否发现漏洞取决于模型能否通过推理找到它。 某些模型拒绝攻击命名的活跃域名。发生这种情况时,运行将在几次 拒绝后停止,而不是耗尽所有预算。 ## 作者信息 本项目由在人类指导下的 Claude 编写。由人类设定目标、审查 输出并决定最终发布的内容,但大部分代码、测试和文档均由该模型生成。 ## 许可证 MIT。请参阅 LICENSE 文件。
标签:CISA项目, GraphQL, Python, 人工智能, 凭据扫描, 无后门, 用户模式Hook绕过, 逆向工具