Jak została odkryta podatność Shellshock Bash?

19

Ponieważ ten błąd dotyczy tak wielu platform, możemy dowiedzieć się czegoś z procesu, w którym wykryto tę lukę: czy był to moment εὕρηκα (eureka) czy wynik kontroli bezpieczeństwa?

Ponieważ wiemy, że Stéphane znalazł błąd Shellshock, a inni mogą również znać ten proces, bylibyśmy zainteresowani historią, w jaki sposób znalazł błąd.

Faheem Mitha
źródło
5
Powiązane: jego odpowiedź na „Kiedy został wprowadzony błąd shellshock (CVE-2014-6271 / 7169) i jaka łatka go w pełni naprawia?”.
Cristian Ciupitu
To pytanie wydaje się nie na temat, ponieważ dotyczy procesu myślenia konkretnej osoby, a nie konkretnego problemu * nix.
terdon
@Anthon, dlaczego to musi dotyczyć Linuksa? Po co zatwierdzać edycję, która wprowadza czyjąś opinię tak, jakby była OP?
muru
@muru Znalazłem to ulepszenie, na szczęście więcej niż jedna osoba zatwierdza sugerowaną edycję. Ale muszę przyznać, że nie zauważyłem, że pytanie zostało już zamknięte, w przeciwnym razie nie zostawiłbym go Linux, Unix, nie dbam o to zbytnio, w przeciwnym razie potrzebujemy BSD itp. W tytule strony.
Anthon
1
Nie zakładaj, że czytam każde pytanie na tej stronie. Zobacz thread.gmane.org/gmane.comp.security.oss.general/14177/... na krótką odpowiedź.
Stéphane Chazelas,

Odpowiedzi:

23

Aby uspokoić kilka osób, nie znalazłem błędu przez obserwowanie exploitów, nie mam powodu sądzić, że został on wykorzystany przed ujawnieniem (choć oczywiście nie mogę tego wykluczyć). Nie znalazłem go również patrząc na bashkod.

Nie mogę powiedzieć, że pamiętam dokładnie wtedy mój ciąg myśli.

To mniej więcej pochodzi z refleksji nad niektórymi zachowaniami niektórych programów, które uważam za niebezpieczne (zachowania, a nie oprogramowanie). Takie zachowanie, które sprawia, że ​​myślisz: to nie brzmi jak dobry pomysł .

W tym przypadku zastanawiałem się nad wspólną konfiguracją ssh, która umożliwia przekazywanie zmiennych środowiskowych niezaangażowanych od klienta, pod warunkiem, że ich nazwa zaczyna się od LC_. Chodzi o to, aby ludzie mogli nadal używać własnego języka podczas sshwchodzenia na inne maszyny. Dobry pomysł, dopóki nie zaczniesz zastanawiać się, jak skomplikowana jest obsługa lokalizacji, zwłaszcza gdy UTF-8 jest wprowadzany do równania (i widzisz, jak źle jest obsługiwany przez wiele aplikacji).

Już w lipcu 2014 roku, miałem już zgłoszone luki w glibc postępowania lokalizacyjnego, które w połączeniu z tej sshd konfiguracji, a dwóch innych niebezpiecznych zachowań na bashpowłoce dozwolone (uwierzytelnione) atakujący włamać się do serwerów git pod warunkiem, że były one w stanie przesyłać pliki tam i bashbył używany jako powłoka logowania użytkownika git unix (CVE-2014-0475).

Pomyślałem, że to prawdopodobnie zły pomysł, aby użyć go bashjako powłoki logowania użytkowników oferujących usługi za pośrednictwem ssh, biorąc pod uwagę, że jest to dość złożona powłoka (gdy wszystko, czego potrzebujesz, to tylko parsowanie bardzo prostej linii poleceń) i odziedziczył większość błędnych projektów ksh. Ponieważ już zidentyfikowałem kilka problemów z bashużywaniem w tym kontekście (do interpretacji ssh ForceCommand), zastanawiałem się, czy może być ich więcej.

AcceptEnv LC_*pozwala każdej zmiennej, której nazwa zaczyna się od, LC_a ja miałem niejasne wspomnienie, że bash eksportowane funkcje ( niebezpieczna, choć przydatna w danym momencie funkcja) korzystały ze zmiennych środowiskowych, których nazwa była podobna myfunction()i zastanawiała się, czy nie było tam czegoś ciekawego do obejrzenia.

Już miałem odrzucić to na tej podstawie, że najgorsze, co można zrobić, to przedefiniować wywołaną komendę, LC_something co tak naprawdę nie może stanowić problemu, ponieważ nie są to nazwy komend, ale zacząłem się zastanawiać, jak bash zaimportowano te zmienne środowiskowe.

Co jeśli zmienne zostałyby wywołane LC_foo;echo test; f()na przykład? Postanowiłem więc przyjrzeć się bliżej.

ZA:

$ env -i bash -c 'zzz() { :;}; export -f zzz; env'
[...]
zzz=() {  :
}

ujawniłem, że moje wspomnienie było błędne, ponieważ zmienne nie zostały wywołane, myfunction()ale myfunction(i to wartość zaczyna się od ()).

I szybki test:

$ env 'true;echo test; f=() { :;}' bash -c :
test
bash: error importing function definition for `true;echo test; f'

potwierdziło moje podejrzenie, że nazwa zmiennej nie została zdezynfekowana, a kod został oceniony podczas uruchamiania .

Gorzej, znacznie gorzej, wartość nie została również zdezynfekowana:

$ env 'foo=() { :;}; echo test' bash -c :
test

Oznaczało to, że każda zmienna środowiskowa może być wektorem.

Wtedy zdałem sobie sprawę z zakresu problemu, potwierdziłem, że można go wykorzystać również przez HTTP ( HTTP_xxx/ QUERYSTRING... env vars), inne takie jak usługi przetwarzania poczty, później DHCP (i prawdopodobnie długą listę) i zgłosiłem (ostrożnie) .

Stéphane Chazelas
źródło
4
Ciekawa lektura! Chociaż komentarze do pytań wyjaśniają, że może to być nieco nie na temat tej witryny, myślę, że taka niewielka ilość pytań i odpowiedzi jak ta (z napisanymi odpowiedziami i tak czysto jak to) jest naprawdę zasób dla strony!
Johan E.