🥇Przewodnik po Aircrack-ng w Linuxie dla początkujących | ProHoster

🥇Przewodnik po Aircrack-ng w Linuxie dla początkujących | ProHoster

Rok temu, 21 marca 2019 roku, w programie bug bounty Mail.Ru na HackerOne zgłoszono bardzo dobry raport o błędzie od maxarr. Przy wprowadzeniu zera bajtowego (ASCII 0) w parametr POST jednego z zapytań API usługi pocztowej, które zwracało przekierowanie HTTP, w danych przekierowania widniały fragmenty nieinicjowanej pamięci, w których najczęściej ujawniały się fragmenty z parametrów GET i nagłówków innych zapytań do tego samego serwera.

To krytyczna podatność, ponieważ zapytania zawierają również ciasteczka sesyjne. Po kilku godzinach stworzono tymczasowe rozwiązanie, które filtrowało zerowy bajt (jak później się okazało, to nie wystarczyło, ponieważ pozostała możliwość wstrzyknięcia CRLF / ASCII 13, 10, co pozwalało manipulować nagłówkami i danymi odpowiedzi HTTP, jest to mniej krytyczne, ale nadal nieprzyjemne). Jednocześnie problem został przekazany analitykom bezpieczeństwa i programistom w celu znalezienia i likwidacji przyczyn wystąpienia błędu.

Poczta Mail.ru to bardzo złożona aplikacja, w formowaniu odpowiedzi może brać udział wiele różnych komponentów frontendowych/backendowych, zarówno open source (wielkie podziękowania dla wszystkich programistów oprogramowania wolnego), jak i opracowanych wewnętrznie. Udało się wykluczyć wszystkie komponenty poza nginx i openresty i zlokalizować problem do wywołania ngx.req.set_uri() w skrypcie OpenResty, który działał inaczej, niż oczekiwano (nie można było wstrzyknąć zera bajtowego ani znaku nowej linii przez parametry GET z przepisywaniem w ngx_http_rewrite_module, który, zgodnie z dokumentacją, jest używany i wydawałoby się, że powinien działać dokładnie tak samo). Zminimalizowano możliwe konsekwencje, dodano maksymalnie restrykcyjne filtrowanie i sprawdzono, czy filtracja eliminuje wszystkie możliwe wektory. Ale mechanizm, który prowadził do wycieku zawartości pamięci, pozostał tajemnicą. Po miesiącu raport o błędzie zamknięto jako rozwiązany, a analiza przyczyn wystąpienia błędu została odłożona na lepsze czasy.

OpenResty to bardzo popularny wtyczka umożliwiająca pisanie skryptów Lua wewnątrz nginx, wykorzystywana w kilku projektach Mail.ru, dlatego problem nie był uważany za rozwiązany. I po pewnym czasie powrócono do niego, aby zrozumieć prawdziwe przyczyny, możliwe konsekwencje i opracować zalecenia dla programistów. W odkryciach kodu źródłowego uczestniczył Denis Denisov i Nikołaj Jermiszkina. Okazało się, że:

  • W nginx, przy użyciu rewrite z danymi użytkownika, istnieje możliwość przejścia przez katalog (prawdopodobnie SSRF) w niektórych konfiguracjach, ale to znany fakt, który powinien być wykrywany przez statyczne analizatory konfiguracji w Nginx Amplify i Gixy od Yandex (tak, my też go używamy, dziękujemy). Przy użyciu OpenResty można łatwo przeoczyć tę możliwość, ale nasza konfiguracja nie była nią dotknięta.

    przykład konfiguracji:

    location ~ /rewrite {
        rewrite ^.*$ $arg_x;
    }
    
    location / {
        root html;
        index index.html index.htm;
    }

    wynik

    curl localhost:8337/rewrite?x=/..../..../..../..../..../..../etc/passwd
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    ...

  • W nginx występuje błąd prowadzący do wycieku zawartości pamięci, jeśli ciąg rewrite zawiera bajt zerowy. Przy zwracaniu przekierowania nginx przydziela nowy bufor pamięci odpowiadający całkowitej długości ciągu, ale kopiuje ciąg przez funkcję, w której bajt zerowy jest terminatorem ciągu, więc ciąg jest kopiowany tylko do bajtu zerowego, a reszta bufora zawiera niezainicjowane dane. Szczegółowe omówienie można znaleźć tutaj.

    przykład konfiguracji (^@ bajt zerowy)

    
    location ~ /memleak {
        rewrite ^.*$ "^@asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdasdf";
    }
    
    location / {
        root html;
        index index.html index.htm;
    }

    wynik
    curl localhost:8337/secret -vv
    ...
    curl localhost:8337/memleak -vv
    ...
    Lokalizacja: http://localhost:8337/secret
    ...

  • Nginx chroni parametry GET przed iniekcją znaków sterujących i umożliwia użycie w rewrite tylko parametrów GET. Dlatego eksploatacja iniekcji przez kontrolowane przez użytkownika parametry w nginx jest niemożliwa. Parametry POST w tym przypadku nie są chronione. OpenResty pozwala pracować zarówno z parametrami GET, jak i POST, więc przy użyciu parametrów POST przez OpenResty pojawia się możliwość iniekcji specjalnych znaków.

    przykład konfiguracji:

    location ~ /memleak {
        rewrite_by_lua_block {
            ngx.req.read_body();
            local args, err = ngx.req.get_post_args();
            ngx.req.set_uri( args["url"], true );
        }
    }
    
    location / {
        root html;
        index index.html index.htm;
    }
    

    wynik:

    curl localhost:8337 -d "url=secret" -vv
    ...
    curl localhost:8337 -d "url=asdfasdfasdfasdfasdfasdfasdfasdf" -vv
    ...
    Lokalizacja: http://localhost:8337/{...może zawierać secret...}
    ...

Dalsza reakcja

O problemie poinformowano programistów nginx i OpenResty, programiści nie traktują tego problemu jako błędu bezpieczeństwa w nginx, ponieważ w samym nginx nie ma możliwości eksploatacji błędu przez iniekcję znaków specjalnych, poprawka ujawniania zawartości pamięci została opublikowana 16 grudnia. Minęły 4 miesiące od momentu zgłoszenia w OpenResty, w ciągu tych 4 miesięcy nie wprowadzono żadnych zmian, mimo że było zrozumienie konieczności bezpiecznej wersji funkcji ngx.req.set_uri(). 18 marca 2020 opublikowaliśmy informację, a 21 marca OpenResty wydała wersję 1.15.8.3, która dodaje sprawdzenie URI.

Portswigger napisał Dobry artykuł, który zawiera komentarze od OpenResty i Nginx (jednakże komentarz, że ujawnia się tylko mały fragment pamięci, jest błędny i wprowadza w błąd; to zależy od długości ciągu następującego po zerowym bajcie i w braku jawnych ograniczeń na długość, może być kontrolowane przez atakującego).

Jak więc doszło do tego błędu i co zrobić, aby go zapobiec?

Czy błąd wynikał z nginx? Tak, wynikał, ponieważ wyciek zawartości pamięci to w każdym przypadku błąd.

Czy błąd dotyczył OpenResty? Tak, przynajmniej kwestia bezpieczeństwa oferowanej funkcjonalności OpenResty nie została zbadana ani udokumentowana.

Czy popełniono błąd w konfiguracji / użyciu OpenResty? Tak, ponieważ w braku wyraźnego wskazania, zrobiono niepotwierdzone założenie o bezpieczeństwie używanej funkcjonalności.

Która z tych błędów jest podatnością na bezpieczeństwo z nagrodą w wysokości $10000? Dla nas to w zasadzie nie ma znaczenia. W każdym oprogramowaniu, szczególnie w przypadku złożoności kilku komponentów, zwłaszcza dostarczanych przez różne projekty i deweloperów, nikt i nigdy nie może zagwarantować, że wszystkie cechy ich działania są znane i udokumentowane, a błędów nie ma. Dlatego każda podatność na bezpieczeństwo pojawia się tam, gdzie wpływa na bezpieczeństwo.

W każdym razie dobrą praktyką będzie normalizacja lub maksymalne ograniczanie / filtrowanie danych wejściowych, które trafiają do jakiegokolwiek zewnętrznego modułu / API, jeśli nie ma wyraźnych wskazówek i jednoznacznego zrozumienia, że nie jest to wymagane.

Errata

Z doświadczenia poprzedniego artykułu., w celu zachowania czystości języka:

bug bounty — konkurs na wykrywanie błędów
raport o błędzie — powiadomienie o błędzie
przekierowanie — skierowanie
otwartoźródłowy — otwarty kod
errata — prace nad błędami

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster