Dlaczego sama zdolność definiowania funkcji w zmiennej środowiskowej nie stanowi zagrożenia bezpieczeństwa?


9

Jak rozumiem, ogólnie uważa się za bezpieczne, aby każdy mógł dostarczyć informacje, które będą przechowywane w zmiennej środowiskowej. Luka w shellshock jest tutaj problemem, ponieważ oznacza, że ​​kod na końcu definicji funkcji w zmiennej środowiskowej zostanie wykonany, gdy uruchomi się nowa instancja bash, i oczywiście nie chcesz, aby ktokolwiek uruchamiał dowolny kod, który podoba ci się na twoim serwerze . Same definicje funkcji najwyraźniej nie stanowią jednak zagrożenia bezpieczeństwa i są dozwolone, ponieważ należy je wyraźnie wywołać w celu wykonania kodu.

Moje pytanie brzmi: dlaczego złośliwy użytkownik nie może po prostu zdefiniować funkcji, zawierającej swój złośliwy kod jako typowe polecenie, lsa następnie mieć nadzieję, że skrypt (lub cokolwiek, co jest uruchamiane) w pewnym momencie użyje tego polecenia?

Przykład tego, co mam na myśli:

$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...

Odpowiedzi:


10

Jest to ryzyko bezpieczeństwa. Z tego właśnie powodu nie można tego zrobić przy przełączaniu do innego kontekstu (zdalne sterowanie systemem, zmiana użytkowników itp.).

Jeśli masz możliwość utworzenia dowolnej zmiennej środowiskowej, istnieje wiele możliwych sposobów wykonania dowolnego kodu.
Weź $LD_PRELOADjako przykład. Jeśli masz możliwość ustawienia tej zmiennej, możesz zastąpić funkcje biblioteczne i wstawić tam swój kod. Możesz ustawić $DISPLAYzmienną i przekierować wyświetlacz X, z którym łączy się program, aby uzyskać kontrolę nad aplikacją.

Dlatego rzeczy takie jak sudousuwanie środowiska ze wszystkich zmiennych. sudopozwala tylko na kilka wybranych zmiennych. I tych zmiennych, odkaża je (przechodzi przez $TERMzmienną, ale nie będzie, jeśli zawiera niezwykłe znaki).


Wow, zawsze zastanawiałem się, dlaczego niektóre wielkie skrypty, które wykonuję w BASH, miałyby dziwne tajemne awarie, kiedy zaczynałem od sudo, szczególnie wokół ścieżek, co doprowadziło mnie do sprawdzenia startów sudo i ich zablokowania, ale nigdy nie wiedziałem, dlaczego tak się stało i było problem, dziękuję za dobre wyjaśnienie dotyczące ponownego usuwania zmiennych środowiskowych.
Lizardx

3

Powiedziałbym, że tak, kiedy bash jest twoim / bin / sh. Nie jest to cecha powłoki Bourne'a i założę się, że nie jest to również cecha powłoki POSIX, w rzeczywistości mogą chcieć to wyraźnie zabronić.

Bash jest naprawdę bardziej skorupą pochodną Korna niż skorupą Bourne'a, pomimo swojej nazwy, i jest jedyną skorupą podobną do Korna, która ma tę cechę, i moim zdaniem jest to funkcja zlewu kuchennego, która nie ma praktycznych zalet. Programiści, którzy unikają funkcji bash dla standardów, takich jak powłoka bourne, powłoka posix lub podzbiór ksh88, które mają wspólne współczesne powłoki, lub innymi słowy, zobowiązali się do dobrych praktyk i standardowych idiomów, są zszokowani, gdy ich oprogramowanie jest włączone Linux i Mac, a teraz potencjalnie podatne na atak, ponieważ autorzy exploita mogą swobodnie korzystać z „bashism”, pomimo ich zamiarów. O ile poprawiona kompatybilność, gdy jest wywoływana jako / bin / sh, w porównaniu z innymi pochodnymi powłoki Korn, to tylko wtedy, gdy / bin / sh jest powłoką logowania lub powłoką interaktywną, gdy bash zachowuje się bardziej jak powłoka Bourne'a, niż powłoka Korn,

