Uciekinier z zastrzeżonej powłoki
Napisał: Patryk Krawaczyński
18/09/2018 w Bezpieczeństwo, Pen Test Brak komentarzy. (artykuł nr 666, ilość słów: 930)
J
eśli powłoka bash zostanie uruchomiona jako rbash (link symboliczny) lub z opcjami --restricted
lub -r
– to przejdzie w tryb ograniczony. Ograniczona powłoka służy do umieszczania użytkowników w bardziej kontrolowanym środowisku niż jej standardowy wariant. Zachowuje się identycznie jak bash z poniższymi ograniczeniami:
- Zmiana katalogów za pomocą wbudowanego polecenia
cd
, - Ustawienie lub resetowanie zmiennych typu:
SHELL
,PATH
,ENV
lubBASH_ENV
, - Wydawanie poleceń zwierających znaki slash ( “/” ),
- Przekierowywanie danych wyjściowych za pomocą operatorów typu: “>”, “>|”, “<>”, “>&” oraz “>>”,
- Wyłączanie restrykcji zmiennych środowiskowych za pomocą poleceń
'set +r'
lub'set +o'
, - I wiele innych.
Wyobraźmy sobie teraz sytuację, w której chcemy umożliwić normalnemu użytkownikowi tylko wykonywanie konkretnych poleceń w powłoce. Na przykład użytkownik o loginie prisonbreak powinien mieć tylko możliwość wykonywania poleceń typu gzip
oraz gunzip
. Normalny użytkownik powłoki posiada uprawnienia do wykonywania poleceń znajdujących się w ścieżkach /bin
, /usr/bin
oraz /usr/local/bin
. W celu usunięcia tych uprawnień oraz nałożenia restrykcji na użytkownika, aby mógł wykonywać zdefiniowany przez nas zestaw poleceń powinniśmy wykonać mniej więcej następujące kroki:
0. Sprawdzić czy rbash jest dostępna jako powłoka systemu:
root@darkstar:~# ls -al /bin/rbash lrwxrwxrwx 1 root root 4 May 16 2017 /bin/rbash -> bash
Jeśli nie – możemy ją dodać za pomocą polecenia:
ln -s /bin/bash /bin/rbash
lub
cp /bin/bash /bin/rbash
1. Sprawdzić czy rbash jest na liście powłok systemu do wyboru:
root@darkstar:~# cat /etc/shells # /etc/shells: valid login shells /bin/sh /bin/dash /bin/bash /bin/rbash /usr/bin/tmux /usr/bin/screen
Jeśli nie – możemy ją dodać za pomocą polecenia:
echo "/bin/rbash" >> /etc/shells
2. Przypisać powłokę rbash użytkownikowi:
Jeśli jest to nowy użytkownik:
useradd -s /bin/rbash prisonbreak
Jeśli jest to istniejący użytkownik:
usermod -s /bin/rbash prisonbreak
3. Ustawić ścieżkę do wykonywania programów:
Jeśli sprawdzimy ustawienia na tym etapie to prisonbreak nadal może wykonywać wszystkie polecenia umieszczone w systemie m.in. w /usr/local/sbin, /usr/local/bin, /usr/sbin, /usr/bin, /sbin, /bin, /usr/games, /usr/local/games, /snap/bin
. Ścieżki te ustawiane są ze zmiennej środowiskowej $PATH. Zazwyczaj jest ona ustawiana dla użytkownika w pliku .bash_profile
lub .bashrc
(lub globalnie /etc/profile
) . Dla naszego użytkownika plik ten powinien przyjąć wartość:
PATH=$HOME/bin typeset -r PATH export PATH
Od tego momentu użytkownik prisonbreak powinien być zamknięty w środowisku “chroot” nie mogąc wykonywać żadnych programów spoza katalogu domowego /home/prisonbreak/bin
:
prisonbreak@darkstar:~$ w -rbash: /usr/lib/command-not-found: restricted: cannot specify `/' in command names prisonbreak@darkstar:~$ ls -rbash: /usr/lib/command-not-found: restricted: cannot specify `/' in command names
Dalsza konfiguracja środowiska powinna pamiętać o paru rzeczach w innym przypadku istnieje możliwość ucieczki z naszej, zastrzeżonej powłoki.
4. Blokada nadpisania zmiennej środowiskowej $PATH:
Jeśli pozostawimy możliwość nadpisania zmiennej środowiskowej $PATH
– na przykład przez edycję pliku .bash_profile
to użytkownik będzie w stanie zmienić ją na swoją wartość. W celu uniknięcia tego powinniśmy ustawić bit niezmienności na tym pliku:
chattr +i /home/prisonbreak/.bash_profile
5. Blokada zapisu do ścieżki wykonywania programów:
Katalog /home/prisonbreak/bin
powinien być tylko do zapisu przez administratora systemu. W przeciwnym wypadku użytkownik może przekopiować sobie do niego powłokę i ją uruchomić:
prisonbreak@darkstar:~$ cp /bin/sh /home/prisonbreak/bin; sh
Dlatego katalog ten powinien mieć odpowiednie prawa i właścicielstwo:
chmod 755 /home/prisonbreak/bin chown root:root /home/prisonbreak/bin
6. Blokada wykonywania innych poleceń z poziomu SSH:
Jeśli nasz użytkownik prisionbreak łączy się z serwerem za pomocą SSH to powinniśmy zablokować mu możliwość wykonywania innych poleceń niż uruchomienie zastrzeżonej powłoki. Dlaczego? Ponieważ może dojść do sytuacji, w której użytkownik odpali czystą powłokę, która nie załaduje żadnych plików konfiguracyjnych – tym samym omijając wszystkie ograniczenia, jakie dotychczas zostały nałożone:
$ ssh prisonbreak@darkstar.net -t "bash --noprofile --norc"
W tym celu należy skonfigurować SSH, aby umożliwiało naszemu użytkownikowi tylko dostęp do systemu za pomocą klucza, a nie hasła. Przy definicji autoryzowanych kluczy możemy określić, jakie polecenie ma być wykonane przez SSH zaraz po zalogowaniu. Przykładowy wpis w pliku .ssh/authorized_keys
może mieć postać:
command="rbash --rcfile .bash_profile",no-port-forwarding,no-x11-forwarding, no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMRyYZmgfx8xLD9Bx xQU0khTGtZVS6ZJisd/1MGetiokYigwtmeuJfEubHUWjyWXeaFfy20QIeGY0oxYGTB8cPvaDS7r ibHwTSlwndr5KkqtrqL+WIjf0OOEr80dqaGtMmvyFpQFU8Wqhet5lyhmYXoNwP1mhEB3wzanXfu XICgaGAxpqBSBgosqwnwJ9JDqmdq2MBhlnA+NaE+VJ1OK/FrkAf4Vz1GVV6xjK4go4s39b4vHl9 M99jjdY3TxtEfcFE5kk3cZXSyvM8DCK0DHAN9qhN0Pe7qMd9uTcjXIzLtXyH0sTvSYBlTbTT5wk bmgL9/yjPSYp7D4xjpg+P419V rbash_only
Możemy też po prostu za pomocą uprawnień ACL odebrać danemu użytkownikowi prawa do wykonywania powłoki bash (zakładając, że skopiowaliśmy ją pod nazwą rbash, a nie użyliśmy linku symbolicznego):
setfacl -m u:prisonbreak:r /bin/bash
Analogicznie nie powinniśmy udostępniać polecenia ssh samemu użytkownikowi w ograniczonej powłoce. SSH jest dość niebezpiecznym poleceniem, które pozwala niezaufanemu użytkownikowi uruchomić nieograniczoną pod-powłokę. Wystarczy użyć ssh i połączyć się do tego samego serwera z odpowiednim parametrem uruchamiając później odpowiednią sekwencję klawiszy:
prisonbreak@darkstar:~$ printenv SHELL /bin/rbash prisonbreak@darkstar:~$ ssh -o PermitLocalCommand=yes -l prisonbreak localhost prisonbreak@darkstar:~$ [Enter] prisonbreak@darkstar:~$ ~C ssh> !/bin/bash prisonbreak@darkstar:~$ printenv SHELL /bin/bash
7. Ustawienie z góry zmiennych $HISTFILE oraz $HISTSIZE:
Trik jest prosty. Użytkownik za pomocą tych zmiennych może stworzyć dowolny plik i wstrzyknąć do niego dane:
prisonbreak@darkstar:~$ export HISTFILE=evil.sh prisonbreak@darkstar:~$ export HISTSIZE=0 prisonbreak@darkstar:~$ export HISTSIZE=100 prisonbreak@darkstar:~$ #!/bin/sh prisonbreak@darkstar:~$ echo "WTF?" prisonbreak@darkstar:~$ exit prisonbreak@darkstar:~$ cat evil.sh #!/bin/sh echo "WTF?" exit
Dlatego do wcześniej zdefiniowanego pliku .bash_profile należy dodać przykładowe wartości:
PATH=$HOME/bin typeset -r PATH export PATH export HISTFILE=.bash_history typeset -r HISTFILE export HISTSIZE=1000 typeset -r HISTSIZE
Wówczas przy próbie nadpisania zmiennej użytkownik otrzyma komunikat:
prisonbreak@darkstar:~$ export HISTFILE=evil.sh rbash: HISTFILE: readonly variable
8. Ostrożność przy przyznawaniu dostępu do konkretnych programów:
Wcześniejsze założenie przewiduje możliwość korzystania przez użytkownika prisonbreak z programów gzip oraz gunzip. Do osiągnięcia tego celu możemy wykonać linki symboliczne w jego ścieżce dostępu do w/w programów:
ln -s /bin/gzip /home/prisonbreak/bin/gzip ln -s /bin/gunzip /home/prisonbreak/bin/gunzip
Niestety z udostępnianiem programów również należy bardzo uważać. Jak mogliśmy się przekonać w serii “Uciekając z sudo cz. 1, cz. 2, cz. 3” bardzo wiele programów umożliwia ucieczkę do powłoki. Dla przypomnienia kilka z nich:
- ftp (
!/bin/sh
) - gdb (
!/bin/sh
) - more (
!/bin/sh
) - less (
!/bin/sh
) - man (
!/bin/sh
) - vi (
:!/bin/sh
) - find (
/ -name cat -exec /bin/sh \;
) - scp (
-S /tmp/evil.sh x y:
) - awk (
'BEGIN { system("/bin/sh") }'
) - python (
import os; os.system("/bin/sh")
) - php (
exec("sh -i");
) - perl (
-e 'exec "/bin/sh";'
) - lua (
os.execute('/bin/sh')
) - ruby (
exec "/bin/sh"
) - irb (
exec "/bin/sh"
) - git help status (
!/bin/sh
) - nano (
-s "/bin/sh"
) - zip (
/tmp/test.zip /tmp/test -T --unzip-command="sh -c /bin/sh"
) - tar (
cf /dev/null test --checkpoint=1 --checkpoint-action=exec=/bin/sh
) - tee (zastępuje przekierowania strumieni: < / > )
- elinks / lynx / mail / mutt
Więcej informacji: Escape From SHELLcatraz – Breaking Out of Restricted Unix Shells, Linux Restricted Shell Bypass, Shell Escapes