Parameter Pollution | JSON Injection

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

HTTP Parameter Pollution (HPP) Overview

HTTP Parameter Pollution (HPP) to technika, w której atakujący manipulują parametrami HTTP, aby zmienić zachowanie aplikacji webowej w niezamierzony sposób. Manipulacja ta polega na dodawaniu, modyfikowaniu lub duplikowaniu parametrów HTTP. Efekt tych manipulacji nie jest bezpośrednio widoczny dla użytkownika, ale może znacząco zmienić funkcjonalność aplikacji po stronie serwera, z zauważalnymi skutkami po stronie klienta.

Example of HTTP Parameter Pollution (HPP)

URL transakcji w aplikacji bankowej:

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

Poprzez dodanie dodatkowego parametru from:

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

Transakcja może zostać błędnie obciążona na accountC zamiast accountA, co pokazuje, jak HPP może manipulować transakcjami lub innymi funkcjonalnościami, takimi jak reset haseł, ustawienia 2FA lub żądania dotyczące API key.

Technology-Specific Parameter Parsing

  • Sposób parsowania i priorytetyzacji parametrów zależy od użytej technologii webowej, co wpływa na to, jak można wykorzystać HPP.
  • Narzędzia takie jak Wappalyzer pomagają zidentyfikować te technologie i ich zachowanie przy parsowaniu parametrów.

PHP and HPP Exploitation

OTP Manipulation Case:

  • Context: Mechanizm logowania wymagający One-Time Password (OTP) został wykorzystany.
  • Method: Poprzez przechwycenie żądania OTP przy użyciu narzędzi takich jak Burp Suite, atakujący zdublowali parametr email w żądaniu HTTP.
  • Outcome: OTP przeznaczone dla pierwszego adresu e-mail zostało wysłane zamiast tego na drugi adres e-mail wskazany w zmanipulowanym żądaniu. Ta luka umożliwiła nieautoryzowany dostęp poprzez obejście zamierzonego zabezpieczenia.

To scenariusz podkreśla krytyczne przeoczenie w backendzie aplikacji, który przetwarzał pierwszy parametr email do wygenerowania OTP, ale używał ostatniego do dostarczenia.

API Key Manipulation Case:

  • Scenario: Aplikacja pozwala użytkownikom zaktualizować API key na stronie ustawień profilu.
  • Attack Vector: Atakujący odkrywa, że poprzez dołączenie dodatkowego parametru api_key do żądania POST, może manipulować wynikiem funkcji aktualizacji API key.
  • Technique: Korzystając z narzędzia takiego jak Burp Suite, atakujący tworzy żądanie zawierające dwa parametry api_key: jeden legalny i jeden złośliwy. Serwer, przetwarzając tylko ostatnie wystąpienie, aktualizuje API key na wartość podaną przez atakującego.
  • Result: Atakujący uzyskuje kontrolę nad funkcjonalnością API ofiary, potencjalnie uzyskując dostęp do prywatnych danych lub je modyfikując bez uprawnień.

Ten przykład dodatkowo podkreśla konieczność bezpiecznego obchodzenia się z parametrami, szczególnie w funkcjach tak krytycznych jak zarządzanie API key.

Parameter Parsing: Flask vs. PHP

Sposób, w jaki technologie webowe obsługują zduplikowane parametry HTTP, różni się i wpływa na ich podatność na ataki HPP:

  • Flask: Przyjmuje pierwszą napotkaną wartość parametru, na przykład a=1 w query stringu a=1&a=2, priorytetyzując pierwszy wystąpienie nad kolejnymi duplikatami.
  • PHP (on Apache HTTP Server): Przeciwnie, priorytetyzuje ostatnią wartość parametru, wybierając a=2 w podanym przykładzie. Takie zachowanie może nieumyślnie ułatwiać eksploatację HPP, honorując zmanipulowany parametr atakującego zamiast oryginalnego.

