漏洞赏金猎人笔记-GraphQL-IV

admin 2023年1月3日11:02:01安全文章评论9 views6024字阅读20分4秒阅读模式

漏洞赏金猎人笔记-GraphQL-IV

声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。

前言

前文有: 漏洞赏金猎人笔记-GraphQL-III , 漏洞赏金猎人笔记-GraphQL-II, 漏洞赏金猎人笔记-GraphQL-I

本文继续GraphQL系列,为第四篇

如何识别GraphQL接口

常见的GraphQL接口有:

/graphql
/graphql/console
/graphql.php
/graphiql.php
/explorer
/altair
/playground

Fuzzing

常用的字典有:

https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/graphql.txt

可以使用FFUF:

ffuf -w graphql.txt -u https://target/FUZZ 

Nuclei

可以使用Nuclei来检测GraphQL接口

模板可以使用如下:

https://github.com/projectdiscovery/nuclei-templates/blob/master/technologies/graphql-detect.yaml

#单个目标
nuclei -t graphql-detect.yaml -u https://example.com 

#
 多目标
nuclei -t graphql-detect.yaml -l target_domains.txt 

指纹识别

可以使用: https://github.com/dolevf/graphw00f

python3 main.py -f -d -t http://localhost:5000

同时密切关注 Burp Suite 日志并使用搜索功能查看目标是否使用 graphql

启用内省查询

配置 GraphQL 的一个常见错误是启用了内省查询;

这里简要说一下何为内省查询:

简单来说就是GraphQL内置了接口文档,你可以通过内省的方法获得这些信息,可以通过__schema字段来向GraphQL查询有哪些类型可用,指定类型又有哪些字段,有哪些查询又是可用的

举个例子,查询一下有哪些可用的类型:


{
  __schema {
    types {
      name
    }
  }
}

返回:

{
  "data": {
    "__schema": {
      "types": [
        {
          "name": "Query"
        },
        {
          "name": "String"
        },
        {
          "name": "ID"
        },
        {
          "name": "Mutation"
        },
        {
          "name": "Episode"
        },
        {
          "name": "Character"
        },
        {
          "name": "Int"
        },
        {
          "name": "LengthUnit"
        },
        {
          "name": "Human"
        },
        {
          "name": "Float"
        },
        {
          "name": "Droid"
        },
        {
          "name": "FriendsConnection"
        },
        {
          "name": "FriendsEdge"
        },
        {
          "name": "PageInfo"
        },
        {
          "name": "Boolean"
        },
        {
          "name": "Review"
        },
        {
          "name": "ReviewInput"
        },
        {
          "name": "Starship"
        },
        {
          "name": "SearchResult"
        },
        {
          "name": "__Schema"
        },
        {
          "name": "__Type"
        },
        {
          "name": "__TypeKind"
        },
        {
          "name": "__Field"
        },
        {
          "name": "__InputValue"
        },
        {
          "name": "__EnumValue"
        },
        {
          "name": "__Directive"
        },
        {
          "name": "__DirectiveLocation"
        }
      ]
    }
  }
}

举个例子来说明指定类型又有哪些字段: 这里来问问内省系统 Droid 有哪些字段:

{
  __type(name: "Droid") {
    name
    fields {
      name
      type {
        name
        kind
      }
    }
  }
}

返回:

{
  "data": {
    "__type": {
      "name": "Droid",
      "fields": [
        {
          "name": "id",
          "type": {
            "name": null,
            "kind": "NON_NULL"
          }
        },
        {
          "name": "name",
          "type": {
            "name": null,
            "kind": "NON_NULL"
          }
        },
        {
          "name": "friends",
          "type": {
            "name": null,
            "kind": "LIST"
          }
        },
        {
          "name": "friendsConnection",
          "type": {
            "name": null,
            "kind": "NON_NULL"
          }
        },
        {
          "name": "appearsIn",
          "type": {
            "name": null,
            "kind": "NON_NULL"
          }
        },
        {
          "name": "primaryFunction",
          "type": {
            "name": "String",
            "kind": "SCALAR"
          }
        }
      ]
    }
  }
}

举个例子来说明有哪些可用查询的地方:

{
  __schema {
    queryType {
      name
    }
  }
}

返回:

{
  "data": {
    "__schema": {
      "queryType": {
        "name": "Query"
      }
    }
  }
}

内省查询又会有什么问题?

本来应该是仅允许内部访问,但配置错误导致任何攻击者可以获得这些信息。

如何确定是否启用了内省查询

向GraphQL接口发一个如下POST请求:

{
  __schema{
    queryType
    {
    name
    }
    
    mutationType {
      name
              }
  subscriptionType {
    name 
    }
    
    types{
      ...FullType
      }
      
      directives{
        name 
        description
         locations
          args{
            ...InputValue
            }
            }
        }
  }
        
        fragment FullType on __Type {
          kind 
          name
           description
            fields(includeDeprecated:true){
              name 
              description
               args{
                 ...InputValue
                 }
                 
                 type{
                   ...TypeRef
                   }
                   isDeprecated 
                   deprecationReason
                   }
                   
                   inputFields{
                     ...InputValue
                     }
                     
                     interfaces{
                       ...TypeRef
                       }
                       
                       enumValues(includeDeprecated:true){
                         name 
                         description
                          isDeprecated
                           deprecationReason
                           }
                           
                    possibleTypes{
                      ...TypeRef
                    }
                    }
        fragment InputValue on __InputValue{
          name 
          description
           type{
             ...TypeRef
             }
          defaultValue
          }
          
          
        fragment TypeRef on __Type{
          kind 
          name 
          ofType{
            kind 
            name 
            ofType{
              kind
               name 
               ofType {
                kind
                name
                ofType{
                     kind 
                     name 
                     ofType{
                       kind 
                       name 
                       ofType{
                         kind 
                         name 
                         ofType{
                           kind
                          name
                          }}}}}}}}

如果启用自省,此查询将返回有关 API 架构的所有信息。如果未启用,服务器将返回错误。自省查询响应可能是巨大的不可读的 JSON(类似下图)。

漏洞赏金猎人笔记-GraphQL-IV

这是garphql最常见的一类问题。

参考

https://graphql.cn/learn/introspection/

https://github.com/graphql/graphql-js/blob/main/src/tests/starWarsIntrospection-test.ts

原文始发于微信公众号(迪哥讲事):漏洞赏金猎人笔记-GraphQL-IV

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年1月3日11:02:01
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  漏洞赏金猎人笔记-GraphQL-IV http://cn-sec.com/archives/1495616.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: