Podstawy skryptów shell #2
Napisał: Patryk Krawaczyński
11/06/2017 w Bezpieczeństwo Brak komentarzy. (artykuł nr 617, ilość słów: 434)
W
drugiej części naszej serii zajmiemy się atakami na katalogi, które są dostępne do zapisu dla wszystkich użytkowników. Pliki znajdujące się w tych katalogach podatne są na atak polegający na możliwości zastąpienia ich innym, “złośliwym” plikiem, który skrypt zamierza odczytać lub zapisać.
Atak na pliki tymczasowe
Za przykład posłuży nam skrypt, który przechowuje poufne informacje w tymczasowym pliku:
#!/bin/bash TAJNE_DANE="Man is obsolete!" echo > /tmp/tajnedane chmod og-rwx /tmp/tajnedane echo "$TAJNE_DANE" >> /tmp/tajnedane
Przy takich założeniach wystarczy, że napiszemy lub wykorzystamy narzędzie, które będzie nasłuchiwało się na pojawienie pliku /tmp/tajnedane
. Po wychwyceniu takiego zdarzenia, jeśli atakującemu uda się otworzyć plik przed tym, jak skrypt wykona polecenie chmod (patrz: TOCTTOU) to będzie w stanie odczytywać dane z tego pliku i tym samym poznać zawartość zmiennej TAJNE_DANE.
Aby uniknąć powyższej sytuacji powinniśmy rozważyć, co najmniej dwie zmiany. Po pierwsze – zawsze używać odpowiedniej maski przy tworzeniu pliku (umask). Po drugie – przy tworzeniu pliku użyliśmy przewidywalnej jego nazwy. Zamiast tego, możemy wykorzystać polecenie mktemp, które utworzy nam nowy plik według określonego szablonu i upewniając się, że żaden plik lub link symboliczny już z taką nazwą nie istnieje.
#!/bin/bash TAJNE_DANE="Man is obsolete!" umask 0177 PLIK_TEMP="$(mktemp /tmp/tajnedane.XXXXXX)" echo "$TAJNE_DANE" >> "$PLIK_TEMP"
Jednak przy założeniu, że zapisane dane w pliku zamierzamy wykorzystać w innym skrypcie to takie podejście jest niewystarczające. Powody opisuje kolejny typ ataku.
Atak na pliki wejściowe
Rozważmy skrypt, który przyjmuje jako dane wejściowe zawartość pliku:
#!/bin/bash echo "Charlie. Alfa. Brawo." > /temp/danepubliczne ... DANE_PUBLICZNE="$(cat /temp/danepubliczne)" echo "$DANE_PUBLICZNE" | nc 192.168.1.10 31337
Po stworzeniu pliku tymczasowego skrypt wyśle jego zawartość na port 31337 innego serwera o adresie IP 192.168.1.10 za pomocą narzędzia netcat. Ponownie oczekujemy na pojawienie się pliku /temp/danepubliczne
. Jeśli po jego utworzeniu będziemy w stanie wykonać polecenia:
rm /temp/danepubliczne ln /tmp/tajnedane /temp/danepubliczne
zanim skrypt odczyta zawartość pliku to nasze “tajne dane” z poprzedniego skryptu zostaną wysłane zamiast “publicznych” z aktualnego. W dodatku stanie się to w czystej postaci. Dlatego, jeśli atakujący będzie w stanie podsłuchać ruch sieciowy odbywający się porcie 31337 wówczas przechwyci te informacje.
Złagodzenie tych podatności jest szczególnie kłopotliwe, ponieważ narzędzia stworzone dla systemów z rodziny *nix w sposób naturalny podążają za (sym)linkami (patrz: wyjątek). Jednym z sposobów na rozwiązanie tego problemu jest unikanie zapisywania plików w katalogach publicznego dostępu. Jeśli musimy już to robić wykorzystajmy także polecenie mktemp
do tworzenia katalogów wewnątrz. W ten sposób będziemy w stanie ustawić na tyle restrykcyjne prawa dostępu do naszego katalogu, aby atakujący nie był w stanie usunąć, zmodyfikować, ani odczytać naszych plików:
#!/bin/bash umask 0177 KAT_TEMP="$(mktemp -d /temp/temp_kat.XXXXXX)" echo "Charlie. Alfa. Brawo." > "$KAT_TEMP"/danepubliczne ... DANE_PUBLICZNE="$(cat "$KAT_TEMP"/danepubliczne)" echo "$DANE_PUBLICZNE" | nc 192.168.1.10 31337
Więcej informacji: Safely Creating Temporary Files in Shell Scripts