Spróbuję cię przekonać, że jest to funkcja zlewozmywaka kuchennego, z 2 przypadkami: jesteś wbudowanym twórcą, który tworzy urządzenia takie jak routery, pamięć masowa podłączona do sieci 1. większa env, oznacza więcej, pamięć, więc większy koszt, więc mniej zysków, więc jeśli to był powód, aby rozważyć skorzystanie z tej funkcji bash, czy zamiast tego nie powinieneś używać FPATH i automatycznego ładowania, zamiast funkcji ksh88? zamiast przekazywać całą funkcję bajt po bajcie w środowisku? Możesz nawet rozważyć hurtowe parsowanie i przycinanie środowiska, zanim dojdzie ono do skryptu powłoki, który mógłby źle parsować zmienną, na przykład po prostu odfiltrować ^ $ (. *) $ I tym podobne ...

Podkreśla to, co jest w tym wyjątkowe, nie ma znaczenia, co to jest zmienna, a skrypt nie musi odwoływać się do zmiennej ani jej używać, może być nadal podatny na atak.

#!/bin/sh
exec /usr/local/myapp/support/someperlscript.pl

Dla wszystkiego innego pod słońcem, powyższe jest tak bezpieczne, jak skrypt perla, nie używasz żadnych zmiennych, w jaki sposób można je źle odczytać? Zmieniam na

#!/bin/bash -norc
exec /usr/local/myapp/support/someperlscript.pl

To też nie pomaga, nie miało to nic wspólnego z ENV ani nic podobnego - wszyscy się palą, ponieważ bash musi być wyjątkowy. Fakt, że bash wersja 2 ma problemu, dla mnie dowód, że nikt nie używa tej funkcji dla swoich aplikacji, ponieważ w przeciwnym razie powinien nie mieć czai się wokół tego długo. Co gorsza, w zasadzie nie da się uniknąć tej funkcji . Oto przykład z: z 'su -', który jeśli zapytasz kogoś, wytłumaczeniem byłoby odrzucenie środowiska, sprawdź stronę podręcznika, a znajdziesz tylko 99,9%. Przetestowałem to w odpowiedni sposób, ponieważ w tym systemie / bin / sh jest powłoką logowania roota, a / bin / sh to bash ALE , w tym przykładzie próbujęzahartować mój .bash_profile. Zmieniłem nazwę swojego istniejącego na root (który jest włączony), ale myślałem, że jeśli su, to prawdopodobnie sudo, w każdym razie zmieniłem na:

exec env -i TERM=vt102 LOGNAME=root USER=root HOME=/var/root /bin/ksh -i

Tak więc właściwie całkowicie podrzucam środowisko i używam minimalnej env, a następnie uruchamiam powłokę, która nie powinna mieć problemu, zamiast bieżącego procesu. Następnie zamiast standardowego przykładu spróbuj:

%dock='() { echo -e "\e[2t\c"; echo dockshock;} ; dock' su 

To ilustruje, jak nie ma to nic wspólnego z analizowaniem żadnej konkretnej funkcji, a exploit może odnosić się do tej funkcji i jej używać. Możesz sobie wyobrazić, że funkcja ma logikę do sprawdzania, czy root, itp. W tym przypadku jest to po prostu zmodyfikowana funkcja służąca do ikonowania lub zadokowania okna terminala, przy użyciu sekwencji ucieczki, która jest dość standardowa, więc po kliknięciu w celu deikonifikacji, zobacz dokok - ale co z tego? Teraz spróbuj tego:

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su - 

I zgadnij co? Okno zostaje wciągnięte do doku. Oto jak to potem wygląda ...

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
Password:
dockshock
# env
_=/usr/bin/env
HOME=/var/root
LOGNAME=root
TERM=vt102
USER=root
# echo $0
/bin/ksh
#

A więc tyle za to! Wyeksportowane funkcje mają w rzeczywistości pierwszeństwo przed skryptami rc. Nie możesz tego uniknąć.


1
POSIX zezwalał na funkcje eksportowe w wersji roboczej 2, a następnie zabronił ich. Ta funkcja jest szalona.
mikeserv
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.