Parameter Pollution | JSON Injection

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

HTTP Parameter Pollution (HPP) — Panoramica

HTTP Parameter Pollution (HPP) è una tecnica in cui gli attaccanti manipolano i parametri HTTP per cambiare il comportamento di un’applicazione web in modi non intenzionati. Questa manipolazione avviene aggiungendo, modificando o duplicando parametri HTTP. L’effetto di queste manipolazioni non è direttamente visibile all’utente ma può alterare significativamente la funzionalità dell’applicazione lato server, con impatti osservabili sul client.

Esempio di HTTP Parameter Pollution (HPP)

Un URL di transazione di un’app bancaria:

  • Original URL: https://www.victim.com/send/?from=accountA&to=accountB&amount=10000

Inserendo un ulteriore parametro from:

  • Manipulated URL: https://www.victim.com/send/?from=accountA&to=accountB&amount=10000&from=accountC

La transazione potrebbe essere addebitata in modo errato su accountC invece che su accountA, dimostrando il potenziale dell’HPP per manipolare transazioni o altre funzionalità come reset della password, impostazioni 2FA o richieste di API key.

Parsing dei parametri specifico per tecnologia

  • Il modo in cui i parametri vengono analizzati e prioritizzati dipende dalla tecnologia web sottostante, influenzando come HPP può essere sfruttato.
  • Strumenti come Wappalyzer aiutano a identificare queste tecnologie e i loro comportamenti di parsing.

PHP e HPP: Sfruttamento

Caso di manipolazione OTP:

  • Contesto: È stato sfruttato un meccanismo di login che richiedeva una One-Time Password (OTP).
  • Metodo: Intercettando la richiesta OTP usando strumenti come Burp Suite, gli attaccanti duplicarono il parametro email nella richiesta HTTP.
  • Esito: L’OTP, destinata all’email iniziale, venne invece inviata al secondo indirizzo email specificato nella richiesta manipolata. Questa falla permise accessi non autorizzati bypassando la misura di sicurezza prevista.

Questo scenario evidenzia una criticità nel backend dell’applicazione, che ha processato il primo parametro email per la generazione dell’OTP ma ha usato l’ultimo per la consegna.

Caso di manipolazione API Key:

  • Scenario: Un’applicazione permette agli utenti di aggiornare la loro API key tramite una pagina di impostazioni del profilo.
  • Vettore di attacco: Un attaccante scopre che aggiungendo un ulteriore parametro api_key alla richiesta POST può manipolare l’esito della funzione di aggiornamento della API key.
  • Tecnica: Utilizzando uno strumento come Burp Suite, l’attaccante costruisce una richiesta che include due parametri api_key: uno legittimo e uno malevolo. Il server, processando solo l’ultima occorrenza, aggiorna la API key con il valore fornito dall’attaccante.
  • Risultato: L’attaccante ottiene il controllo sulla funzionalità API della vittima, potendo potenzialmente accedere o modificare dati privati senza autorizzazione.

Questo esempio sottolinea ulteriormente la necessità di una gestione sicura dei parametri, specialmente in funzionalità critiche come la gestione delle API key.

Parsing dei parametri: Flask vs. PHP

Il modo in cui le tecnologie web gestiscono parametri HTTP duplicati varia, influenzando la loro suscettibilità agli attacchi HPP:

  • Flask: Adotta il primo valore del parametro incontrato, come a=1 in una query string a=1&a=2, dando priorità all’istanza iniziale rispetto ai duplicati successivi.
  • PHP (on Apache HTTP Server): Al contrario, dà priorità all’ultimo valore del parametro, scegliendo a=2 nell’esempio dato. Questo comportamento può facilitare involontariamente gli exploit HPP onorando il parametro manipolato dall’attaccante rispetto all’originale.

Note di test HPP (OWASP WSTG)

  • Gli standard HTTP non definiscono come interpretare parametri multipli con lo stesso nome, quindi il comportamento varia tra stack e componenti.
  • Quando si testa HPP lato server, duplicare ogni parametro nelle query string o nei body e osservare se l’applicazione concatena i valori, usa il primo/ultimo o genera errori.
  • Per HPP lato client, iniettare un & codificato in URL in un valore di parametro riflesso (es., %26HPP_TEST) e cercare occorrenze decodificate come &HPP_TEST o &HPP_TEST all’interno di link generati o action di form.

Server-Side Parameter Pollution (SSPP) nelle API interne

Alcune applicazioni inseriscono input utente in richieste server-side verso API interne. Se quell’input non è correttamente codificato, è possibile iniettare o sovrascrivere parametri nella richiesta interna. Testare qualsiasi input utente, inclusi query parameter, campi form, header e parametri nel path dell’URL.

