hacktricks/pentesting-web/cache-deception/README.md

272 lines
21 KiB
Markdown
Raw Normal View History

# Cache Poisoning i Cache Deception
{% hint style="success" %}
Ucz się i ćwicz Hacking AWS:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Wsparcie HackTricks</summary>
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
</details>
{% endhint %}
<figure><img src="../../.gitbook/assets/image (48).png" alt=""><figcaption></figcaption></figure>
\
Użyj [**Trickest**](https://trickest.com/?utm\_source=hacktricks\&utm\_medium=text\&utm\_campaign=ppc\&utm\_term=trickest\&utm\_content=cache-deception), aby łatwo budować i **automatyzować przepływy pracy** zasilane przez **najbardziej zaawansowane** narzędzia społecznościowe na świecie.\
Uzyskaj dostęp już dziś:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=cache-deception" %}
## Różnica
> **Jaka jest różnica między zatruciem pamięci podręcznej a oszustwem pamięci podręcznej?**
>
> * W **zatruciu pamięci podręcznej** atakujący powoduje, że aplikacja przechowuje w pamięci podręcznej złośliwą zawartość, a ta zawartość jest serwowana z pamięci podręcznej innym użytkownikom aplikacji.
> * W **oszustwie pamięci podręcznej** atakujący powoduje, że aplikacja przechowuje w pamięci podręcznej wrażliwą zawartość należącą do innego użytkownika, a następnie atakujący odzyskuje tę zawartość z pamięci podręcznej.
## Zatrucie pamięci podręcznej
Zatrucie pamięci podręcznej ma na celu manipulację pamięcią podręczną po stronie klienta, aby zmusić klientów do ładowania zasobów, które są nieoczekiwane, częściowe lub pod kontrolą atakującego. Zakres wpływu zależy od popularności dotkniętej strony, ponieważ skażona odpowiedź jest serwowana wyłącznie użytkownikom odwiedzającym stronę w okresie skażenia pamięci podręcznej.
Wykonanie ataku zatrucia pamięci podręcznej obejmuje kilka kroków:
1. **Identyfikacja niekluczowych wejść**: Są to parametry, które, chociaż nie są wymagane do zbuforowania żądania, mogą zmieniać odpowiedź zwracaną przez serwer. Identyfikacja tych wejść jest kluczowa, ponieważ mogą być wykorzystywane do manipulacji pamięcią podręczną.
2. **Wykorzystanie niekluczowych wejść**: Po zidentyfikowaniu niekluczowych wejść, kolejnym krokiem jest ustalenie, jak niewłaściwie wykorzystać te parametry, aby zmodyfikować odpowiedź serwera w sposób korzystny dla atakującego.
3. **Zapewnienie, że skażona odpowiedź jest buforowana**: Ostatnim krokiem jest upewnienie się, że zmanipulowana odpowiedź jest przechowywana w pamięci podręcznej. W ten sposób każdy użytkownik uzyskujący dostęp do dotkniętej strony podczas skażenia pamięci podręcznej otrzyma skażoną odpowiedź.
### Odkrycie: Sprawdź nagłówki HTTP
Zazwyczaj, gdy odpowiedź została **przechowywana w pamięci podręcznej**, będzie **nagłówek to wskazujący**, możesz sprawdzić, na które nagłówki powinieneś zwrócić uwagę w tym poście: [**Nagłówki pamięci podręcznej HTTP**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers).
### Odkrycie: Kody błędów pamięci podręcznej
Jeśli myślisz, że odpowiedź jest przechowywana w pamięci podręcznej, możesz spróbować **wysłać żądania z błędnym nagłówkiem**, na które powinno być odpowiedziane **kodem statusu 400**. Następnie spróbuj uzyskać dostęp do żądania normalnie, a jeśli **odpowiedź to kod statusu 400**, wiesz, że jest podatne (a nawet możesz przeprowadzić DoS).
Możesz znaleźć więcej opcji w:
{% content-ref url="cache-poisoning-to-dos.md" %}
[cache-poisoning-to-dos.md](cache-poisoning-to-dos.md)
{% endcontent-ref %}
Jednak zauważ, że **czasami te rodzaje kodów statusu nie są buforowane**, więc ten test może nie być wiarygodny.
### Odkrycie: Identyfikacja i ocena niekluczowych wejść
Możesz użyć [**Param Miner**](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943), aby **bruteforce'ować parametry i nagłówki**, które mogą **zmieniać odpowiedź strony**. Na przykład, strona może używać nagłówka `X-Forwarded-For`, aby wskazać klientowi załadowanie skryptu stamtąd:
```markup
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
```
### Wywołaj szkodliwą odpowiedź z serwera zaplecza
Zidentyfikowany parametr/nagłówek sprawdź, jak jest **sanitizowany** i **gdzie** jest **odzwierciedlany** lub wpływa na odpowiedź z nagłówka. Czy możesz to w jakiś sposób wykorzystać (wykonać XSS lub załadować kontrolowany przez siebie kod JS? wykonać DoS?...)
### Uzyskaj odpowiedź w pamięci podręcznej
Gdy już **zidentyfikujesz** **stronę**, którą można wykorzystać, który **parametr**/**nagłówek** użyć i **jak** go **wykorzystać**, musisz uzyskać stronę w pamięci podręcznej. W zależności od zasobu, który próbujesz umieścić w pamięci podręcznej, może to zająć trochę czasu, możesz musieć próbować przez kilka sekund.
Nagłówek **`X-Cache`** w odpowiedzi może być bardzo przydatny, ponieważ może mieć wartość **`miss`**, gdy żądanie nie zostało zapisane w pamięci podręcznej, oraz wartość **`hit`**, gdy jest w pamięci podręcznej.\
Nagłówek **`Cache-Control`** jest również interesujący, aby wiedzieć, czy zasób jest buforowany i kiedy będzie następny raz buforowany: `Cache-Control: public, max-age=1800`
Innym interesującym nagłówkiem jest **`Vary`**. Ten nagłówek jest często używany do **wskazywania dodatkowych nagłówków**, które są traktowane jako **część klucza pamięci podręcznej**, nawet jeśli normalnie nie są kluczowane. Dlatego, jeśli użytkownik zna `User-Agent` ofiary, którą celuje, może zanieczyścić pamięć podręczną dla użytkowników korzystających z tego konkretnego `User-Agent`.
Jeszcze jednym nagłówkiem związanym z pamięcią podręczną jest **`Age`**. Określa czas w sekundach, przez jaki obiekt był w pamięci podręcznej proxy.
Podczas buforowania żądania, bądź **ostrożny z nagłówkami, których używasz**, ponieważ niektóre z nich mogą być **używane w sposób nieoczekiwany** jako **kluczowane**, a **ofiara będzie musiała użyć tego samego nagłówka**. Zawsze **testuj** zanieczyszczenie pamięci podręcznej za pomocą **różnych przeglądarek**, aby sprawdzić, czy działa.
## Przykłady wykorzystania
### Najprostszy przykład
Nagłówek taki jak `X-Forwarded-For` jest odzwierciedlany w odpowiedzi bez sanitizacji.\
Możesz wysłać podstawowy ładunek XSS i zanieczyścić pamięć podręczną, aby każdy, kto uzyska dostęp do strony, został zaatakowany XSS:
```markup
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"
```
_Note that this will poison a request to `/en?region=uk` not to `/en`_
### Cache poisoning to DoS
{% content-ref url="cache-poisoning-to-dos.md" %}
[cache-poisoning-to-dos.md](cache-poisoning-to-dos.md)
{% endcontent-ref %}
### Wykorzystanie zatrucia pamięci podręcznej do wykorzystania luk w obsłudze ciasteczek
Ciasteczka mogą być również odzwierciedlane w odpowiedzi strony. Jeśli możesz to wykorzystać do spowodowania XSS, na przykład, możesz być w stanie wykorzystać XSS w kilku klientach, które ładują złośliwą odpowiedź z pamięci podręcznej.
```markup
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
```
Note that if the vulnerable cookie is very used by the users, regular requests will be cleaning the cache.
### Generating discrepancies with delimiters, normalization and dots <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
Sprawdź:
{% content-ref url="cache-poisoning-via-url-discrepancies.md" %}
[cache-poisoning-via-url-discrepancies.md](cache-poisoning-via-url-discrepancies.md)
{% endcontent-ref %}
### Cache poisoning with path traversal to steal API key <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
[**Ten opis wyjaśnia**](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html) jak możliwe było skradzenie klucza API OpenAI za pomocą URL-a takiego jak `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123`, ponieważ wszystko, co pasuje do `/share/*`, będzie buforowane bez normalizacji URL przez Cloudflare, co miało miejsce, gdy żądanie dotarło do serwera webowego.
To jest również lepiej wyjaśnione w:
{% content-ref url="cache-poisoning-via-url-discrepancies.md" %}
[cache-poisoning-via-url-discrepancies.md](cache-poisoning-via-url-discrepancies.md)
{% endcontent-ref %}
### Using multiple headers to exploit web cache poisoning vulnerabilities <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
Czasami będziesz musiał **wykorzystać kilka niekluczowanych wejść**, aby móc nadużyć pamięci podręcznej. Na przykład, możesz znaleźć **otwarty przekierowanie**, jeśli ustawisz `X-Forwarded-Host` na domenę kontrolowaną przez Ciebie i `X-Forwarded-Scheme` na `http`. **Jeśli** **serwer** **przekazuje** wszystkie **żądania HTTP** **do HTTPS** i używa nagłówka `X-Forwarded-Scheme` jako nazwy domeny dla przekierowania. Możesz kontrolować, gdzie strona jest skierowana przez przekierowanie.
```markup
GET /resources/js/tracking.js HTTP/1.1
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
X-Forwarded-Host: ac8e1f8f1fb1f8cb80586c1d01d500d3.web-security-academy.net/
X-Forwarded-Scheme: http
```
### Wykorzystywanie z ograniczonym nagłówkiem `Vary`
Jeśli odkryłeś, że nagłówek **`X-Host`** jest używany jako **nazwa domeny do ładowania zasobu JS**, ale nagłówek **`Vary`** w odpowiedzi wskazuje na **`User-Agent`**. W takim przypadku musisz znaleźć sposób na wyekstrahowanie User-Agent ofiary i zanieczyszczenie pamięci podręcznej przy użyciu tego user agenta:
```markup
GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com
```
### Fat Get
Wyślij żądanie GET z żądaniem w URL i w ciele. Jeśli serwer WWW używa tego z ciała, ale serwer cache'ujący przechowuje to z URL, każdy, kto uzyskuje dostęp do tego URL, faktycznie użyje parametru z ciała. Jak w przypadku luki, którą znalazł James Kettle na stronie Github:
```
GET /contact/report-abuse?report=albinowax HTTP/1.1
Host: github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
report=innocent-victim
```
There it a portswigger lab about this: [https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get)
### Parameter Cloacking
Na przykład, możliwe jest oddzielenie **parametrów** na serwerach ruby za pomocą znaku **`;`** zamiast **`&`**. Może to być użyte do umieszczania wartości parametrów bez kluczy wewnątrz tych z kluczami i ich nadużywania.
Portswigger lab: [https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking)
### Exploiting HTTP Cache Poisoning by abusing HTTP Request Smuggling
Dowiedz się tutaj, jak przeprowadzać [ataki Cache Poisoning, nadużywając HTTP Request Smuggling](../http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-poisoning).
### Automated testing for Web Cache Poisoning
[Web Cache Vulnerability Scanner](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner) może być użyty do automatycznego testowania pod kątem web cache poisoning. Obsługuje wiele różnych technik i jest wysoce konfigurowalny.
Przykład użycia: `wcvs -u example.com`
## Vulnerable Examples
### Apache Traffic Server ([CVE-2021-27577](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-27577))
ATS przesłał fragment w URL bez jego usuwania i wygenerował klucz cache tylko przy użyciu hosta, ścieżki i zapytania (ignorując fragment). Tak więc żądanie `/#/../?r=javascript:alert(1)` zostało wysłane do backendu jako `/#/../?r=javascript:alert(1)` i klucz cache nie zawierał ładunku, tylko host, ścieżkę i zapytanie.
### GitHub CP-DoS
Wysłanie złej wartości w nagłówku content-type spowodowało wyzwolenie odpowiedzi 405 w cache. Klucz cache zawierał ciasteczko, więc możliwe było zaatakowanie tylko użytkowników nieautoryzowanych.
### GitLab + GCP CP-DoS
GitLab używa koszy GCP do przechowywania treści statycznych. **GCP Buckets** obsługują **nagłówek `x-http-method-override`**. Możliwe było więc wysłanie nagłówka `x-http-method-override: HEAD` i zanieczyszczenie cache, aby zwrócił pustą treść odpowiedzi. Mogło to również wspierać metodę `PURGE`.
### Rack Middleware (Ruby on Rails)
W aplikacjach Ruby on Rails często wykorzystywane jest middleware Rack. Celem kodu Rack jest pobranie wartości nagłówka **`x-forwarded-scheme`** i ustawienie go jako schematu żądania. Gdy nagłówek `x-forwarded-scheme: http` jest wysyłany, następuje przekierowanie 301 do tej samej lokalizacji, co potencjalnie może spowodować Denial of Service (DoS) dla tego zasobu. Dodatkowo, aplikacja może uznawać nagłówek `X-forwarded-host` i przekierowywać użytkowników do określonego hosta. To zachowanie może prowadzić do ładowania plików JavaScript z serwera atakującego, co stanowi zagrożenie dla bezpieczeństwa.
### 403 and Storage Buckets
Cloudflare wcześniej cache'ował odpowiedzi 403. Próba dostępu do S3 lub Azure Storage Blobs z niepoprawnymi nagłówkami autoryzacji skutkowała odpowiedzią 403, która była cache'owana. Chociaż Cloudflare przestał cache'ować odpowiedzi 403, to zachowanie może nadal występować w innych usługach proxy.
### Injecting Keyed Parameters
Cache często zawiera konkretne parametry GET w kluczu cache. Na przykład, Varnish Fastly cache'ował parametr `size` w żądaniach. Jednak jeśli wysłano również URL-encoded wersję parametru (np. `siz%65`) z błędną wartością, klucz cache byłby skonstruowany przy użyciu poprawnego parametru `size`. Jednak backend przetwarzałby wartość w URL-encoded parametrze. URL-encoding drugiego parametru `size` prowadził do jego pominięcia przez cache, ale jego wykorzystania przez backend. Przypisanie wartości 0 do tego parametru skutkowało błędem 400 Bad Request, który można było cache'ować.
### User Agent Rules
Niektórzy deweloperzy blokują żądania z user-agentami odpowiadającymi narzędziom o dużym ruchu, takim jak FFUF czy Nuclei, aby zarządzać obciążeniem serwera. Ironią jest to, że podejście to może wprowadzać luki, takie jak cache poisoning i DoS.
### Illegal Header Fields
[RFC7230](https://datatracker.ietf.mrg/doc/html/rfc7230) określa akceptowalne znaki w nazwach nagłówków. Nagłówki zawierające znaki spoza określonego zakresu **tchar** powinny idealnie wyzwalać odpowiedź 400 Bad Request. W praktyce serwery nie zawsze przestrzegają tego standardu. Znaczącym przykładem jest Akamai, które przesyła nagłówki z nieprawidłowymi znakami i cache'uje każdy błąd 400, o ile nagłówek `cache-control` nie jest obecny. Zidentyfikowano wzorzec, w którym wysłanie nagłówka z nielegalnym znakiem, takim jak `\`, skutkowało cache'owalnym błędem 400 Bad Request.
### Finding new headers
[https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6](https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6)
## Cache Deception
Celem Cache Deception jest sprawienie, aby klienci **ładowali zasoby, które będą zapisywane przez cache z ich wrażliwymi informacjami**.
Przede wszystkim zauważ, że **rozszerzenia** takie jak `.css`, `.js`, `.png` itp. są zazwyczaj **konfigurowane** do **zapisywania** w **cache.** Dlatego, jeśli uzyskasz dostęp do `www.example.com/profile.php/nonexistent.js`, cache prawdopodobnie zapisze odpowiedź, ponieważ widzi rozszerzenie `.js`. Ale, jeśli **aplikacja** odpowiada **wrażliwymi** treściami użytkownika przechowywanymi w _www.example.com/profile.php_, możesz **ukraść** te treści od innych użytkowników.
Inne rzeczy do przetestowania:
* _www.example.com/profile.php/.js_
* _www.example.com/profile.php/.css_
* _www.example.com/profile.php/test.js_
* _www.example.com/profile.php/../test.js_
* _www.example.com/profile.php/%2e%2e/test.js_
* _Użyj mniej znanych rozszerzeń, takich jak_ `.avif`
Inny bardzo jasny przykład można znaleźć w tym opisie: [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712).\
W przykładzie wyjaśniono, że jeśli załadujesz nieistniejącą stronę, taką jak _http://www.example.com/home.php/non-existent.css_, treść _http://www.example.com/home.php_ (**z wrażliwymi informacjami użytkownika**) zostanie zwrócona, a serwer cache zapisze wynik.\
Następnie **atakujący** może uzyskać dostęp do _http://www.example.com/home.php/non-existent.css_ w swojej przeglądarce i obserwować **poufne informacje** użytkowników, którzy uzyskali dostęp wcześniej.
Zauważ, że **cache proxy** powinno być **skonfigurowane** do **cache'owania** plików **na podstawie** **rozszerzenia** pliku (_.css_) a nie na podstawie content-type. W przykładzie _http://www.example.com/home.php/non-existent.css_ będzie miało `text/html` content-type zamiast `text/css` mime type (co jest oczekiwane dla pliku _.css_).
Dowiedz się tutaj, jak przeprowadzać [ataki Cache Deceptions, nadużywając HTTP Request Smuggling](../http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-deception).
## Automatic Tools
* [**toxicache**](https://github.com/xhzeem/toxicache): skaner Golang do znajdowania luk w web cache poisoning w liście URL i testowania wielu technik wstrzykiwania.
## References
* [https://portswigger.net/web-security/web-cache-poisoning](https://portswigger.net/web-security/web-cache-poisoning)
* [https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities](https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities)
* [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712)
* [https://youst.in/posts/cache-poisoning-at-scale/](https://youst.in/posts/cache-poisoning-at-scale/)
* [https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9](https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9)
* [https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/](https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/)
<figure><img src="../../.gitbook/assets/image (48).png" alt=""><figcaption></figcaption></figure>
\
Użyj [**Trickest**](https://trickest.com/?utm\_source=hacktricks\&utm\_medium=text\&utm\_campaign=ppc\&utm\_term=trickest\&utm\_content=cache-deception), aby łatwo budować i **automatyzować przepływy pracy** zasilane przez **najbardziej zaawansowane** narzędzia społeczności.\
Uzyskaj dostęp już dziś:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=cache-deception" %}
{% hint style="success" %}
Ucz się i ćwicz Hacking AWS:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Wsparcie HackTricks</summary>
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się trikami hackingowymi, przesyłając PR do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
</details>
{% endhint %}