
Wstęp – tu zaczyna się opowieść
Testując oprogramowanie takie jak NetIQ Advanced Authentication – dziś znane jako OpenText Advanced Authenticator – produkt używany przez korporacje, instytucje rządowe i infrastrukturę krytyczną, łatwo założyć, że ktoś już dawno znalazł wszystkie poważne podatności. Przecież to system tak ważny, że musiał być dokładnie sprawdzony… prawda?
To właśnie weryfikacja takich założeń jest początkiem prawdziwego testowania.
Łatwo wpaść w rutynę i szukać tylko oczywistych błędów. O wiele trudniejsze – i znacznie bardziej wartościowe – jest zrozumienie, jak naprawdę działa aplikacja. Komu ufa? Jakie przyjmuje założenia? W jaki sposób komunikują się jej poszczególne komponenty?
Z takim nastawieniem, razem z Sławomirem Zakrzewskim, zaczęliśmy analizować NetIQ Advanced Authentication w wersji 6.4.2. Nie od strzelania payloadami – ale od zadawania właściwych pytań.
To podejście pozwoliło nam odkryć dwie podatności:
- CVE-2024-10865 – Reflected Cross-Site Scripting (XSS)
- CVE-2024-10864 – Blind Time-Based SQL Injection
Jednak najważniejsze nie były same CVE, a zrozumienie systemu i tego, jak drobne luki mogą się łączyć w realne, groźne wektory ataku.
Rozdział 1: Brak pliku – jest XSS (CVE-2024-10865)
Podczas analizy funkcji tworzenia backupu zauważyliśmy, że wymaga ona pliku o bardzo konkretnym formacie nazwy i rozszerzenia. Po dokładnym przestudiowaniu dokumentacji i odtworzeniu logiki walidacji ustaliliśmy prawidłowy wzorzec:aubak-2020-10-10_13-44-v-NetIQ-6.4.2.0-354.cpt.
Po wgraniu pliku o takiej nazwie walidacja przechodziła poprawnie, ale nic ciekawego się nie działo. Funkcjonalność sama w sobie była poprawna.
Zaczęliśmy więc testować nietypowe przypadki. Gdy w nazwie pliku wprowadziliśmy błąd, aplikacja zwróciła komunikat o błędzie, w którym bez żadnej filtracji wstrzykiwała nazwę pliku w odpowiedź HTML. To od razu zasugerowało potencjalną podatność XSS.
Dla potwierdzenia tej teorii przesłaliśmy plik o nazwie:aubak-2020-10-10_13-44-v-NetIQ-6.4.2.0-354<img src=x onerror=prompt(1)>.cpt
…i faktycznie – nasz JavaScript wykonał się w przeglądarce.

Co wyglądało jak nudny błąd walidacji, okazało się reflected XSS – połączeniem braku sanitizacji i nadmiernie szczegółowych komunikatów błędów.
Rozdział 2: Biała lista, która nie chroniła (SQLi – CVE-2024-10864)
W trakcie skanowania infrastruktury zauważyliśmy otwarty port 5432 (PostgreSQL). Dla zasady sprawdziliśmy połączenie używając domyślnych danych logowania: postgres:postgres.
Połączenie zostało odrzucone – ale nie z powodu błędnego hasła. Powodem był brak naszego IP na liście dozwolonych adresów.
Było to interesujące, jednak na ten moment była to ślepa uliczka… póki co.
Podczas dalszej analizy panelu administracyjnego znaleźliśmy funkcję importu użytkowników z bazy danych. Pozwalała ona podać adres serwera, dane logowania oraz nazwę bazy. Naturalnie, spróbowaliśmy użyć tych samych domyślnych danych do połączenia się z PostgreSQL.
Aplikacja zwróciła komunikat:
"Invalid database name"
To była cenna wskazówka – oznaczała, że aplikacja poprawnie uwierzytelniła się w bazie, ale nie znalazła podanej bazy danych.
Spróbowaliśmy więc domyślnej bazy PostgreSQL – postgres.
Tym razem odpowiedź brzmiała:
"Users processed = 0, added = 0, updated = 0, deleted = 0"
Co to oznaczało?
- Aplikacja mogła łączyć się z bazą danych.
- Wykonywała zapytania SQL – prawdopodobnie
SELECTz tabeli użytkowników – ale nie znalazła danych.
Na pierwszy rzut oka – nic groźnego. Nawet mając ważne dane logowania, mogliśmy co najwyżej zaimportować użytkowników, bez dostępu do ich haseł czy danych wrażliwych.
Ale nie zatrzymaliśmy się na tym.
Zaczęliśmy podejrzewać, że aplikacja buduje zapytania SQL dynamicznie, w oparciu o wartości podawane przez użytkownika – np. nazwę bazy czy tabeli.
Idealne miejsce, by przetestować SQL Injection.
W polu „database name” wstrzyknęliśmy:
' or pg_sleep(10);--Odpowiedź serwera opóźniła się dokładnie o 10 sekund.
Bingo. Blind Time-Based SQL Injection potwierdzony.
Dzięki starannie przygotowanym payloadom i mierzeniu czasów odpowiedzi mogliśmy teraz wyciągać dowolne dane z bazy – mimo że nasz adres IP nie był do niej dopuszczony.
Jak to możliwe?
- Aplikacja miała dostęp do bazy i działała jako proxy.
- Pola formularza były podatne na SQLi.
- Domyślne dane logowania były prawidłowe.
Na pierwszy rzut oka mogło się wydawać, że istnienie domyślnych danych logowania to błąd o minimalnym wpływie. Jednak zrozumienie architektury aplikacji ujawniło, jak groźna jest ta luka – umożliwiała dostęp do danych, do których nie powinniśmy mieć żadnych uprawnień. Dzięki podatności SQL Injection mogliśmy nadużywać funkcji import. Byliśmy w stanie ominąć restrykcje IP oraz wyciągnąć dowolne dane z bazy.
Przemyślenia – testowanie to coś więcej niż payloady
Skuteczne testowanie bezpieczeństwa to nie tylko strzelanie payloadami i czekanie, aż coś się złamie.
To przede wszystkim rozumienie architektury, granic zaufania i założeń, jakie przyjęli twórcy systemu.
W tym przypadku żadna z tych podatności nie została znaleziona przez fuzzery czy automatyczne skanery. Zostały odkryte dzięki analizie, jak aplikacja obsługuje backupy, jak buduje połączenia z bazą i gdzie domyślnie ufa użytkownikowi.
Różnica między funkcjonalnością a podatnością często leży w kontekście. Aby ją dostrzec, trzeba poświęcić czas i naprawdę zrozumieć działanie systemu.
Dobre testowanie wymaga nie tylko kreatywności – ale przede wszystkim ciekawości i dyscypliny, by zwolnić i spojrzeć głębiej.
Podziękowania
Wielkie podziękowania dla CERT Polska za wsparcie w procesie zgłaszania omówionych podatności.
Dziękujemy również zespołowi NetIQ (obecnie część OpenText) za profesjonalną i szybką reakcję – obsłużenie tych zgłoszeń z pełną transparentnością i dbałością o bezpieczeństwo użytkowników.
Na koniec, ogromne podziękowania dla Sławomira Zakrzewskiego z AFINE – za Twoje spojrzenie, wiedzę i wytrwałość w całym procesie badawczym.
Referencje
- CVE-2024-10864 – Blind Time-Based SQL Injection w NetIQ Advanced Authentication
- CVE-2024-10865 – Reflected Cross-Site Scripting (XSS) w NetIQ Advanced Authentication




