Kiedy wprowadzono błąd shellshock (CVE-2014-6271 / 7169) i jaka łatka go w pełni naprawia?


122

Trochę kontekstu na temat błędu: CVE-2014-6271

Bash obsługuje eksportowanie nie tylko zmiennych powłoki, ale także funkcji powłoki do innych instancji bash, poprzez środowisko procesowe do (pośrednich) procesów potomnych. Obecne wersje bash używają zmiennej środowiskowej nazwanej nazwą funkcji i definicji funkcji rozpoczynającej się od „() {” w wartości zmiennej do propagowania definicji funkcji przez środowisko. Luka występuje, ponieważ bash nie zatrzymuje się po przetworzeniu definicji funkcji; kontynuuje parsowanie i wykonywanie poleceń powłoki zgodnie z definicją funkcji. Na przykład ustawienie zmiennej środowiskowej na

  VAR=() { ignored; }; /bin/id

wykona / bin / id, gdy środowisko zostanie zaimportowane do procesu bash.

Źródło: http://seclists.org/oss-sec/2014/q3/650

Kiedy wprowadzono błąd i jaka łatka go w pełni naprawia? (Zobacz CVE-2014-7169 )

Jakie są wrażliwe wersje poza wymienionymi w CVE (początkowo) (3. {0..2} i 4. {0..3})?

Czy błędny kod źródłowy został ponownie wykorzystany w innych projektach?

Dodatkowe informacje są pożądane.


Powiązane: Co oznacza env x = '() {:;}; polecenie 'bash zrobić i dlaczego jest niepewny?


Kolejny dobry napis
Greg Bray

Odpowiedzi:


205

TL; DR

Luka w shellshock jest całkowicie naprawiona

  • W gałęzi bash-2.05b: 2.05b.10 i nowsze (wraz z łatką 10)
  • W gałęzi bash-3.0: 3.0.19 i nowsze (wraz z łatką 19)
  • W gałęzi bash-3.1: 3.1.20 i nowsze (wraz z łatką 20)
  • W gałęzi bash-3.2: 3.2.54 i nowsze (wraz z łatką 54)
  • W gałęzi bash-4.0: 4.0.41 i nowsze (łatka 41 w zestawie)
  • W gałęzi bash-4.1: 4.1.14 i nowsze (wraz z łatką 14)
  • W gałęzi bash-4.2: 4.2.50 i nowsze (wraz z łatką 50)
  • W gałęzi bash-4.3: 4.3.27 i nowsze (wraz z łatką 27)

Jeśli twoja wersja bash pokazuje starszą wersję, twój dostawca systemu operacyjnego mógł ją załatać sam, więc najlepiej to sprawdzić.

Jeśli:

env xx='() { echo vulnerable; }' bash -c xx

pokazuje „wrażliwy”, wciąż jesteś wrażliwy. Jest to jedyny istotny test (czy parser bash jest nadal narażony na kod w dowolnej zmiennej środowiskowej).

Detale.

Błąd był w początkowej realizacji funkcji export / import wprowadzony na 5 th sierpnia 1989 roku przez Briana Foxa, a po raz pierwszy wydany w bash-1.03 około miesiąc później w czasie, gdy bash nie był w takim powszechnym użyciu, zanim bezpieczeństwo było tyle obaw, że HTTP i sieć, a nawet Linux istniały.

Z ChangeLog w 1.05 :

Fri Sep  1 18:52:08 1989  Brian Fox  (bfox at aurel)

       * readline.c: rl_insert ().  Optimized for large amounts
         of typeahead.  Insert all insertable characters at once.

       * I update this too irregularly.
         Released 1.03.
[...]
Sat Aug  5 08:32:05 1989  Brian Fox  (bfox at aurel)

       * variables.c: make_var_array (), initialize_shell_variables ()
         Added exporting of functions.

Niektóre dyskusje w gnu.bash.bug i comp.unix.questions w tym czasie również wspominają o tej funkcji.

Łatwo zrozumieć, jak się tam dostało.

bash eksportuje funkcje w zmiennych env, takich jak

foo=() {
  code
}

A przy imporcie wszystko, co musi zrobić, to zinterpretować to z =zastąpionym spacją ... z wyjątkiem tego, że nie powinna ślepo interpretować.

Jest to również podzielone w tym, że w bash(w przeciwieństwie do powłoki Bourne'a) zmienne skalarne i funkcje mają inną przestrzeń nazw. Właściwie jeśli masz

foo() { echo bar; }; export -f foo
export foo=bar

bash z przyjemnością umieści oba te elementy w środowisku (tak wpisy o tej samej nazwie), ale wiele narzędzi (w tym wiele powłok) ich nie propaguje.

Można by również argumentować, że bash powinien używać do tego BASH_prefiksu przestrzeni nazw, ponieważ jest to zmienne env istotne tylko od bash do bash. rcużywa fn_przedrostka dla podobnej funkcji.

Lepszym sposobem na jego wdrożenie byłoby umieszczenie definicji wszystkich eksportowanych zmiennych w zmiennej takiej jak:

BASH_FUNCDEFS='f1() { echo foo;}
  f2() { echo bar;}...'

Które nadal będą musiały być oczyszczone, ale przynajmniej, że nie może być więcej niż wykorzystywaną $BASH_ENVlub $SHELLOPTS...

Jest tam łatka, która uniemożliwia bashinterpretowanie czegokolwiek innego niż definicja funkcji w niej zawarta ( https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html ), i to ta, która ma zostały zastosowane we wszystkich aktualizacjach bezpieczeństwa z różnych dystrybucji Linuksa.

Jednak bash nadal interpretuje tam znajdujący się kod i każdy błąd w interpretatorze może zostać wykorzystany. Jeden taki błąd został już znaleziony (CVE-2014-7169), chociaż jego wpływ jest znacznie mniejszy. Wkrótce pojawi się kolejna łatka.

Aż do poprawki hartowania, która uniemożliwia bashowi interpretację kodu w dowolnej zmiennej (np. Przy użyciu BASH_FUNCDEFSpowyższego podejścia), nie będziemy pewni, czy nie będziemy podatni na błąd w parserze bash. I wierzę, że prędzej czy później pojawi się taka poprawka hartująca.

Edytuj 28.09.2014

Znaleziono dwa dodatkowe błędy w parserze (CVE-2014-718 {6,7}) (zauważ, że większość pocisków musi zawierać błędy w parserze dla przypadków narożnych, co nie byłoby problemem, gdyby ten parser nie zostały narażone na niezaufane dane).

Podczas gdy wszystkie 3 błędy 7169, 7186 i 7187 zostały naprawione w kolejnych łatkach, Red Hat naciskał na poprawkę hartowania. W swojej łatce zmienili zachowanie, tak że funkcje zostały wyeksportowane do zmiennych zwanych BASH_FUNC_myfunc()mniej lub bardziej wyprzedzającymi decyzję projektową Cheta.

Później Chet opublikował tę poprawkę jako oficjalną łatkę upstreams .

Ta łatka utwardzająca lub jej warianty są teraz dostępne dla większości głównych dystrybucji Linuksa i ostatecznie trafiły do ​​Apple OS / X.

To teraz niepokoi wszelkie arbitralne zmienne env wykorzystujące parser za pośrednictwem tego wektora, w tym dwie inne luki w parserze (CVE-2014-627 {7,8}), które zostały ujawnione później przez Michała Zalewskiego (CVE-2014-6278 jest prawie tak źle jak CVE-2014-6271) na szczęście po tym, jak większość ludzi zdążyła zainstalować łatkę hartującą

Błędy w parserze również zostaną naprawione, ale nie stanowią już tak dużego problemu, ponieważ parser nie jest już tak łatwo narażony na niezaufane dane wejściowe.

Pamiętaj, że chociaż luka w zabezpieczeniach została naprawiona, prawdopodobnie zobaczymy pewne zmiany w tym obszarze. Początkowy fix dla CVE-2014-6271 złamał kompatybilności wstecznej w tym, że zatrzymuje funkcje importowania z .lub :lub /w ich imieniu. Nadal można je zadeklarować przez bash, co powoduje niespójne zachowanie. Ponieważ funkcje z .i :w ich imieniu są powszechnie używane, to prawdopodobnie poprawka przywraca przyjmowanie przynajmniej tych z otoczenia.

Dlaczego nie znaleziono go wcześniej?

Zastanawiałem się nad tym. Mogę podać kilka wyjaśnień.

Po pierwsze, myślę, że gdyby badacz bezpieczeństwa (a nie jestem zawodowym badaczem bezpieczeństwa) specjalnie szukał luk w bash, prawdopodobnie by go znalazł.

Na przykład, gdybym był badaczem bezpieczeństwa, moje podejście mogłoby wyglądać następująco:

  1. Sprawdź, skąd bashpobiera dane wejściowe i co z nimi robi. A środowisko jest oczywiste.
  2. Sprawdź, w których miejscach bashwywoływany jest tłumacz i na jakie dane. Znów będzie się wyróżniał.
  3. Importowanie eksportowanych funkcji jest jedną z funkcji, które są wyłączone, gdy bashjest ustawiony na setuid / setgid, co czyni go jeszcze bardziej oczywistym miejscem do patrzenia.

Teraz podejrzewam, że nikt nie pomyślał o traktowaniu bash(tłumacza) jako zagrożenia, ani że zagrożenie mogło przyjść w ten sposób.

bashInterpreter nie jest przeznaczona do przetwarzania wejściowych niezaufane.

Skrypty powłoki (nie interpreter) są często analizowane z punktu widzenia bezpieczeństwa. Składnia powłoki jest tak niewygodna i istnieje wiele ostrzeżeń dotyczących pisania wiarygodnych skryptów (widziałeś mnie lub innych, którzy wspominają o operatorze split + glob lub dlaczego na przykład powinieneś cytować zmienne?), Że dość często można znaleźć luki w zabezpieczeniach w skryptach, które przetwarzają niezaufane dane.

Dlatego często słyszysz, że nie powinieneś pisać skryptów powłoki CGI, lub skrypty setuid są wyłączone w większości Uniksów. Lub też powinieneś zachować szczególną ostrożność podczas przetwarzania plików w katalogach do zapisu na świecie (patrz na przykład CVE-2011-0441 ).

Skupiamy się na tym, na skryptach powłoki, a nie na tłumaczu.

Można wystawiać interpreter powłoki do niezaufanych danych (karmienie danych zagranicznych jako Shellcode interpretacji) przez evallub .lub nazywając ją pod warunkiem użytkowników plików, ale wtedy nie trzeba lukę w zabezpieczeniach bash, żeby go wykorzystać. To całkiem oczywiste, że jeśli przekazujesz niezarządzane dane do powłoki do interpretacji, to ją zinterpretuje.

Powłoka jest więc wywoływana w zaufanych kontekstach. Dostaje stałe skrypty do interpretacji i częściej (ponieważ tak trudno jest pisać wiarygodne skrypty) stałe dane do przetworzenia.

Na przykład w kontekście sieciowym można wywołać powłokę w czegoś takiego jak:

popen("sendmail -oi -t", "w");

Co może pójść nie tak? Jeśli przewiduje się coś złego, dotyczy to danych podawanych do tego sendmaila, a nie tego, w jaki sposób przetwarzany jest sam wiersz poleceń powłoki lub jakie dodatkowe dane są podawane do tej powłoki. Nie ma powodu, dla którego chciałbyś wziąć pod uwagę zmienne środowiskowe przekazywane do tej powłoki. A jeśli to zrobisz, zdasz sobie sprawę, że to są wszystkie zmienne env, których nazwa zaczyna się od „HTTP_” lub są dobrze znanymi zmiennymi env CGI, takimi jak SERVER_PROTOCOLlub QUERYSTRINGz którymi żadna powłoka lub sendmail nie mają nic wspólnego.

W kontekstach podniesienia uprawnień, takich jak uruchamianie setuid / setgid lub przez sudo, środowisko jest ogólnie brane pod uwagę i w przeszłości występowało wiele luk, ponownie nie przeciwko samej powłoce, ale przeciwko rzeczom, które podnoszą przywileje, takie jak sudo(patrz na przykład CVE -2011-3628 ).

Na przykład bashnie ufa środowisku, gdy jest setuid lub wywoływane przez polecenie setuid (pomyśl mountna przykład, że wywołuje pomocników). W szczególności ignoruje eksportowane funkcje.

sudorobi czyszczenia środowiska: wszystkie domyślnie wyjątkiem białej listy, a jeśli jest skonfigurowana, aby nie, przynajmniej czarnych listach kilka, które są znane wpływa na powłokę lub innej osoby (jak PS4, BASH_ENV, SHELLOPTS...). Umieszcza również na czarnej liście zmienne środowiskowe, których treść zaczyna się ()(dlatego CVE-2014-6271 nie pozwala na eskalację uprawnień przez sudo).

Ale znowu, dotyczy to kontekstów, w których środowisku nie można ufać: w tym kontekście złośliwy użytkownik może ustawić dowolną zmienną o dowolnej nazwie i wartości. Nie dotyczy to serwerów WWW / ssh ani wszystkich wektorów wykorzystujących CVE-2014-6271, w których środowisko jest kontrolowane (przynajmniej nazwa zmiennych środowiskowych jest kontrolowana ...)

Ważne jest, aby zablokować zmienną taką echo="() { evil; }", ale nie HTTP_FOO="() { evil; }", ponieważ HTTP_FOOnie będzie wywoływana jako polecenie przez żaden skrypt powłoki lub wiersz poleceń. A apache2 nigdy nie ustawi echoani BASH_ENVzmiennej.

To oczywiste, że niektóre zmienne środowiskowe powinny znajdować się na czarnej liście w niektórych kontekstach na podstawie ich nazwy , ale nikt nie pomyślał, że powinny być na czarnej liście na podstawie ich zawartości (z wyjątkiem sudo). Innymi słowy, nikt nie pomyślał, że arbitralne zmienne środowiskowe mogą być wektorem do wstrzykiwania kodu.

Jeśli chodzi o to, czy rozległe testy po dodaniu tej funkcji mogły ją złapać, powiedziałbym, że jest mało prawdopodobne.

Podczas testowania funkcji testujesz funkcjonalność. Funkcjonalność działa dobrze. Jeśli wyeksportujesz funkcję w jednym bashwywołaniu, zostanie ona zaimportowana w innym. Bardzo dokładne testowanie może wykryć problemy, gdy zarówno zmienna, jak i funkcja o tej samej nazwie są eksportowane lub gdy funkcja jest importowana w lokalizacji innej niż ta, w której została wyeksportowana.

Aby jednak wykryć lukę, nie jest to test funkcjonalności, który musiałbyś wykonać. Aspekt bezpieczeństwa musiałby być głównym celem i nie testowałbyś funkcjonalności, ale mechanizm i sposób, w jaki można by ją wykorzystać.

Nie jest to coś, co programiści (szczególnie w 1989 roku) często mają w głowie, a deweloperowi powłoki można usprawiedliwić, że jego oprogramowanie prawdopodobnie nie nadaje się do wykorzystania w sieci.


127
PS: Ta odpowiedź pochodzi od osoby, która pierwotnie odkryła błąd :)
Ramesh

6
@Ben Czy to nie jest odpowiedź na przeciwne pytanie?
Klamka

31
Czy mogę zapytać… czy przypadkowo natknąłeś się na błąd, czy aktywnie szukałeś błędów w Bash?
200_success

7
@gerrit Ponieważ błąd nie powoduje złego zachowania w normalnych warunkach. Ponieważ nic nie idzie źle, nikt nie patrzy na kod poza badaczami bezpieczeństwa i czarnymi czapkami.
Loren Pechtel

4
@JacekSzymanski prawda, ale co z innymi nagłówkami? szczególnie niestandardowe nagłówki? (atakujący może po prostu dodać nagłówek X-Exploit-Payload, który powinien być ustawiony jako HTTP_X_EXPORT_PAYLOAD)
immibis

19

Według bazy danych NVD na stronie NIST ( http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-6271 ) WSZYSTKIE WERSJE bash od 1.14.0 są podatne na atak.

RedHat dowiedział się o błędzie 14 września .

Patch wydany przez Mr.Ramey (opiekun bash) w dniu 26 września 2014 r. Naprawia błąd CVE-2014-7169 .

Zastosuj te i wszystkie poprzednie łaty do odpowiednich źródeł bash:


Dodatkowe luki w bashu


Trochę więcej o historii błędu (dzięki uprzejmości Mikeserv )

Źródło: http://www.linuxmisc.com/12-unix-shell/e3f174655d75a48b.htm

W 1994 roku Chet Ramey opisał to jako poprzedzające starą specyfikację POSIX 2, która i tak określała eksportowane funkcje. A przynajmniej tak opisał mechanizm uderzenia - czy był tak wadliwy, jak teraz, nie wiem. Omawia również eksport funkcji rc w tym wątku.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.