Probe comuni:

  • Aggiungere un nuovo parametro con %26 (URL-encoded &).
  • Troncare la query downstream con %23 (URL-encoded #).
  • Sovrascrivere un parametro esistente duplicandolo.

Esempio:

GET /userSearch?name=peter%26name=carlos&back=/home

Potenzialmente genera una server-side request come:

GET /users/search?name=peter&name=carlos&publicProfile=true

Parameter pollution by technology

I risultati sono tratti da https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89

PHP 8.3.11 AND Apache 2.4.62

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*l_Pf2JNCYhmfAvfk7UTEbQ.jpeg

  1. Ignora tutto ciò che segue %00 nel nome del parametro .
  2. Tratta name[] come array .
  3. _GET non significa il metodo GET .
  4. Preferisce l’ultimo parametro .

Ruby 3.3.5 and WEBrick 1.8.2

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kKxtZ8qEmgTIMS81py5hhg.jpeg

  1. Usa i delimitatori & e ; per separare i parametri .
  2. Non riconosce name[] .
  3. Preferisce il primo parametro .

Spring MVC 6.0.23 AND Apache Tomcat 10.1.30

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*llG22MF1gPTYZYFVCmCiVw.jpeg

  1. POST RequestMapping == PostMapping & GET RequestMapping == GetMapping .
  2. POST RequestMapping & PostMapping riconoscono name[] .
  3. Preferisce name se name AND name[] esistono .
  4. Concatena i parametri, es. first,last .
  5. POST RequestMapping & PostMapping riconoscono parametri di query con Content-Type .

NodeJS 20.17.0 AND Express 4.21.0

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg

  1. Riconosce name[] .
  2. Concatena i parametri, es. first,last .

GO 1.22.7

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NVvN1N8sL4g_Gi796FzlZA.jpeg

  1. Non riconosce name[] .
  2. Preferisce il primo parametro .

Python 3.12.6 AND Werkzeug 3.0.4 AND Flask 3.0.3

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Se5467PFFjIlmT3O7KNlWQ.jpeg

  1. Non riconosce name[] .
  2. Preferisce il primo parametro .

Python 3.12.6 AND Django 4.2.15

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rf38VXut5YhAx0ZhUzgT8Q.jpeg

  1. Non riconosce name[] .
  2. Preferisce l’ultimo parametro .

Python 3.12.6 AND Tornado 6.4.1

https://miro.medium.com/v2/resize:fit:1100/format:webp/1*obCn7xahDc296JZccXM2qQ.jpeg

  1. Non riconosce name[] .
  2. Preferisce l’ultimo parametro .

JSON Injection

JSON, XML and YAML Hacking

Chiavi duplicate

obj = {"test": "user", "test": "admin"}

Il front-end potrebbe ritenere valida la prima occorrenza mentre il backend utilizza la seconda occorrenza della chiave.

Key Collision: Troncamento dei Caratteri e Commenti

Alcuni caratteri non verranno interpretati correttamente dal frontend ma il backend li interpreterà e userà quelle chiavi, questo potrebbe essere utile per bypass certain restrictions:

{"test": 1, "test\[raw \x0d byte]": 2}
{"test": 1, "test\ud800": 2}
{"test": 1, "test"": 2}
{"test": 1, "te\st": 2}

Nota come in questi casi il front end potrebbe pensare che test == 1 e il backend penserà che test == 2.

Questo può anche essere usato per aggirare restrizioni sui valori come:

{"role": "administrator\[raw \x0d byte]"}
{"role":"administrator\ud800"}
{"role": "administrator""}
{"role": "admini\strator"}

Uso del troncamento dei commenti

obj = {"description": "Duplicate with comments", "test": 2, "extra": /*, "test": 1, "extra2": */}

Qui useremo il serializer di ciascun parser per vedere il relativo output.

Serializer 1 (e.g., GoLang’s GoJay library) produrrà:

  • description = "Duplicate with comments"
  • test = 2
  • extra = ""

Serializer 2 (e.g., Java’s JSON-iterator library) produrrà:

  • description = "Duplicate with comments"
  • extra = "/*"
  • extra2 = "*/"
  • test = 1

In alternativa, l’uso diretto di commenti può essere efficace:

obj = {"description": "Comment support", "test": 1, "extra": "a"/*, "test": 2, "extra2": "b"*/}

La libreria GSON di Java:

{ "description": "Comment support", "test": 1, "extra": "a" }

La libreria simdjson di Ruby:

{ "description": "Comment support", "test": 2, "extra": "a", "extra2": "b" }

Precedenza incoerente: Deserialization vs. Serialization

obj = {"test": 1, "test": 2}

obj["test"] // 1
obj.toString() // {"test": 2}

Float and Integer

Il numero

999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

può essere decodificato in più rappresentazioni, tra cui:

999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9.999999999999999e95
1E+96
0
9223372036854775807

Ciò potrebbe creare incoerenze

Riferimenti

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks