GraphQL简介GraphQL 是一种面向数据的 API 查问格调。传统的 API 拿到的是前后端约定好的数据格式,GraphQL 对 API 中的数据提供了一套易于了解的残缺形容,客户端可能精确地取得它须要的数据,没有任何冗余,也让 API 更容易地随着时间推移而演进。RESTful VS GraphQLGraphQL API与Rest API最大的区别在于:GraphQL 通过将数据查问和数据批改拆散开来,使得客户端可能更灵便地管制所需数据的粒度和类型,并且在多个资源之间建设关系。GraphQL只需一次申请就可能获取全副所须要的数据,而不是像RESTful API那样,要想获取所有数据就必须发动屡次API申请。

前置常识GraphQL查问形式GraphQL是一种用于API的查询语言,首先咱们就须要晓得GraphQL有哪些查问形式。次要有:QueryMutationSubscriptionInputEnumUnionInterface其中最为常见的是Query、Mutation、Subscription这三种,Query用于向服务端查问指定数据、Mutation用于在服务端批改或增加数据,具体可参考官网文档进行理解:https://graphql.org/learn/GraphQL内省查问简略来说就是,GraphQL内查机制,通常是外部可用,通过内省的办法取得相干信息,如对象定义、接口参数等信息。个别查问后面带有双下划线的就示意内省的一部分,比方:__Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive等,官网文档:https://graphql.org/learn/introspection/GraphQL API发现当咱们在测试时,如何发现GraphQL API?上面介绍几种无效的办法。常见的GraphQL门路断定GraphQL API与Restful API不同,一般来说它的URL比拟固定,这也是它的个性之一,从单个申请中获取应用程序所需的所有数据。常见的GraphQL门路如下:

/graphql
/graphiql
/v1/graphql
/v2/graphql
/v3/graphql
/v1/graphiql
/v2/graphiql
/v3/graphiql
/api/graphql
/api/graphiql
/graphql/api
/graphql/console
/console
/playground
/gql
/query
/graphql-devtools
/graphql-explorer
/graphql-playground
/graphql.php
/index.php?graphql
......通用查问探测因为GraphQL API中存在一个__typename 的保留字段,该字段会以字符串模式返回查问对象的类型,所以咱们能够向未知API发送query{__typename},如果响应中返回{"data": {"__typename": "query"}},那么就能够确定该API为GraphQL API。

内省查问向未知API发送__schema字段应用自省来发现架构信息,该字段在所有查问的根类型上都可用。query {__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}能够查问到所有类型、字段、参数以及参数类型。

扭转申请办法/报错信息判断利用不同的申请办法(GET、POST)发动申请也可能进行GraphQL API的分别,因为对于一些仅容许某种申请办法的GraphQL API而言,不同的申请办法返回的格局和内容也不同。除此之外,依据报错信息能够判断是否为GraphQL API,次要特色是Syntax Error: Expected Name, found。

GraphQL API攻击面内省查问攻打通过理解GraphQL的内省查问机制,其实咱们能够发现在相干零碎没批改默认配置的状况下,咱们能够通过__schema 或者 __type 等来进行零碎级别的查问,以获取服务器上定义的所有类型、字段、敏感信息等。通过内省查问,咱们获取到零碎所有相干字段及信息,如下图:

而后利用voyager工具将查问后果可视化。

获取数据结构以便进一步利用。

拒绝服务批量查问GraphQL反对申请批处理,并且会对申请一个一个解决,这就导致能够利用批量查问来施行Dos攻打。示例:申请body:
{"query":"query {\n systemUpdate\n}","variables":[]},
{"query": "query {\n systemUpdate\n}","variables":[]},
{"query":"query {\n systemUpdate\n}","variables":[]} 深度递归查问当查问类型互相援用时,通过构建一个循环查问,来实现Dos攻打。query {
Pastes {

Owner {   Pastes {     Owner {       Pastes { 

Owner

        {           Pastes {             Owner {               Pastes {                 Owner {                   Pastes {                     Owner {                       name                     }                   }                 }               } } 

}

            }           }         }       }     }   } }随着查问呈指数级增长,最终导致服务器解体。


