Wystartowała Akademia NIS2/KSC2! Można jeszcze dołączyć do końca lipca!

Konferencja Mega Sekurak Hacking Party w Krakowie – 26-27 października!

Bezpłatne szkolenie: AI dla admina. Netflow, firewalle i segmentacja bez zgadywania

Groźny atak na szyfrowany komunikator Gajim przez lukę w KDE Plasma

03 sierpnia 2026, 13:09 | Aktualności, Teksty | 0 komentarzy
Tagi: , , , , ,

Wiele współczesnych naruszeń bezpieczeństwa nie wynika z pojedynczego, spektakularnego błędu (np. klasy naruszenia ochrony pamięci). Prawdziwa esencja ofensywnego rzemiosła leży w łańcuchach podatności. Często dwie właściwości aplikacji, które pojedynczo wyglądają na niegroźne słabości lub błędy o niskim priorytecie, po połączeniu mogą dać zabójczy efekt.

To historia o tym, jak jedna subtelna cecha komunikatora Gajim w połączeniu z luką logiczną w środowisku KDE Plasma stworzyła mechanizm umożliwiający zdalne wykonanie kodu (RCE). Wystarczy jedno kliknięcie w otrzymany w wiadomości link.

Nazywam się Patryk Ptak, w sieci działam jako SivertPL. Jestem niezależnym badaczem bezpieczeństwa. W trakcie moich własnych badań nad klientami protokołu XMPP (jak Gajim) oraz ich interakcjami m.in z KDE Plasma, zidentyfikowałem lukę logiczną w ekosystemie KDE. Zanim jednak sfinalizowałem proces ujawnienia, doszło do częstej w świecie researchu kolizji – podatność ta bowiem została w międzyczasie niezależnie odkryta również przez innego badacza (Dennisa Dasta) i zarejestrowana jako CVE-2025-49091

Opublikowany biuletyn skupiał się jednak głównie na surowym błędzie w KDE Plasma, prezentując wymagający sporej interakcji użytkownika scenariusz z poziomu przeglądarki Firefox, która również mogła funkcjonować jako wehikuł dla tej podatności, tak jak potencjalnie wiele innych aplikacji.

Poniższy materiał to mój autorski, niezależnie opracowany łańcuch. Pokazuje on, jak tę samą lukę logiczną można było rozwinąć w bardziej skryty i praktyczny sposób ataku na użytkownika końcowego innej aplikacji – znanego szyfrowanego komunikatora.

Mit absolutnego bezpieczeństwa

Gajim od lat cieszy się reputacją jednego z najbezpieczniejszych klientów do szyfrowanej komunikacji opartej na protokole XMPP. Jest szczególnie popularny wśród użytkowników ceniących maksymalną prywatność, w szczególności w społecznościach w sieci TOR.

Ta opinia nie wzięła się znikąd. W przeciwieństwie do alternatywy – Pidgina (i innych aplikacji bazujących na libpurple), Gajim:

1. Jest napisany w Pythonie, języku zapewniającym bezpieczeństwo pamięci (memory safety).

2. Posiada dojrzały, stabilny kod źródłowy (mature codebase).

3. W pełni implementuje nowoczesny protokół szyfrowania (OMEMO).

Te cechy sprawiają, że klasyczna niskopoziomowa eksploitacja jest tu niezwykle trudna, jeśli nie niemożliwa. Niestety, reputacja czasem wpędza użytkowników w fałszywe poczucie bezpieczeństwa. Zabezpieczenia Gajima zostały tu bowiem ominięte pewną interesującą drogą.

Status podatności: Łatka dla KDE Plasma została już oficjalnie wydana. Atak w domyślnej konfiguracji (out-of-the-box) dotyczył użytkowników dystrybucji jak Debian, Fedora, openSUSE czy Arch Linux, i potencjalnie innych, korzystających ze środowiska KDE Plasma, o ile w systemie brakowało binarki klienta telnet, co w wymienionych wyżej dystrybucjach miało miejsce domyślnie

Źródło problemu: Niekontrolowany fallback przy obsłudze linków 

Głównym bohaterem tej historii jest wspomniana luka logiczna CVE-2025-49091 w KDE Plasma, w komponencie obsługującym niektóre rodzaje linków (emulator Konsole). Podatność była bezpośrednio związana z interpretacją przezeń schematu URI telnet://.

W przypadku, gdy użytkownik wywołał taki link, a w systemie brakowało klienta telnet, mechanizm KDE wykonywał niekontrolowany powrót (fallback) do interpretera poleceń:

bash -c

W efekcie, błąd ten pozwalał na przekazanie zawartości dowolnego pliku lokalnego z dysku ofiary wprost do wykonania przez powłokę bash w Konsole.

Błąd sam w sobie ma jednak ograniczone pole manewru – w scenariuszu Dennisa Dasta na Firefox, użytkownik jest atakowany wyskakującymi oknami z pytaniem, czy na pewno chce otworzyć dany link w zewnętrznej aplikacji. Link nie jest zaciemniony, co dodatkowo utrudnia praktyczne wykorzystanie ataku.

Ponadto napastnik musi mieć pewność, że na dysku ofiary istnieje plik o kontrolowanej przez niego zawartości i znanej mu lokalizacji.

I w tym momencie mój research skrzyżował się z komunikatorem Gajim.

Gajim jako wehikuł umożliwiający zdalny atak

Gajim posiada specyficzną właściwość, której nie można wprost sklasyfikować jako błąd bezpieczeństwa, ale stanowi dobry punkt wyjścia dla ataku. Komunikator ten wspiera automatyczną detekcję i podświetlanie linków do wielu niszowych bądź przestarzałych protokołów sieciowych. Jednym z nich jest właśnie telnet://.

Jeśli wyślemy do ofiary wiadomość zawierającą link:

telnet://sciezka_do_pliku

To Gajim posłusznie uzna go za prawidłowy URL, podświetli i umożliwi kliknięcie. Po kliknięciu, kontrolę przejmie podatny mechanizm KDE Plasma. Ponieważ klienta telnet domyślnie nie ma w wielu systemach wskazaną w linku ścieżkę Konsole wyegzekwuje jako skrypt Bash.

Pojawia się jednak kluczowe wyzwanie: Jak niepostrzeżenie dostarczyć złośliwy skrypt na dysk ofiary i poznać jego dokładną lokalizację?

Krok 1: Pamięć podręczna awatarów, czyli silent upload (cache poisoning) 

Najbardziej eleganckim i wolnym od interakcji sposobem na umieszczenie pliku na dysku ofiary w mojej ocenie okazał się mechanizm obsługi awatarów kontaktów w Gajim.

Gdy atakujący wyśle odpowiednią stanzę XMPP, czyli np. zaktualizuje swój awatar, proces Gajim ofiary automatycznie pobierze ten awatar i zapisze go w lokalnej pamięci podręcznej (cache) w katalogu domowym użytkownika (~/.cache/gajim/avatars/). 

Analizując ten mechanizm, zauważyłem trzy kluczowe cechy:

1. Nazwa pliku na dysku ofiary jest deterministyczna – to hash SHA-1 zawartości przesyłanego pliku („awatara”).

2. Gajim nie weryfikuje rygorystycznie struktury wysyłanego pliku graficznego. Jeśli wyślemy tam surowy kod skryptu shell, zostanie on bez ostrzeżenia zapisany jako “awatar”.

3. Jeśli atakujący nie miał ustawionego wcześniej poprawnego, widocznego awatara, nie dojdzie do żadnej zauważalnej zmiany po stronie ofiary.

Jako napastnik przygotowuję skrypt (np. generujący reverse shell w Pythonie), wyliczam jego hash SHA-1 i ustawiam ten plik jako swój awatar. Plik ląduje w systemie ofiary w przewidywalnym miejscu, bez jej wiedzy i interakcji.

Krok 2: Konstrukcja linku i obfuskacja 

Teraz należy wysłać link telnet:// wskazujący na nasz ukryty w cache skrypt. Aby ofiara nie nabrała podejrzeń, trzeba zadbać o wizualną prezentację linku, między innymi za pomocą techniki RTLO (Right-To-Left Override). Techniki bardzo starej, kojarzonej głównie z malware na Windows, która pomoże i w tym przypadku.

Wstrzyknięcie specjalnego znaku Unicode (U+202E), oraz spacji tuż za nim (aby zachować poprawny pierwszy znak hiperłącza), pozwala na odwrócenie kierunku wyświetlania tekstu. Konstrukcja zobfuskowanego linku wykorzystuje również znak Null-Byte (%00) oraz percent encoding niektórych znaków – poniżej wyjściowa treść linku:

