Podstawy skryptów shell #5
Napisał: Patryk Krawaczyński
13/07/2019 w Bezpieczeństwo Brak komentarzy. (artykuł nr 700, ilość słów: 488)
W
tej części zajmiemy się ścieżkami, do których odwołują się nasze skrypty. Na przykładzie z aktualnie używanego systemu operacyjnego Ubuntu w wersji 18.04.X LTS przeanalizujemy proste błędy, które mogą doprowadzić do innych problemów z działaniem oraz bezpieczeństwem. Pierwszym błędem jest zapisywanie różnych danych do tymczasowych katalogów pod przewidywalnymi nazwami plików. Musimy mieć świadomość, że do tymczasowych katalogów mają dostęp wszyscy użytkownicy systemu – dlatego działanie w ich obrębie musi być bardzo przemyślane w stosunku do danych, jakie chcemy w nich umieszczać (możemy porównać to do tłumu, który patrzy na wszystko, co robimy). Nawet, jeśli chodzi o proste mechanizmy sprawdzające, czy inny proces skrypty już nie jest uruchomiony.
Jeśli prześledzimy działanie dwóch skryptów: /bin/znew
, /bin/bzexe
z pakietów: gzip (1.6-5ubuntu1
) oraz bzip2 (1.0.6-8.1
) to odkryjemy, że jeden z nich odwołuje się do ścieżki znajdującej się w katalogu /tmp
:
root@darkstar:~# strace znew --help ... stat("/tmp/zfoo.1051", 0x7fffe0c49310) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/tmp/zfoo.1051", O_WRONLY|O_CREAT|O_EXCL, 0666) = 3 ...
a drugi natomiast do bieżącego katalogu:
root@darkstar:~# strace bzexe --help ... stat("zfoo11063", 0x7ffe7085a250) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "zfoo11063", O_WRONLY|O_CREAT|O_EXCL, 0666) = 3 ... stat("zfoo21063", 0x7ffe7085a250) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "zfoo21063", O_WRONLY|O_CREAT|O_EXCL, 0666) = 3 ...
Z kodu możemy wyczytać, że format szukanych plików to w rzeczywistości wyrażenie zfoo + PID, aktualnie odpalonego skryptu:
tmp=${TMPDIR-/tmp}/zfoo.$$ echo hi > zfoo1$$ || exit 1 echo hi > zfoo2$$ || exit 1
Są to bardzo proste nazwy plików, które można bardzo łatwo przewidzieć. Jeśli z poziomu innego użytkownika wygenerujemy teraz wszystkie możliwe ich warianty – możemy doprowadzić do zablokowania działania skryptu:
agresor@stardust:~$ cat /proc/sys/kernel/pid_max 32768 agresor@stardust:~$ for i in {0..32768}; do touch /tmp/zfoo.$i; done root@stardust:~# znew --help /bin/znew: 64: /bin/znew: cannot create /tmp/zfoo.1458: File exists
To samo będzie tyczyć się skryptu bzexe, jeśli dany użytkownik zdecyduje się go wykonać będąc aktualnie w katalogu /tmp
. Bardziej bezpieczniejszą wersją by było użycie polecenia: mktemp:
root@stardust:~# tmp=$(mktemp /tmp/zfoo.XXXXXXXXXXXXXXXXXXXX) root@stardust:~# echo $tmp /tmp/zfoo.J0zNQl8EnbpWHelp6M8J
A jeszcze lepszym – stworzenie własnej przestrzeni w katalogu tymczasowym, do której nikt oprócz aktualnie uruchamianego procesu nie będzie miał dostępu:
root@stardust:~# tmpdir=$(mktemp -d /tmp/XXXXXXXXXXXXXXXX) root@stardust:~# tmp=$(mktemp $tmpdir/zfoo.XXXXXXXXXXXXXXXXXXXX) root@stardust:~# echo $tmp /tmp/P1IGE19vcT1P5zge/zfoo.9xUKB4JEy8dlEqn8RGvt root@stardust:~# cd /tmp/P1IGE19vcT1P5zge root@stardust:/tmp/P1IGE19vcT1P5zge# ls -al total 892 drwx------ 2 root root 4096 Jul 13 12:07 . drwxrwxrwt 11 root root 905216 Jul 13 12:06 .. -rw------- 1 root root 0 Jul 13 12:07 zfoo.9xUKB4JEy8dlEqn8RGvt
Bonus:
Czy uruchamianie różnych programów będąc aktualnie w katalogach z dostępem dla wszystkich jest bezpieczne? Z poziomu zwykłego użytkownika w katalogu /tmp stwórzmy specjalny plik:
agresor@stardust:~$ touch /tmp/mandb_nfmt agresor@stardust:~$ chmod 755 /tmp/mandb_nfmt
Teraz z poziomu administratora wydajmy dwa razy to samo polecenie (man-db: 2.8.3-2ubuntu0.1
). Pierwszy raz będąc w własnym katalogu domowym oraz drugi raz będąc w katalogu /tmp:
root@stardust:~# man man root@stardust:~# cd /tmp root@stardust:/tmp# man man
Czy wynik polecenia był ten sam? Wersją dla Ubuntu 16.04.X LTS będzie:
root@stardust:~# cat > mandb_nfmt <<EOF #!/bin/sh echo 'Pwn3d!' EOF root@stardust:~# chmod a+x mandb_nfmt root@stardust:~# mv mandb_nfmt /usr/share/man/ agresor@stardust:~$ touch /tmp/mandb_nfmt agresor@stardust:~$ chmod 755 /tmp/mandb_nfmt root@stardust:~# man man root@stardust:~# cd /tmp root@stardust:/tmp# man man
Więcej informacji: Looks for files “mandb_nfmt” and “-” (in the current directory)