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 bash
kod.
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 ssh
wchodzenia 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 bash
powł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 bash
był 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 bash
jako 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 bash
uż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) .