[Znak RTLO] telnet:.cache/gajim/avatars/HASH_SHA1%00/moc.x//:sptth

Gotowy do wysyłki, zaciemniony link może wyglądać tak:

https://twitter.com/00%317076d6aadee1744dbdbcdcfaf0a7295f6cc479/s27%at16%va/miA6%ag/eh36%acE2%:tenlet

Dzięki znakowi RTLO, ofiara w oknie czatu Gajima zobaczy pozornie bezpieczny odnośnik, wyglądający na standardowy adres zaczynający się od https://.

Z kolei użycie Null-Byte (%00) jest kluczowe dla błędu w KDE – odcina ono sztuczny ogon linku w momencie przekazania go do interpretera Bash, dzięki czemu system szuka na dysku czystego pliku awatara, odrzucając doklejony na końcu sufiks.

Krok 3: Egzekucja kodu i zacieranie śladów

Co się stanie na urządzeniu ofiary gdy wejdzie w ten odnośnik?

1. Wywołanie handlera: Ofiara klika w link. Gajim przekazuje URI telnet:// do handlera linków KDE Plasma.

2. Wyzwolenie fallbacku Bash: Handler linków próbuje obsłużyć ten link w Konsole, ale tam system stwierdza brak klienta telnet. Zachodzi podatność CVE-2025-49091 – ścieżka do złośliwego “awatara” z pamięci podręcznej staje się argumentem do bash -c, zamiast telnet.

3. Egzekucja skryptu: Po uruchomieniu, Konsole wykonuje skrypt z podanej ścieżki, możliwe jest mignięcie okna. Skrypt nawiązuje w tle połączenie z serwerem Command & Control napastnika. 

4. Odwrócenie uwagi: By zachować wrażenie normalnego działania linku, skrypt otwiera w domyślnej przeglądarce prawidłowy URL.

5. Zacieranie śladów: Skrypt nadpisuje i kasuje sam siebie by utrudnić analizę powłamaniową, a na koniec czyści pozostałe ślady.

Ważna uwaga: Klasyczne, proste formy izolacji Gajima (jak uruchamianie go z poziomu użytkownika o niższych uprawnieniach czy w niektórych sandboxach) mogą okazać się tu niewystarczające. Kod nie wykona się bowiem z uprawnieniami Gajima, a zewnętrznego procesu utworzonego przez KDE Plasma. 

Wideo i eksploit

Demonstrację ataku z perspektywy ofiary – od kliknięcia w link do wykonania kodu napastnika (podmiana tapety) – można obejrzeć na poniższym wideo.

Kompletny i uzbrojony eksploit generujący złośliwy awatar, wysyłający odpowiednie stanzy oraz gotowy link do ofiary, dostępny jest tutaj:

https://github.com/thefreestyleresearcher/CVE-2025-49091-Gajim-RCE/blob/main/CVE-2025-49091.py

Podsumowanie i wnioski

Opisany przypadek udowadnia, że poleganie na samych biuletynach bezpieczeństwa nie zawsze oddaje realne ryzyko. Sama luka logiczna w KDE Plasma bez zewnętrznego wektora dostarczenia pliku mogłaby zostać uznana za trudną do wykorzystania podatność. 

Dopiero jej połączenie z mechanizmami komunikatora stworzyło realne zagrożenie.

Inspiracją do opublikowania tego materiału była chęć pokazania, że pomimo potężnego rozwoju automatycznych skanerów kodu oraz sztucznej inteligencji, ludzka intuicja, nieszablonowe myślenie i wyobraźnia wciąż pozostają niezastąpione. 

Dziękuję redakcji sekuraka za przestrzeń do publikacji. Materiał ten dedykuję wszystkim niezależnym badaczom – szczególnie tym, którzy dopiero zaczynają swoją przygodę z researchem i obawiają się, że w dobie rozwoju AI niedługo dla ludzi nie będzie już miejsca. 

Gra wciąż trwa, a jej zasady nadal definiujemy my.

~Patryk Ptak, SivertPL

Po więcej badań zapraszam na blog: sivert.pl.

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



Komentarze

Odpowiedz