CVE-2014-6271 (shellshock): luka w powłokach Bash, sh i podobnych

Data publikacji: 25/09/2014, Łukasz Siewierski

sasserWczoraj ogłoszono nową podatność: CVE-2014-6271. Podatność ta dotyczy powłok bash, sh, zsh i podobnych oraz pozwala na zdalne wykonanie kodu przy pewnych założeniach, np. przez moduł CGI do serwera Apache. Pomimo, że istnieje poprawka bezpieczeństwa, która rozwiązuje ten błąd, nie jest ona kompletna. Poniżej tłumaczymy na czym polega luka, jak sprawdzić czy jesteśmy podatni i co zrobić, gdy okaże się, że tak jest.

Na czym polega ta luka bezpieczeństwa?

Bash pozwala deklarować i wykonywać funkcje, tak jak na przykładzie poniżej.

$ function funkcja { echo "Hello World!"; }
$ funkcja
Hello World!

Mniej znaną (i wykorzystywaną) funkcjonalnością jest możliwość eksportu zmiennej, która jest funkcją, do powłoki potomnej. W przypadku normalnego działania zmienna funkcja nie będzie widoczna w powłoce potomnej, tak jak na przykładzie poniżej.

$ bash -c 'funkcja'
bash: funkcja: nie znaleziono polecenia

Jednak jeśli wyeksportujemy tę zmienną, polecenie już zadziała.

$ export -f funkcja
$ bash -c 'funkcja'
Hello World!

Ta funkcjonalność jest zaimplementowana dzięki pewnemu obejściu problemu. Każda zmienna, której wartość zaczyna się od () { zostanie potraktowana jak wyeksportowana funkcja. Dlatego można uzyskać powyższy efekt bez eksportowania funkcji, tak jak pokazano poniżej.

$ funkcja='() { echo "Hello World!"; }' bash -c 'funkcja'
Hello World!

Powyższy kod zostanie poprawnie wykonany zarówno na podatnym jak i na niepodatnym systemie. Podejście zaprezentowane wyżej powoduje, że przy każdym wywołaniu powłoki potomnej wywoływana jest również definicja zmiennej funkcja.

Problemy zaczynają się, kiedy na końcu definicji funkcji dodamy jakiś kod. Ten kod zostanie wykonany niezależnie od tego czy wywołamy funkcję czy nie. Przykład takiego polecenia podany jest poniżej.

$ funkcja='() { echo "Hello World!"; }; echo "Goodbye World!"' bash -c ''
Goodbye World!

Na podatnym systemie wynik wykonania będzie taki jak powyżej. Wynika to z faktu, że przy stworzeniu powłoki potomnej zostanie wywołana definicja zmiennej funkcja, która spowoduje zdefiniowanie takiej zmiennej i, jako efekt uboczny, wykonanie kodu, który znajduje się po definicji funkcji.

W powłoce, która nie jest podatna, wykonanie będzie miało inny, zaprezentowany poniżej, efekt.

$ funkcja='() { echo "Hello World!"; }; echo "Goodbye World!"' bash -c ''
bash: warning: funkcja: ignoring function definition attempt
bash: błąd importu definicji funkcji dla `funkcja'

Jednak zaproponowana łata nie jest do końca skuteczna. Ponieważ nie zrezygnowano z przedstawionego tutaj podejścia do deklaracji eksportowanych funkcji, a jedynie usunięto pewne efekty uboczne, wciąż można spróbować wykorzystać wspomnianą lukę. Poniższy kod, pomimo, że nie powinien, to utworzy plik o nazwie test i treści: Still vulnerable.

funkcja='() { (a)%>' bash -c 'test echo "Still vulnerable"'; bash -c ''

W tym przypadku wykorzystujemy fakt, że wartość deklaracji zmiennej funkcja nie jest poprawnie parsowana. Przekierowanie %> nie jest poprawnym poleceniem powłoki.

Aby sprawdzić czy serwer WWW jest podatny, wystarczy wejść na stronę shellshock.brandonpotter.com i postępować zgodnie z zamieszczonymi tam instrukcjami.

Podatne usługi i aplikacje

    W przypadku standardowych systemów z rodziny Linux wykorzystanie tego CVE może nastąpić w kilku, opisanych poniżej, przypadkach.

    • Opcja demona protokołu SSH ForceCommand jest często używana do ograniczenia możliwości wykonania komend zdalnym użytkownikom. Niektóre wdrożenia serwerów Git i Subversion używają tej opcji. Ponieważ wykonanie kodu za definicją funkcji odbywa się z uprawnieniami użytkownika demona SSH, można rozszerzyć zakres wykonywanych poleceń.
    • Moduły serwera Apache mod_cgi czy też mod_cgid używają powłoki do deklaracji zmiennych. W ten sposób tworzą zmienne z np. wartości nagłówków. Przekazując odpowiednio spreparowany nagłówek można wykonać polecenie w kontekście użytkownika serwera Apache.
    • Narzędzia niestandardowe, które wykorzystują funkcje takie jak system/popen w języku C, os.system/os.popen w języku Python, system/exec w języku PHP czy open/system w języku Perl mogą być również podatne.
    • Klienci protokołu DHCP uruchamiają skrypty powłoki, aby skonfigurować system. Przekazanie odpowiednich wartości może spowodować wykonanie poleceń jako użytkownik, z którym chodzi demon DHCP. Najczęściej tym użytkownikiem jest root!
    • Systemy SCADA takie jak Wago seria 758-870 PLC są również podatne i wykorzystują skrypty cgi we wbudowanym serwerze HTTP. Firma Wago zdecydowała, że nie będzie wydawać poprawek bezpieczeństwa dla tych systemów.

    Podsumowanie

    Aby sprawdzić czy ta podatność jest wciąż niezałatana wystarczy wykonać oba testy wspomniane powyżej. Luka jest dosyć poważna, szczególnie jeśli zostanie wykorzystana przez serwer Apache. Wtedy zdalny atakujący jest w stanie przejąć kontrolę nad systemem za pomocą serwera HTTP.

    Niedługo powinny pojawić się poprawki bezpieczeństwa na popularne systemy operacyjne z rodziny Linux. W międzyczasie można wykrywać użycie tej podatności za pomocą rozwiązań takich jak Snort czy Suricata. Dzisiaj pojawią się odpowiednie reguły, opublikowane w ramach listy Emerging Threats.

    Artykuł powstał w oparciu o następujące źródła: