(CVE-2021-42324) Metacharacter Injection w przełącznikach DCN S4600-10P-SI

9 Lutego 2022

Krótki opis podatności

Podczas wykonywania testów penetracyjnych natrafiłem na ciekawą  podatność w jednym z urządzeń  firmy DCN. Firmware przełączników DCN S4600-10P-SI w wersjach między R0241.0370, a R0241.0470, był podatny na atak Metacharacter Injection, umożliwiając na ucieczkę z przygotowanego przez producenta sandboxa, i w efekcie wykonywanie komend z uprawnieniami root bezpośrednio na systemie operacyjnym urządzenia. Podatna funkcjonalność związana z nagrywaniem ruchu sieciowego narzędziem tcpdump nie waliduje otrzymanych danych, a następnie przekazuje je bezpośrednio do powłoki systemowej.

Do wykorzystania podatności atakujący musi mieć dostęp do powłoki systemowej urządzenia. Podatność może zostać wykorzystana nawet przez użytkowników o najniższych uprawnieniach.

Metacharacter Injection

Metaznaki to znaki, które są specjalnie interpretowane przez daną powłokę. Różne powłoki mają różne zbiory metaznaków, jednak w tym artykule skupię się na powłoce sh (Bourne shell) i podatności OS Command Injection.

Metaznaki dostępne w powłoce sh:

Znak Funkcja
> Przekierowanie strumienia wyjściowego
>> Przekierowanie strumienia wyjściowego (tryb append)
< Przekierowanie strumienia wejściowego
* Znak wildcard; zero lub więcej znaków
? Znak wildcard; jeden znak
[ ] Znak wildcard; dowolny znak znajdujący się w nawiasach (np. [abc])
`cmd` Command Substitution; wykonywana jest komenda między znakami „
$(cmd) Command Substitution; wykonywana jest komenda między znakami ()
| Pipe; służy do przekierowania wyjścia z jednej komendy do drugiej
; Znak końca komendy
|| Operator logcziny OR
&& Operator logiczny AND
( ) Grupuje komendy
& Uruchamia daną komendę w tle
# Komentarz
$ Pobiera wartość danej zmiennej
\ Znak ucieczki

 

Typ ataku Metacharacter Injection polega na “wstrzyknięciu” tych znaków do wykonywanej komendy, w taki sposób aby doprowadzić do niezamierzonego zachowania ze strony podatnej aplikacji.

Przykładem występowania takiej podatności może być następujący skrypt PHP  <?php system(„echo ” . $_REQUEST[„string”]); ?>

 

 

Skrypt oczekuje przesłania zmiennej o nazwie string, a następnie dokleja zawartość tej zmiennej do polecenia echo, które jest wykonywane jako komenda systemowa. Przez dodanie metaznaku “;” (średnik), atakujący jest w stanie zakończyć wykonywaną komendę echo, a następnie wykonać własne komendy (w tym przypadku komenda id). Po przesłaniu stringu test;id, całość wykonywanej komendy będzie wyglądać:

echo test;id

Jest to jeden z najprostszych przykładów występowania podatności Metacharacter / OS Command Injection i stanowi bazę do wykorzystania podatności występującej w urządzeniach DCN S4600-10P-SI.

Przykłady użycia innych metaznaków

  • „ (backticks)
  • && (operator logiczny AND)
  • $()

Podatność w kodzie

Przełącznik udostępnia funkcjonalność nagrywania ruchu sieciowego komendą capture. Komenda ta jest dostępna dla wszystkich użytkowników urządzenia, niezależnie od ich poziomu uprawnień.

“Pod maską” komenda capture uruchamia program tcpdump, dołączając do niego argumenty podane przez użytkownika.

Zmienne podane przez użytkownika nie są walidowane przed doklejeniem ich do komend systemowych używanych do zbudowania skryptu uruchamiającego program tcpdump. Dzięki temu możliwe jest doklejenie swoich komend do tych, które są wykonywane przez program. Poniżej zaprezentowany jest wycinek kodu podatnej funkcji imi_shell_execute_tcpdump_command_Local wraz z krótkim opisem.

Analizując powyższy wycinek funkcji można zauważyć, w jaki sposób budowany jest skrypt uruchamiający program tcpdump.

Zmienna tcpdump_command przechowuje ścieżkę wywołania i argumenty programu tcpdump. W trakcie działania programu doklejana jest do niej ścieżka do pliku podanego przez użytkownika. W efekcie, wykonywane polecenie pod koniec działania funkcji wygląda następująco:

tcpdump <argumenty> -w <ścieżka do zapisu pliku>

W momencie kiedy użytkownik do ścieżki pliku doda metaznaki (np. średnik) polecenie przyjmie taką formę

tcpdump <argumenty> -w <ścieżka do zapisu pliku>;<komenda>

co daje możliwość wykonania komend na systemie.

Dalsze iteracje podatności w różnych wersjach oprogramowania działają na tej samej zasadzie, różniąc się jedynie sposobem wykonania komend przez użycie różnych metaznaków lub mechanizmów powłoki systemowej.

Kolejne wersje oprogramowania

R0241.0370

Podatność pierwszy raz została zauważona w tej wersji oprogramowania, w parametrze file. Aby wykonać komendy na systemie należało wstawić średnik, a następnie skorzystać z mechanizmu ‘command substitution’.

Dodatkowo, przez dodanie cudzysłowów możliwe było wstawienie znaku spacji, który normalnie był traktowany jako separator parametrów. Prawidłowo skonstruowany payload wyglądał zatem tak:

capture match icmp count 1 file ‘o;”$(<command>)”’

Przykład wykonania komendy ls -l /

Widok na interfejsie Serial

R0241.0439

Parametr file nadal jest podatny na wstrzyknięcie metaznaków, jednak tym razem użycie znaku cudzysłowu jest zabronione. Znak ten jest potrzebny do wstawienia spacji do komendy. Aby to obejść można wykorzystać kodowanie heksadecymalne znaku spacji, a następnie rozwiązanie go do pełnoprawnej spacji.

Przykład wyłączenia procesu sterującego i otrzymanie powłoki systemowej na interfejsie Serial

Wynik na interfejsie Serial, razem z wykonaniem komendy id

Wykonanie tak zapisanej komendy jest możliwe dzięki właściwościom powłoki systemowej obecnej na urządzeniu.

;privesc=pkill$’\x20’nos;$privesc;

Pierwsza część payloadu przypisuje wartość pkill$’\x20’nos do zmiennej privesc. Druga część wykonuje polecenie, które znajduje się tej zmiennej. Dzięki właściwościom powłoki systemowej, ciąg znaków pkill$’\x20’nos rozwiązuje się do pkill nos, co jest poprawnym poleceniem systemowym, które zostaje następnie wykonane.

R0241.0445

W kolejnej wersji firmware, podatność została załatana w parametrze file. W trakcie testów okazało się jednak, że pozostałe parametry komendy capture są nadal podatne na ten sam wektor ataku, co widać na przykładzie parametru source-port.

Dodatkowo, przy próbie mitygacji, uniemożliwiono korzystanie z funkcjonalności przy domyślnych parametrach. W nowej wersji firmware, niemożliwe było wstawienie znaków specjalnych do nazwy pliku. Wśród tych znaków był też znak kropki (”.”). Domyślna wartość nazwy pliku, tj. ta, która zostaje użyta jeśli użytkownik nie poda swojej własnej, to default.pcap. Po wgraniu poprawki, w momencie gdy program otrzymywał taką nazwę zwracał błąd o złej nazwie pliku, mimo że użytkownik nie podał żadnej. Aby skorzystać z podatności, należy podać nazwę pliku, która nie będzie zawierać znaków specjalnych.

Błąd wyświetlany przy użyciu domyślnej nazwy pliku

Przykład wykonania komendy ls -la

Widok na interfejsie Serial

R0241.0453

W tej wersji firmware, poprzednie metody wykonywania komend nie działają w taki sam sposób. Parametry source-port oraz destination-port nadal są podatne, jednak metoda z dopisaniem średnika różni się w działaniu. Sposobem na obejście tego jest użycie znaku ampersand (”&”). Umożliwia to na natychmiastowe wykonanie komendy.

Przykład wykonania komendy ls -la

Widok na interfejsie Serial

Metoda ze średnikiem cały czas działa, jednak w trochę zmieniony sposób. Wydane polecenie wykonuje się dopiero w momencie, kiedy użytkownik zatrzyma wszystkie procesy nagrywania ruchu sieciowego komendą capture packet force stop.

Przykład wykonania komendy ls -la

Widok na interfejsie Serial

R0241.0470

W tej wersji producent firmware podszedł do problemu globalnie, dla każdego parametru. W trakcie testów nie udało mi się obejść zabezpieczeń wprowadzonych w nowej wersji. Należy pamiętać jednak, że możliwe jest zrobienie tzw. downgrade firmware’u do niższych wersji gdzie podatność nadal istnieje.

Podsumowanie

Proces naprawienia podatności zajął w sumie około 6 miesięcy i aż cztery nowe wersje firmware. W trakcie prób naprawy producent skupił się wyłącznie na payloadach wskazanych w zgłoszeniu, co skutecznie uniemożliwiło wykonanie tego samego ataku dwukrotnie, ale nie rozwiązywało istniejącego problemu. Dopiero w ostatniej opisywanej wersji firmware, podatność została załatana przez poprawną walidację wszystkich parametrów.

Timeline

  • 06.04.2021 – Zgłoszenie podatności do producenta
  • 05.2021 – Wydanie wersji R0241.0349
  • 28.05.2021 – Zgłoszenie podatności w wersji R0241.0349
  • 06.2021 – Wydanie wersji R0241.0445
  • 23.06.2021 – Zgłoszenie podatności w wersji R0241.0445
  • 07.2021 – Wydanie wersji R0241.0453
  • 24.08.2021 – Zgłoszenie podatności w wersji R0241.0453
  • 09.2021 – Wydanie wersji R0241.0470 z poprawioną podatnością
  • 12.10.2021 – Zgłoszenie CVE
Opublikowane przez: Piotr Mierzwiński

Inne artykuły_