Tym razem nie będziemy przyglądać się konkretnemu językowi programowania, a linuxowej funkcji służącej do wypakowania plików, a konkretniej o unzip
1.
Dlaczego taki temat?
Czasami wymagania biznesowe sprawiają, że musimy dodać obsługę archiwów do naszego serwisu internetowego.
Mogą to być pliki zip
, rar
czy też tar
.
Załóżmy hipotetyczną sytuację: prowadzimy serwis, w którym można tworzyć galerie.
Użytkownik ma możliwość wysyłania zdjęć na nasz serwer. Może to robić pojedynczo - czyli po jednym pliku na raz.
Jeżeli jednak tych plików jest więcej, na przykład 100, najprostszym rozwiązaniem z punktu widzenia użyteczności było by spakowanie ich do jednego archiwum i przeslanie ich jako jednego pliku zip
na nasz serwer.
Po naszej stronie następuje wypakowanie tego pliku do tymczasowego katalogu przy użyciu komendy unzip
.
Następnie kopiujemy wszystkie pliki z rozszerzeniem .png
do odpowiednich katalogów i dodajemy je do bazy danych.
Następnie czyścimy dany katalog.
Gdzie czyha niebezpieczeństwo?
W Linuxie oprócz standardowego pliku istnieją symlinki2.
Można je przyrównać do Windowsowych skrótów.
Tworzymy zatem plik skrót.png
, który nie ma własnej treści, tylko odnosi się do jakiegoś innego pliku.
Używamy do tego celu komendy ln
z argumentem s:
ln -s /etc/passwd skrot.png
W naszym wypadku odnosimy się do pliku /etc/passwd
który to zawiera informacje na temat wszystkich kont w danym systemie.
Teraz, jeśli będziemy chcieli wyświetlić zawartość tego pliku, ujrzymy treść /etc/passswd
- bowiem na ten to plik wskazuje dowiązanie symboliczne.
Posiadając już taki plik możemy dodać go do archiwum zip.
Jeśli stworzymy archiwum bez żadnych argumentów przy użyciu komendy zip:
zip archiwum.zip skrot.png
Program przed stworzeniem sprawdzi gdzie prowadzą wszystkie symlinki w danym momencie i do archiwum doda pliki z ich treścią.
My natomiast chcemy aby stworzone zostało archiwum z zachowanymi dowiązaniami, tak aby zostały one rozwiązane na atakowanym serwerze.
Nie chcemy bowiem wysyłać archiwum z plikiem zawierającym nasze dane użytkowników.
Musimy zatem użyć argumentu --symlinks
.
zip --symlinks archiwum.zip skrot.png
Teraz wysyłamy złośliwy plik na serwer.
Tam jest on wypakowywany do tymczasowego katalogu temp:
unzip archiwum.zip -d temp
Kopiujemy teraz wszystkie pliki z rozszerzeniem png
do katalogu serwera.
Jak możesz się spodziewać, jeśli teraz użytkownik będzie chciał zobaczyć ten plik - zamiast jego treści ujrzy zawartość /etc/passwd
.
Jak zatem zabezpieczyć się przed tym atakiem?
Najlepiej korzystać z modułów wypakowywania plików dostępnych w większości języków programowania.
Warto poszukać tam opcji, która wyłączy obsługę dowiązań symbolicznych.
Dodatkowo, przed każdą operacją na wypakowanym pliku warto sprawdzić, czy nie jest to symlink.