HPP Testing Notes (OWASP WSTG)

  • Standardy HTTP nie definiują, jak interpretować wiele parametrów o tej samej nazwie, więc zachowanie różni się między stackami i komponentami.
  • Podczas testowania server-side HPP, zduplikuj każdy parametr w query stringach lub w ciałach żądań i obserwuj, czy aplikacja konkatenjuje wartości, używa pierwszej/ostatniej, czy zwraca błąd.
  • Dla client-side HPP, wstrzyknij URL-encoded & w odzwierciedloną wartość parametru (np. %26HPP_TEST) i szukaj zdekodowanych wystąpień takich jak &HPP_TEST lub &HPP_TEST wewnątrz generowanych linków lub akcji formularzy.

Server-Side Parameter Pollution (SSPP) in Internal APIs

Niektóre aplikacje osadzają dane wejściowe użytkownika w żądaniach po stronie serwera do internal APIs. Jeśli te dane nie są prawidłowo zakodowane, można wstrzyknąć lub nadpisać parametry w żądaniu wewnętrznym. Testuj każde dane wejściowe użytkownika, w tym query parameters, pola formularzy, nagłówki i parametry ścieżki URL.

Typowe testy:

  • Dodaj nowy parametr używając %26 (URL-encoded &).
  • Skróć downstream query używając %23 (URL-encoded #).
  • Nadpisz istniejący parametr, duplikując go.

Przykład:

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

Może skutkować żądaniem po stronie serwera takim jak:

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

Parameter pollution by technology

Wyniki pochodzą z 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. Ignoruj wszystko po %00 w nazwie parametru.
  2. Obsługuje name[] jako tablicę.
  3. _GET nie oznacza metody GET.
  4. Preferuje ostatni parametr.

Ruby 3.3.5 and WEBrick 1.8.2

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

  1. Używa delimiterów & oraz ; do rozdzielania parametrów.
  2. Nie rozpoznaje name[].
  3. Preferuje pierwszy parametr.

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 rozpoznają name[].
  3. Preferuje name jeśli name i name[] istnieją.
  4. Łączy parametry np. first,last.
  5. POST RequestMapping & PostMapping rozpoznają query parameter z 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. Rozpoznaje name[].
  2. Łączy parametry np. first,last.

GO 1.22.7

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

  1. Nie rozpoznaje name[].
  2. Preferuje pierwszy parametr.

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. Nie rozpoznaje name[].
  2. Preferuje pierwszy parametr.

Python 3.12.6 AND Django 4.2.15

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

  1. Nie rozpoznaje name[].
  2. Preferuje ostatni parametr.

Python 3.12.6 AND Tornado 6.4.1

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

  1. Nie rozpoznaje name[].
  2. Preferuje ostatni parametr.

JSON Injection

JSON, XML and YAML Hacking

Duplikaty kluczy

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

Front-end może uwierzyć pierwszemu wystąpieniu, podczas gdy backend użyje drugiego wystąpienia klucza.

Key Collision: Character Truncation and Comments

Niektóre znaki nie będą poprawnie interpretowane przez frontend, ale backend je zinterpretuje i użyje tych kluczy, co może być przydatne do obejścia pewnych ograniczeń:

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

Zauważ, że w tych przypadkach front end może uważać, że test == 1, a backend będzie uważać, że test == 2.

Może to być również użyte do bypass ograniczeń wartości, takich jak:

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

Korzystanie z Comment Truncation

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

Tutaj użyjemy serializera z każdego parsera, aby zobaczyć odpowiadające im wyjścia.

Serializator 1 (np. GoLang’s GoJay library) wygeneruje:

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

Serializator 2 (np. Java’s JSON-iterator library) wygeneruje:

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

Alternatywnie, proste użycie komentarzy może być również skuteczne:

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

Biblioteka GSON w Javie:

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

Biblioteka simdjson dla Ruby:

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

Niespójne priorytety: Deserialization vs. Serialization

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

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

Liczby zmiennoprzecinkowe i całkowite

Liczba

999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

może zostać zdekodowany do wielu reprezentacji, w tym:

999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9.999999999999999e95
1E+96
0
9223372036854775807

Co może powodować niespójności

References

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks