diff --git a/network-services-pentesting/pentesting-web/graphql.md b/network-services-pentesting/pentesting-web/graphql.md index aa92d392c..e23a250c2 100644 --- a/network-services-pentesting/pentesting-web/graphql.md +++ b/network-services-pentesting/pentesting-web/graphql.md @@ -185,7 +185,7 @@ Se l'introspezione è abilitata, è possibile utilizzare [**GraphQL Voyager**](h ### Interrogazione -Ora che sappiamo che tipo di informazioni sono salvate all'interno del database, proviamo a **estraire alcuni valori**. +Ora che sappiamo che tipo di informazioni sono salvate nel database, proviamo a **estraire alcuni valori**. Nell'introspezione è possibile trovare **quali oggetti è possibile interrogare direttamente** (perché non è possibile interrogare un oggetto solo perché esiste). Nell'immagine seguente è possibile vedere che il "_queryType_" si chiama "_Query_" e che uno dei campi dell'oggetto "_Query_" è "_flags_", che è anch'esso un tipo di oggetto. Pertanto è possibile interrogare l'oggetto flag. @@ -199,7 +199,7 @@ Si noti che il tipo della query "_flags_" è "_Flags_", e che questo oggetto è ```javascript query={flags{name, value}} ``` -Nota che nel caso in cui l'**oggetto da interrogare** sia di **tipo primitivo** come una **stringa** come nell'esempio seguente +Nota che nel caso in cui l'**oggetto da interrogare** sia di **tipo primitivo** come **stringa** come nell'esempio seguente ![](<../../.gitbook/assets/image (958).png>) @@ -212,7 +212,7 @@ Se questi oggetti non hanno bisogno di alcun argomento per la ricerca, è possib ![](<../../.gitbook/assets/image (880).png>) -Tuttavia, in questo esempio se si tenta di farlo si riceve questo **errore**: +Tuttavia, in questo esempio se si tenta di farlo si riceverà questo **errore**: ![](<../../.gitbook/assets/image (1042).png>) @@ -226,7 +226,7 @@ Quindi, facendo un leggero _**uid**_ bruteforce ho scoperto che con _**uid**=**1 ![](<../../.gitbook/assets/image (90).png>) -Nota che ho **scoperto** di poter richiedere i **parametri** "_**user**_" e "_**password**_" perché se cerco qualcosa che non esiste (`query={user(uid:1){noExists}}`) ottengo questo errore: +Nota che ho **scoperto** di poter chiedere i **parametri** "_**user**_" e "_**password**_" perché se cerco qualcosa che non esiste (`query={user(uid:1){noExists}}`) ottengo questo errore: ![](<../../.gitbook/assets/image (707).png>) @@ -238,7 +238,7 @@ Se è possibile cercare per tipo stringa, come: `query={theusers(description: "" ### Ricerca -In questa configurazione, un **database** contiene **persone** e **film**. Le **persone** sono identificate dalla loro **email** e dal loro **nome**; i **film** dal loro **nome** e dal loro **rating**. Le **persone** possono essere amiche tra loro e avere anche film, indicando relazioni all'interno del database. +In questa configurazione, un **database** contiene **persone** e **film**. Le **persone** sono identificate dalla loro **email** e dal loro **nome**; i **film** dal loro **nome** e dal loro **rating**. Le **persone** possono essere amici tra loro e avere anche film, indicando relazioni all'interno del database. È possibile **cercare** le persone **per** il **nome** e ottenere le loro email: ```javascript @@ -298,7 +298,7 @@ name ``` ### Mutazioni -**Le mutazioni sono utilizzate per apportare modifiche lato server.** +**Le mutazioni vengono utilizzate per apportare modifiche lato server.** Nell'**ispezione** è possibile trovare le **mutazioni** **dichiarate**. Nell'immagine seguente il "_MutationType_" è chiamato "_Mutation_" e l'oggetto "_Mutation_" contiene i nomi delle mutazioni (come "_addPerson_" in questo caso): @@ -317,7 +317,7 @@ rating } } ``` -**Nota come sia i valori che il tipo di dati siano indicati nella query.** +**Nota come nella query siano indicati sia i valori che il tipo di dati.** Inoltre, il database supporta un'operazione di **mutazione**, chiamata `addPerson`, che consente la creazione di **persone** insieme alle loro associazioni con **amici** e **film** esistenti. È fondamentale notare che gli amici e i film devono esistere nel database prima di poterli collegare alla persona appena creata. ```javascript @@ -349,12 +349,12 @@ releaseYear ``` ### Sovraccarico della direttiva -Come spiegato in [**uno dei vuln descritti in questo report**](https://www.landh.tech/blog/20240304-google-hack-50000/), un sovraccarico della direttiva implica la chiamata di una direttiva anche milioni di volte per far perdere al server operazioni fino a quando è possibile effettuare un attacco DoS. +Come spiegato in [**uno dei vuln descritti in questo report**](https://www.landh.tech/blog/20240304-google-hack-50000/), un sovraccarico della direttiva implica la chiamata di una direttiva anche milioni di volte per far perdere operazioni al server fino a quando è possibile effettuare un attacco DoS. ### Forza bruta batch in 1 richiesta API Questa informazione è stata presa da [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\ -Autenticazione tramite API GraphQL con **invio simultaneo di molte query con credenziali diverse** per verificarla. Si tratta di un classico attacco di forza bruta, ma ora è possibile inviare più di una coppia login/password per richiesta HTTP a causa della funzionalità di batching di GraphQL. Questo approccio ingannerebbe le applicazioni esterne di monitoraggio dei tassi facendo loro credere che tutto vada bene e che non ci sia un bot di forza bruta che cerca di indovinare le password. +Autenticazione tramite API GraphQL con **invio simultaneo di molte query con credenziali diverse** per verificarla. Si tratta di un attacco di forza bruta classico, ma ora è possibile inviare più di una coppia login/password per richiesta HTTP a causa della funzionalità di batching di GraphQL. Questo approccio ingannerebbe le applicazioni esterne di monitoraggio dei tassi facendo loro credere che tutto va bene e che non c'è un bot di forza bruta che cerca di indovinare le password. Di seguito puoi trovare la dimostrazione più semplice di una richiesta di autenticazione dell'applicazione, con **3 diverse coppie di email/password alla volta**. Ovviamente è possibile inviarne migliaia in una singola richiesta allo stesso modo: @@ -382,11 +382,37 @@ Per eludere le restrizioni sulle query di introspezione nelle API, inserire un * {queryType{name}}}" } ``` -Se non avete successo, considerate metodi di richiesta alternativi, come le **richieste GET** o **POST con `x-www-form-urlencoded`**, poiché le restrizioni potrebbero applicarsi solo alle richieste POST. +Se non avete successo, considerate metodi di richiesta alternativi, come le **richieste GET** o **POST con `x-www-form-urlencoded`**, poiché le restrizioni potrebbero essere applicate solo alle richieste POST. -### **Scoperta delle Strutture GraphQL Esposte** +### Provare i WebSockets -Quando l'introspezione è disabilitata, esaminare il codice sorgente del sito web per le query pre-caricate nelle librerie JavaScript è una strategia utile. Queste query possono essere trovate utilizzando la scheda `Sources` negli strumenti per sviluppatori, fornendo approfondimenti dello schema dell'API e rivelando potenzialmente **query sensibili esposte**. I comandi per cercare all'interno degli strumenti per sviluppatori sono: +Come menzionato in [**questa presentazione**](https://www.youtube.com/watch?v=tIo\_t5uUK50), verificate se è possibile connettersi a graphQL tramite WebSockets poiché potrebbe consentire di aggirare un potenziale WAF e far sì che la comunicazione tramite websocket faccia trapelare lo schema del graphQL: +```javascript +ws = new WebSocket('wss://target/graphql', 'graphql-ws'); +ws.onopen = function start(event) { +var GQL_CALL = { +extensions: {}, +query: ` +{ +__schema { +_types { +name +} +} +}` +} + +var graphqlMsg = { +type: 'GQL.START', +id: '1', +payload: GQL_CALL, +}; +ws.send(JSON.stringify(graphqlMsg)); +} +``` +### **Scoperta delle strutture GraphQL esposte** + +Quando l'introspezione è disabilitata, esaminare il codice sorgente del sito web per le query pre-caricate nelle librerie JavaScript è una strategia utile. Queste query possono essere trovate utilizzando la scheda `Sources` negli strumenti per sviluppatori, fornendo approfondimenti sullo schema dell'API e rivelando potenzialmente **query sensibili esposte**. I comandi per cercare all'interno degli strumenti per sviluppatori sono: ```javascript Inspect/Sources/"Search all files" file:* mutation @@ -400,7 +426,7 @@ Se non sai cos'è il CSRF leggi la seguente pagina: [csrf-cross-site-request-forgery.md](../../pentesting-web/csrf-cross-site-request-forgery.md) {% endcontent-ref %} -Lì fuori sarai in grado di trovare diversi endpoint GraphQL **configurati senza token CSRF.** +Qui fuori sarai in grado di trovare diversi endpoint GraphQL **configurati senza token CSRF.** Nota che le richieste GraphQL di solito vengono inviate tramite richieste POST utilizzando il Content-Type **`application/json`**. ```javascript @@ -416,15 +442,25 @@ Tuttavia, nota che il nuovo valore predefinito del cookie del flag `samesite` di Tieni presente che di solito è possibile inviare la **richiesta** **query** anche come una **richiesta GET e il token CSRF potrebbe non essere convalidato in una richiesta GET.** -Inoltre, sfruttando un [attacco **XS-Search**](../../pentesting-web/xs-search/) potrebbe essere possibile esfiltrare contenuti dall'endpoint GraphQL abusando delle credenziali dell'utente. +Inoltre, abusando di un [**attacco XS-Search**](../../pentesting-web/xs-search/) potrebbe essere possibile esfiltrare contenuti dal punto finale GraphQL abusando delle credenziali dell'utente. -Per ulteriori informazioni, **controlla il** [**post originale qui**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html). +Per ulteriori informazioni **controlla il** [**post originale qui**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html). + +## Dirottamento WebSocket tra siti in GraphQL + +Analogamente alle vulnerabilità CRSF che abusano di GraphQL, è anche possibile eseguire un **dirottamento WebSocket tra siti per abusare di un'**autenticazione con GraphQL con cookie non protetti** e far sì che un utente compia azioni inaspettate in GraphQL. + +Per ulteriori informazioni controlla: + +{% content-ref url="../../pentesting-web/websocket-attacks.md" %} +[websocket-attacks.md](../../pentesting-web/websocket-attacks.md) +{% endcontent-ref %} ## Autorizzazione in GraphQL -Molte funzioni GraphQL definite sull'endpoint potrebbero controllare solo l'autenticazione del richiedente ma non l'autorizzazione. +Molte funzioni GraphQL definite sul punto finale potrebbero controllare solo l'autenticazione del richiedente ma non l'autorizzazione. -La modifica delle variabili di input della query potrebbe portare a dettagli sensibili dell'account [**leaked**](https://hackerone.com/reports/792927). +La modifica delle variabili di input della query potrebbe portare a dettagli sensibili dell'account [**esposti**](https://hackerone.com/reports/792927). La mutazione potrebbe addirittura portare al furto dell'account cercando di modificare altri dati dell'account. ```javascript @@ -436,19 +472,19 @@ La mutazione potrebbe addirittura portare al furto dell'account cercando di modi ``` ### Bypass dell'autorizzazione in GraphQL -[Concatenare le query](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) insieme può eludere un sistema di autenticazione debole. +[Concatenare le query](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) insieme può bypassare un sistema di autenticazione debole. -Nell'esempio seguente puoi vedere che l'operazione è "forgotPassword" e che dovrebbe eseguire solo la query forgotPassword associata ad essa. Questo può essere eluso aggiungendo una query alla fine, in questo caso aggiungiamo "register" e una variabile utente per far registrare il sistema come nuovo utente. +Nell'esempio seguente puoi vedere che l'operazione è "forgotPassword" e che dovrebbe eseguire solo la query forgotPassword associata ad essa. Questo può essere bypassato aggiungendo una query alla fine, in questo caso aggiungiamo "register" e una variabile utente per far registrare il sistema come nuovo utente.
-## Eludere i limiti di velocità utilizzando Alias in GraphQL +## Bypass dei limiti di velocità utilizzando Alias in GraphQL -In GraphQL, gli alias sono una funzionalità potente che consente di **denominare esplicitamente le proprietà** durante una richiesta API. Questa capacità è particolarmente utile per recuperare **più istanze dello stesso tipo** di oggetto in una singola richiesta. Gli alias possono essere utilizzati per superare il limite che impedisce agli oggetti GraphQL di avere più proprietà con lo stesso nome. +In GraphQL, gli alias sono una funzionalità potente che consente di **denominare esplicitamente le proprietà** durante una richiesta API. Questa capacità è particolarmente utile per recuperare **più istanze dello stesso tipo** di oggetto all'interno di una singola richiesta. Gli alias possono essere utilizzati per superare il limite che impedisce agli oggetti GraphQL di avere più proprietà con lo stesso nome. Per una comprensione dettagliata degli alias in GraphQL, si consiglia la seguente risorsa: [Alias](https://portswigger.net/web-security/graphql/what-is-graphql#aliases). -Sebbene lo scopo principale degli alias sia ridurre la necessità di numerose chiamate API, è stato identificato un caso d'uso non intenzionale in cui gli alias possono essere sfruttati per eseguire attacchi brute force su un endpoint GraphQL. Questo è possibile perché alcuni endpoint sono protetti da limitatori di velocità progettati per contrastare gli attacchi brute force limitando il **numero di richieste HTTP**. Tuttavia, questi limitatori di velocità potrebbero non considerare il numero di operazioni all'interno di ciascuna richiesta. Poiché gli alias consentono l'inclusione di più query in una singola richiesta HTTP, possono aggirare tali misure di limitazione della velocità. +Sebbene lo scopo principale degli alias sia ridurre la necessità di numerose chiamate API, è stato identificato un caso d'uso non intenzionale in cui gli alias possono essere sfruttati per eseguire attacchi brute force su un endpoint GraphQL. Questo è possibile perché alcuni endpoint sono protetti da limitatori di velocità progettati per contrastare gli attacchi brute force limitando il **numero di richieste HTTP**. Tuttavia, questi limitatori potrebbero non considerare il numero di operazioni all'interno di ciascuna richiesta. Dato che gli alias consentono l'inclusione di più query in una singola richiesta HTTP, possono aggirare tali misure di limitazione della velocità. Considera l'esempio fornito di seguito, che illustra come le query con alias possono essere utilizzate per verificare la validità dei codici sconto del negozio. Questo metodo potrebbe eludere i limiti di velocità poiché combina diverse query in una singola richiesta HTTP, consentendo potenzialmente la verifica di numerosi codici sconto contemporaneamente. ```bash @@ -475,8 +511,10 @@ valid * [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Toolkit che può essere utilizzato per ottenere schemi e cercare dati sensibili, testare l'autorizzazione, forzare gli schemi e trovare percorsi per un dato tipo. * [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html): Può essere utilizzato come standalone o [estensione Burp](https://github.com/doyensec/inql). * [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): Può essere utilizzato anche come client CLI per automatizzare gli attacchi -* [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): Strumento che elenca i diversi modi per raggiungere un dato tipo in uno schema GraphQL. -* [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Estensione Burp per test GraphQL avanzati. Il _**Scanner**_ è il nucleo di InQL v5.0, dove è possibile analizzare un endpoint GraphQL o un file di schema di introspezione locale. Genera automaticamente tutte le query e le mutazioni possibili, organizzandole in una vista strutturata per la tua analisi. Il componente _**Attacker**_ ti consente di eseguire attacchi batch GraphQL, che possono essere utili per aggirare limiti di velocità implementati in modo non corretto. +* [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): Strumento che elenca i diversi modi per **raggiungere un dato tipo in uno schema GraphQL**. +* [https://github.com/doyensec/GQLSpection](https://github.com/doyensec/GQLSpection): Il successore delle modalità Standalone e CLI di InQL +* [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Estensione Burp per test avanzati di GraphQL. Il _**Scanner**_ è il nucleo di InQL v5.0, dove è possibile analizzare un endpoint GraphQL o un file di schema di introspezione locale. Genera automaticamente tutte le query e le mutazioni possibili, organizzandole in una vista strutturata per la tua analisi. Il componente _**Attacker**_ ti consente di eseguire attacchi batch GraphQL, che possono essere utili per aggirare limiti di velocità implementati in modo non sicuro. +* [https://github.com/nikitastupin/clairvoyance](https://github.com/nikitastupin/clairvoyance): Prova a ottenere lo schema anche con l'introspezione disabilitata utilizzando l'aiuto di alcuni database Graphql che suggeriranno i nomi delle mutazioni e dei parametri. ### Client @@ -507,7 +545,7 @@ Altri modi per supportare HackTricks: * Se vuoi vedere la tua **azienda pubblicizzata in HackTricks** o **scaricare HackTricks in PDF** Controlla i [**PIANI DI ABBONAMENTO**](https://github.com/sponsors/carlospolop)! * Ottieni il [**merchandising ufficiale PEASS & HackTricks**](https://peass.creator-spring.com) -* Scopri [**The PEASS Family**](https://opensea.io/collection/the-peass-family), la nostra collezione di esclusivi [**NFT**](https://opensea.io/collection/the-peass-family) +* Scopri [**La Famiglia PEASS**](https://opensea.io/collection/the-peass-family), la nostra collezione di esclusive [**NFT**](https://opensea.io/collection/the-peass-family) * **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Condividi i tuoi trucchi di hacking inviando PR a** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.