mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
207 lines
10 KiB
Markdown
207 lines
10 KiB
Markdown
# Zanieczyszczenie parametrów | Wstrzykiwanie JSON
|
|
|
|
{{#include ../banners/hacktricks-training.md}}
|
|
|
|
## Przegląd HTTP Parameter Pollution (HPP)
|
|
|
|
HTTP Parameter Pollution (HPP) to technika, w której atakujący manipulują parametrami HTTP, aby zmienić zachowanie aplikacji internetowej 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.
|
|
|
|
### Przykład HTTP Parameter Pollution (HPP)
|
|
|
|
URL transakcji aplikacji bankowej:
|
|
|
|
- **Oryginalny URL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000`
|
|
|
|
Poprzez dodanie dodatkowego parametru `from`:
|
|
|
|
- **Manipulowany URL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000&from=accountC`
|
|
|
|
Transakcja może być błędnie obciążona na `accountC` zamiast `accountA`, co pokazuje potencjał HPP do manipulacji transakcjami lub innymi funkcjonalnościami, takimi jak resetowanie haseł, ustawienia 2FA czy żądania kluczy API.
|
|
|
|
#### **Specyficzne dla technologii parsowanie parametrów**
|
|
|
|
- Sposób, w jaki parametry są analizowane i priorytetowane, zależy od używanej technologii webowej, co wpływa na to, jak HPP może być wykorzystywane.
|
|
- Narzędzia takie jak [Wappalyzer](https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/) pomagają zidentyfikować te technologie i ich zachowania w zakresie parsowania.
|
|
|
|
### PHP i wykorzystanie HPP
|
|
|
|
**Przypadek manipulacji OTP:**
|
|
|
|
- **Kontekst:** Mechanizm logowania wymagający jednorazowego hasła (OTP) został wykorzystany.
|
|
- **Metoda:** Poprzez przechwycenie żądania OTP za pomocą narzędzi takich jak Burp Suite, atakujący zduplikował parametr `email` w żądaniu HTTP.
|
|
- **Wynik:** OTP, przeznaczone dla początkowego adresu e-mail, zostało zamiast tego wysłane na drugi adres e-mail podany w manipulowanym żądaniu. Ta luka umożliwiła nieautoryzowany dostęp, omijając zamierzony środek bezpieczeństwa.
|
|
|
|
Ten scenariusz podkreśla krytyczne niedopatrzenie w backendzie aplikacji, który przetwarzał pierwszy parametr `email` do generacji OTP, ale używał ostatniego do dostarczenia.
|
|
|
|
**Przypadek manipulacji kluczem API:**
|
|
|
|
- **Scenariusz:** Aplikacja pozwala użytkownikom na aktualizację swojego klucza API poprzez stronę ustawień profilu.
|
|
- **Wektor ataku:** Atakujący odkrywa, że poprzez dodanie dodatkowego parametru `api_key` do żądania POST, mogą manipulować wynikiem funkcji aktualizacji klucza API.
|
|
- **Technika:** Wykorzystując narzędzie takie jak Burp Suite, atakujący tworzy żądanie, które zawiera dwa parametry `api_key`: jeden prawidłowy i jeden złośliwy. Serwer, przetwarzając tylko ostatnie wystąpienie, aktualizuje klucz API na wartość podaną przez atakującego.
|
|
- **Wynik:** Atakujący zyskuje kontrolę nad funkcjonalnością API ofiary, potencjalnie uzyskując dostęp do prywatnych danych lub je modyfikując bez autoryzacji.
|
|
|
|
Ten przykład dodatkowo podkreśla konieczność bezpiecznego zarządzania parametrami, szczególnie w funkcjach tak krytycznych jak zarządzanie kluczem API.
|
|
|
|
### Parsowanie parametrów: Flask vs. PHP
|
|
|
|
Sposób, w jaki technologie webowe obsługują duplikaty parametrów HTTP, różni się, co wpływa na ich podatność na ataki HPP:
|
|
|
|
- **Flask:** Przyjmuje pierwszą wartość parametru, np. `a=1` w ciągu zapytania `a=1&a=2`, priorytetując początkowe wystąpienie nad kolejnymi duplikatami.
|
|
- **PHP (na serwerze Apache HTTP):** Przeciwnie, priorytetowo traktuje ostatnią wartość parametru, wybierając `a=2` w podanym przykładzie. To zachowanie może niezamierzenie ułatwić wykorzystanie HPP, honorując złośliwy parametr atakującego zamiast oryginalnego.
|
|
|
|
## Zanieczyszczenie parametrów według technologii
|
|
|
|
Wyniki zostały zaczerpnięte z [https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89](https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89)
|
|
|
|
### PHP 8.3.11 I Apache 2.4.62 <a href="#id-9523" id="id-9523"></a>
|
|
|
|
<figure><img src="../images/image (1255).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*l_Pf2JNCYhmfAvfk7UTEbQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*l_Pf2JNCYhmfAvfk7UTEbQ.jpeg</a></p></figcaption></figure>
|
|
|
|
1. Ignoruj wszystko po %00 w nazwie parametru.
|
|
2. Obsługuj name\[] jako tablicę.
|
|
3. \_GET nie oznacza metody GET.
|
|
4. Preferuj ostatni parametr.
|
|
|
|
### Ruby 3.3.5 i WEBrick 1.8.2
|
|
|
|
<figure><img src="../images/image (1257).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kKxtZ8qEmgTIMS81py5hhg.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kKxtZ8qEmgTIMS81py5hhg.jpeg</a></p></figcaption></figure>
|
|
|
|
1. Używa & i ; jako separatorów do dzielenia parametrów.
|
|
2. Nie rozpoznaje name\[].
|
|
3. Preferuje pierwszy parametr.
|
|
|
|
### Spring MVC 6.0.23 I Apache Tomcat 10.1.30 <a href="#dd68" id="dd68"></a>
|
|
|
|
<figure><img src="../images/image (1258).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*llG22MF1gPTYZYFVCmCiVw.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*llG22MF1gPTYZYFVCmCiVw.jpeg</a></p></figcaption></figure>
|
|
|
|
1. POST RequestMapping == PostMapping & GET RequestMapping == GetMapping.
|
|
2. POST RequestMapping & PostMapping rozpoznaje name[].
|
|
3. Preferuj name, jeśli name i name[] istnieją.
|
|
4. Łącz parametry, np. first,last.
|
|
5. POST RequestMapping & PostMapping rozpoznaje parametr zapytania z Content-Type.
|
|
|
|
### **NodeJS** 20.17.0 **I** Express 4.21.0 <a href="#id-6d72" id="id-6d72"></a>
|
|
|
|
<figure><img src="../images/image (1259).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg</a></p></figcaption></figure>
|
|
|
|
1. Rozpoznaje name[].
|
|
2. Łącz parametry, np. first,last.
|
|
|
|
### GO 1.22.7 <a href="#id-63dc" id="id-63dc"></a>
|
|
|
|
<figure><img src="../images/image (1260).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NVvN1N8sL4g_Gi796FzlZA.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NVvN1N8sL4g_Gi796FzlZA.jpeg</a></p></figcaption></figure>
|
|
|
|
1. NIE rozpoznaje name[].
|
|
2. Preferuj pierwszy parametr.
|
|
|
|
### Python 3.12.6 I Werkzeug 3.0.4 I Flask 3.0.3 <a href="#b853" id="b853"></a>
|
|
|
|
<figure><img src="../images/image (1261).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Se5467PFFjIlmT3O7KNlWQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Se5467PFFjIlmT3O7KNlWQ.jpeg</a></p></figcaption></figure>
|
|
|
|
1. NIE rozpoznaje name[].
|
|
2. Preferuj pierwszy parametr.
|
|
|
|
### Python 3.12.6 I Django 4.2.15 <a href="#id-8079" id="id-8079"></a>
|
|
|
|
<figure><img src="../images/image (1262).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rf38VXut5YhAx0ZhUzgT8Q.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rf38VXut5YhAx0ZhUzgT8Q.jpeg</a></p></figcaption></figure>
|
|
|
|
1. NIE rozpoznaje name[].
|
|
2. Preferuj ostatni parametr.
|
|
|
|
### Python 3.12.6 I Tornado 6.4.1 <a href="#id-2ad8" id="id-2ad8"></a>
|
|
|
|
<figure><img src="../images/image (1263).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*obCn7xahDc296JZccXM2qQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*obCn7xahDc296JZccXM2qQ.jpeg</a></p></figcaption></figure>
|
|
|
|
1. NIE rozpoznaje name[].
|
|
2. Preferuj ostatni parametr.
|
|
|
|
## Wstrzykiwanie JSON
|
|
|
|
### Duplikaty kluczy
|
|
```ini
|
|
obj = {"test": "user", "test": "admin"}
|
|
```
|
|
Front-end może uwierzyć w pierwsze wystąpienie, podczas gdy backend używa drugiego wystąpienia klucza.
|
|
|
|
### Kolizja kluczy: Skracanie znaków i komentarze
|
|
|
|
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 niektórych ograniczeń**:
|
|
```json
|
|
{"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 frontend może myśleć, że `test == 1`, a backend będzie myślał, że `test == 2`.
|
|
|
|
Może to być również użyte do obejścia ograniczeń wartości, takich jak:
|
|
```json
|
|
{"role": "administrator\[raw \x0d byte]"}
|
|
{"role":"administrator\ud800"}
|
|
{"role": "administrator""}
|
|
{"role": "admini\strator"}
|
|
```
|
|
### **Używanie skracania komentarzy**
|
|
```ini
|
|
obj = {"description": "Duplicate with comments", "test": 2, "extra": /*, "test": 1, "extra2": */}
|
|
```
|
|
Tutaj użyjemy serializatora z każdego parsera, aby zobaczyć jego odpowiedni wynik.
|
|
|
|
Serializer 1 (np. biblioteka GoJay w GoLang) wygeneruje:
|
|
|
|
- `description = "Duplicate with comments"`
|
|
- `test = 2`
|
|
- `extra = ""`
|
|
|
|
Serializer 2 (np. biblioteka JSON-iterator w Javie) wygeneruje:
|
|
|
|
- `description = "Duplicate with comments"`
|
|
- `extra = "/*"`
|
|
- `extra2 = "*/"`
|
|
- `test = 1`
|
|
|
|
Alternatywnie, proste użycie komentarzy może być również skuteczne:
|
|
```ini
|
|
obj = {"description": "Comment support", "test": 1, "extra": "a"/*, "test": 2, "extra2": "b"*/}
|
|
```
|
|
Biblioteka GSON w Javie:
|
|
```json
|
|
{ "description": "Comment support", "test": 1, "extra": "a" }
|
|
```
|
|
Biblioteka simdjson w Ruby:
|
|
```json
|
|
{ "description": "Comment support", "test": 2, "extra": "a", "extra2": "b" }
|
|
```
|
|
### **Niespójna Precedencja: Deserializacja vs. Serializacja**
|
|
```ini
|
|
obj = {"test": 1, "test": 2}
|
|
|
|
obj["test"] // 1
|
|
obj.toString() // {"test": 2}
|
|
```
|
|
### Float i Integer
|
|
|
|
Liczba
|
|
```undefined
|
|
999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
|
```
|
|
może być dekodowane do wielu reprezentacji, w tym:
|
|
```undefined
|
|
999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
|
9.999999999999999e95
|
|
1E+96
|
|
0
|
|
9223372036854775807
|
|
```
|
|
Co może stworzyć niespójności
|
|
|
|
## Referencje
|
|
|
|
- [https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654](https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654)
|
|
- [https://github.com/google/google-ctf/tree/master/2023/web-under-construction/solution](https://github.com/google/google-ctf/tree/master/2023/web-under-construction/solution)
|
|
- [https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89](https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89)
|
|
- [https://bishopfox.com/blog/json-interoperability-vulnerabilities](https://bishopfox.com/blog/json-interoperability-vulnerabilities)
|
|
|
|
|
|
{{#include ../banners/hacktricks-training.md}}
|