The article below is my publication for the Polish IT magazine IT Wiz.
Cisza po burzy?
Wraz z nieustającym rozwojem oprogramowania, rozwija się również jego bezpieczeństwo. Luki o charakterze krytycznym nie pojawiają się już tak często, jak miało to miejsce chociażby dekadę temu. Idąc tym tokiem, dzisiaj administratorzy systemów mogli poniekąd oczekiwać spokojnego zakończenia bieżącego roku – wszak jeszcze niedawno światem wstrząsnął błąd, który dorobił się swojego kryptonimu – Heartbleed. Na krytyczne znaczenie rzeczonego błędu miały wpływ dwa czynniki: po pierwsze, dotyczyło szeroko stosowanej konfiguracji w warstwie szyfrowania, a więc czegoś, co de facto nie służy niczemu innemu – jest narzutem bezpieczeństwa. Po drugie, powszechność implementacji, gdyż dotyczył jednej z popularniejszych wersji szeroko stosowanej biblioteki OpenSSL.
Niestety (albo wręcz przeciwnie), spokojnego końca roku się nie doczekamy. Oto Stephane Chazelas, francuski inżynier informatyki odkrył lukę, która może nie podlega pierwszemu czynnikowi, ale za to można szacować dużo większą podatność, nie mówiąc już o łatwości eksploatacji. Luka dotyczy tym razem powłoki systemowej Bash we wszystkich, aktywnie rozwijanych jej gałęziach. Problem w tym, że właściwie każda dystrybucja systemu Linux stosuje Bash jako domyślną powłokę systemową od wielu lat, w tym urządzenia typu embedded tudzież takie, gdzie Linuksa byśmy się nawet nie spodziewali. O ile w przypadku Heartbleed można było wykraść dane poprzez celowy atak, tak tutaj można spodziewać się powstania skryptów masowo eksploatujących tę podatność z automatu, tworząc pokaźnych rozmiarów botnety. Warto dodać, że botnety na serwerach są dużo potężniejsze z racji często lepszego dostępu do sieci. W tym temacie szeroko już alarmowały media nie-informatyczne, jak chociażby Reuters.
Na czym to polega
Bash, podobnie jak inne powłoki, pozwala na definicje zmiennych środowiskowych. Zmienne takie mogą zawierać definicje funkcji jeśli zaczynają się od ciągu znaków ‘() {‘. Jest to szczególnie przydatne w przypadku wprowadzania funkcji dla innych instancji powłoki w danym systemie, jednak w tym wypadku wiąże sie to z zagrożeniem. Problem w tym, że interpretacja kodu nie kończy się wraz z ostatnią klamrą definicji. Zatem, do skutecznego wykorzystania podatności wystarczy nadpisanie rozpoznawalnej szerzej zmiennej z funkcją poprzez dodanie kodu, który wykona się z takimi uprawnieniami, z jakimi działa instancja powłoki. Błąd ten jest na tyle krytyczny, że dorobił się swojego kryptonimu – Shellshock.
Przecież nie udostępniam shella!
Skala problemu kryje się w mnogości zastosowań. W przypadku Heartbleed było tego sporo – należało namierzyć każdą implementację biblioteki OpenSSL poprzez identyfikację wszelakich urządzeń z możliwością nawiązywania połączeń szyfrowanych. I tak, do typowych ataków na serwery doszły wszelkie klienty VPN, a więc nawet domowe routery i wiele innych urządzeń.
W tym wypadku pracy w namierzaniu ewentualnych wektorów ataku będzie znacznie więcej, ponieważ podatne będzie każde wykorzystanie Basha wiążące się z pracą w środowisku o zdefiniowanych zmiennych z funkcjami. Zatem nie chodzi tylko systemy wielu użytkowników. Podatne są również systemy, gdzie użytkownik nie ma możliwości stworzenia nowych zmiennych środowiskowych! Ataki można przeprowadzać więc pośrednio – poprzez skrypty CGI chociażby, a więc praktycznie każdy serwer http generujący dynamiczne strony, na przykład w PHP. Do tego dochodzą środowiska dla skryptów klientów DHCP, opcja AcceptEnv w OpenSSH tudzież SSH_ORIGINAL_COMMAND a także wszelakie skrypty, które eksportują definicje funkcji, szczególnie z ustawionym SUID.