字段反复查问因为GraphQL API不会对重读字段进行去重解决,所以还能够通过查问反复字段进行Dos攻打。query {
pastes {

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

}越权查问/信息泄露通过内审查问获取到相干信息后,能够进一步利用,GraphQL API作为单路由API接口在查问过程中往往会疏忽一些鉴权问题,这可能导致越权破绽的呈现,并且泄露敏感信息。例如在查问到存在id参数。

通过批改id参数进行程度越权,获取想要的敏感信息。


命令执行因为GraphQL API没有充沛验证输出或者没有严格过滤,导致在一些查问中能够通过链接的模式拼接 UNIX 命令,达到命令执行的目标。

或者是通过systemDiagnostics承受某些 UNIX 二进制文件作为调试目标的参数,例如 whoami、ps等,在获取相干凭证或者权限之后,能够进行拼接来达到命令执行的目标。

SQL注入GraphQL API同样会可能存在SQL注入破绽,能够对查问构造体中的一些参数进行SQL注入尝试。

这里对“test”参数进行SQL注入尝试。

加上单引号后返回报错信息。

后续间接利用sqlmap进行后续操作。

graphql注入相似于SQL注入拼接字符串,在GraphQL API进行相干查问时,能够通过拼接的形式进行注入来获取数据或者扭转查问逻辑。失常查问:mutation {
create(content: "test", id: 1) {

  name  password  title

}
}graphql注入:mutation {
editPaste(content: "test", id: 1) {

  name  title} changePassword(password: "admin123") {  name  password  title

}
}XSSGraphQL API同样也会蒙受xss攻打,其实针对任何存在零碎而言,如果没有相应的进攻伎俩,没有对输出性参数进行过滤都可能蒙受一些输出型破绽攻打。

攻打载荷胜利解析,此外也能够利用上传性能上传HTML脚本进行攻打测试。

SSRF如果在GraphQL相干查问操作容许本地主机或其余服务器不限度输出,就可能蒙受服务端申请伪造攻打破绽案例:


爱护机制绕过在GrapQL API中如果存在相干歹意输出爱护机制,能够利用批改申请头参数进行绕过。例如上面应用IDE时,进行命令执行时,存在爱护机制。

发现Cookie中存在显著的disable字段。

批改disable为enable。

胜利绕过爱护机制。

登陆爆破在GraphQL API通过能够实现弱明码爆破来碰碰运气,不过还得分无登陆次数限度和有登陆次数限度两种状况。无登陆次数限度如果无登陆次数的限度,间接可进行弱明码爆破。


有登陆次数限度如果一些网站存在登陆次数的限度,比方上面在爆破过程中。

会提醒过多登陆尝试GraphQL对象不可能蕴含多个同名的属性,所以咱们能够利用别名来实现多个同属性的操作,这样如果零碎只限度了API申请速率,那么也能够通过别名查问来实现登陆爆破。


JWT令牌伪造能够通过相干工具获取GraphQL API的数据结构,这里咱们就发现了存在新建用户的操作。

利用这个接口创立一个新用户。

发现登陆操作。

利用新建用户胜利查问到accessToken。

发现能够利用token进行管理员敏感信息查问。

尝试用方才的token进行尝试,发现还是新建用户的信息。

伪造JWT,把新用户的token解析后,批改为admin。

胜利查问到治理账号密码。

目录穿梭/任意文件写入在GraphQL API中相干文件上传/下载操作也可能存在目录穿梭、任意文件读取、任意文件写入等破绽。例如通过目录穿梭胜利任意文件写入。

胜利上传至tmp目录。

工具除了传统的浸透测试工具以外,应用GraphQL API的工具也变得非常重要。inql:GraphQL测试工具, 能够独立应用,也可作为Burp扩大应用,https://github.com/doyensec/inqlvoyager:GraphQL API交互可视化工具,https://github.com/graphql-kit/graphql-voyagerGraphQLmap:GraphQL API浸透测试脚本引擎,https://github.com/swisskyrepo/GraphQLmapgraphiql:基于浏览器的GraphQL IDE工具,https://github.com/graphql/graphiql对于Portal Lab星阑科技 Portal Lab 致力于前沿平安技术钻研及能力工具化。次要钻研方向为数据流动平安、API 平安、利用平安、攻防反抗等畛域。实验室成员研究成果曾发表于BlackHat、HITB、BlueHat、KCon、XCon等国内外出名平安会议,并屡次公布开源平安工具。将来,Portal Lab将持续以凋谢翻新的态度踊跃投入各类平安技术钻研,继续为平安社区及企业级客户提供高质量技术输入。