29 marca. Święta, za oknem ciepło, na poranek była zaplanowana uczta. W dobrym humorze siadłem do wieczornego przeglądania ulubionego forum, HN.
W oczy rzucił mi się wątek u samej góry. Ponad 700 komentarzy w kilka godzin (parę dni później ponad 1700). Grubsza akcja.

Jak się okazuje, wykryto złośliwy kod w nowej wersji programu często używanego na serwerach. Zagrożenie udało się rozpoznać, nim doprowadziło do większych szkód.
Teraz trwają analizy. Ukazują póki co wyrafinowany atak, rozwijany przez lata. Obejmujący hakerskie triki i psychologiczne usypianie czujności.

Rok temu stworzyłem wielkanocny wpis o ataku pewnej firmy na jej własnych kierowców. Tym razem coś cyfrowego. Aferkowa Wielkanoc zaczyna być tradycją!

Uczciwie przyznam – sprawy cyberbezpieczeństwa znam tylko pobieżnie. Mniej niż rzeczy dotyczące prywatności.
Dlatego będzie to wpis niespecjalistyczny, popularyzatorski. Przybliży świat open source i ciemne strony cyfrowego ekosystemu: masową zależność od nielicznych programów oraz nadużywanie dobrej woli ich autorów.

Szukasz głębszego nura w tę sprawę? To polecam strony polskich bezpieczników, jak analiza Gynvaela Coldwinda. Albo niektóre inne źródła, które tu podlinkuję.

Spis treści

Wprowadzenie

Sprawa dotyczy programu o nazwie XZ oraz jego narzędzi pomocnicznych. Jest obecny na wielu komputerach z systemem Linux. Jak serwery, na których stoi współczesny internet.

Do programu wprowadzono dyskretną zmianę, robiąc z niego potencjalny wytrych. Zamkami, które miał otwierać, miały być rzekomo połączenia przez SSH – powszechną, szyfrowaną metodę panowania nad serwerami.

Potem pojawiły się głosy, że jest jeszcze gorzej, a atak mógł mieć na celu nie tylko włamanie, ale i sabotaż (RCE; uruchomienie złośliwego kodu).
Czym by się nie okazał; byłby groźny i miałby wielki obszar rażenia.

Postać z logo tukana zamiast głowy i w koszulce z napisem XZ trzyma na barkach kulę ziemską z napisem SSH. W jej stronę leci kopniak wymierzony przez inną postać, w stroju mnicha Shaolin, z emotą diabełka zamiast głowy.

Źródło: Emojipedia, ikona projektu Tukaani, Freepik.
Autorzy: siłaczkatemangostar, kopiąca postaćmacrovector, kula ziemskamacrovector_official. Przeróbki moje.

Program i narzędzia XZ

Główny winowajca, program XZ, odpowiada za pracę z plikami skompresowanymi z rozszerzeniem .xz. Ku zdziwieniu niektórych: to całkiem popularny format. Coś jak ZIP ze świata konsumenckiego, tylko że mieści w sobie jeden plik.

Sam XZ jest właściwie tylko nakładką, wygodnym interfejsem. Jego fundament nazywa się liblzma. To on został dotknięty zmianami.
Lib to tutaj skrót od library, biblioteka. Zestaw przydatnych funkcji. LZMA oznacza natomiast metodę kompresji.

Dla uproszczenia będę stosował w tym wpisie zbiorcze określenie XZ wobec wszystkich narzędzi i bibliotek opartych bezpośrednio na „zatrutym” kodzie.

Cały projekt, w ramach którego rozwija się XZ, nosi nazwę Tukaani. Logo projektu to rysunkowy tukan z obrazka wyżej. Założycielem i głównym opiekunem projektu jest od 2009 roku Lasse C., istotna postać w tej historii.

Dzięki lekkości i wszechstronności jego wynalazki zwróciły uwagę innych projektów. A Lasse, niczym Atlas, dostał na barki cały glob. Ale o tym później.

Cyfrowy łańcuch dostaw

Istotną częścią całej sprawy są różne powiązania między projektami open source. Można powiedzieć, że kod spływa z góry, od źródła. W języku angielskim jest ono zresztą nazywane upstream, jak źródło rzeki.

Na początku łańcuszka jest jakiś projekt, jak wspomniany Tukaani. Kod źródłowy jego programów jest na widoku, przechowywany w tak zwanym repozytorium. Tak było też z XZ, choć jego strona jest obecnie zawieszona.

Komunikat mówiący o zawieszeniu dostępu do projektu przez naruszenie warunków serwisu Github

Każdy może czytać kod programów i proponować własne zmiany oraz usprawnienia. Jeśli zostaną zaakceptowane przez osoby opiekujące się projektem – to w ciągu paru sekund zostaną wdrożone.

Każdy program może się przebić i zwrócić uwagę innych projektów, jak Linuksy. Będę używał kolokwialnie liczby mnogiej, bo na bazie jednego Linuksa (jądra) powstało wiele systemów. Zwanych dystrybucjami, rozwijanych często niezależnie od siebie.

Twórcy Linuksów biorą przydatne według nich programy i dodają je do swoich systemów. Czasem jako udogodnienia dla użytkowników, a czasem wręcz jako filary systemu. Kod od XZ bywał bliżej tej drugiej kategorii.

Ostatnim ogniwem łańcuszka są właściciele komputerów (tu głównie firmy mające swoje serwery). Decydują się na Linuksa, bo to system wszechstronny i przyjazny w obsłudze. Wybierają którąś z wielu jego wersji, instalują.

Na tych serwerach opiera się sieć, z której korzystają zwykli użytkownicy. Nie mając pojęcia, że świat stoi na Linuksie.

Schemat zależności. U góry widać pojedynczy plik podpisany XZ. Odchodzą od niego strzałki do ikon kilku wariantów systemu Linux. Od nich z kolei odchodzą strzałki w stronę licznych rysunkowych ikon serwerów.

W praktyce nie każda dystrybucja byłaby równie popularna na serwerach.
Źródło: oficjalne ikony projektów, serwery autorstwa Smashicons (serwis Flaticon).

Przy takich zależnościach „zatrucie źródła” oznacza, że zagrożenie dotknie bardzo wielu serwerów. Mnóstwo rzeczy zależy od kilku nielicznych, popularnych projektów. Dlatego są łakomym kąskiem dla hakerów.
Infekowanie popularnych źródeł nazywa się oficjalnie „atakami na łańcuch dostaw” (ang. supply chain attacks).

Czyżby otwartość kodu na cudzy wkład była wadą? Nie. Powiedziałbym wręcz, że to dzięki tej otwartości w ogóle udało się wychwycić zagrożenie.

Gdzieś na świecie istnieją projekty komercyjne, do których również ktoś dodał niespodzianki. Przez brak przejrzystości trudniej jest taki kod przeszukać i wykryć pułapki. Ale to temat na inną opowieść. Na razie wszystko toczy się w świecie open source.

Atak krok po kroku

Cała historia jest moim zdaniem dużo ciekawsza, jeśli wyjdzie się poza technikalia. Jest to wtedy opowieść o presji społecznej, zdobywaniu zaufania i zdradzie.

Problem zmęczonego opiekuna projektu

Jednym z najciekawszych faktów w sprawie jest to, że cała akcja rozpoczęła się parę lat temu. W momencie, kiedy użytkownik określający siebie mianem Jia Tan wkupił się w łaski Lassego C., twórcy XZ.

Tworzenie własnych projektów open source może być przyjemną odskocznią. Przykład: ja i ten blog. Do tej pory dał mi dużo radości, a interakcje z innymi ludźmi były niemal wyłącznie pozytywne.

Ale nie każdy ma tak fajnie. Czasem zdarza się, że osoba prowadząca popularny projekt doświadcza presji, żeby dodawać nowe rzeczy.
Jakiś korpoludek potrzebuje programu, ale nie umiałby samodzielnie go zmodyfikować. Więc naciska na twórców, żeby wprowadzili potrzebne mu zmiany.

Im większy projekt, tym większa presja. U niektórych osób z własnymi projektami rośnie również poczucie odpowiedzialności.
Gdy zaczynali, projekt mógł być małą, radośnie szlifowaną kulką. Ale presja społeczna potrafi zrobić z niego glob, który muszą trzymać na barkach. Jak tytan Atlas.

Na ten temat powstał nawet bardzo trafny obrazek:

Obrazek pokazujący stos klocków ułożonych na sobie, podpisanych 'współczesna cyfrowa infrastruktura'. Prawie cała piramida opiera się na drobnym, pojedynczym klocku, podpisanym jako element utrzymywany przez losową, niedocenianą osobę od 20023 roku.

Źródło: XKCD.

Podobna sytuacja dotknęła Lassego od XZ, którego projekt miał na karku już kilkanaście lat. I zaczynał budzić u autora poczucie wypalenia. Wtedy pojawiła się postać skora do pomocy, przedstawiająca się jako Jia Tan.

Ciekawą chronologię zdarzeń, obejmującą pierwsze kroki JT w świecie open source, można znaleźć na stronie boehs.org.

Dobry i zły glina

Znaną metodą prowadzenia przesłuchań jest podział ról na dobrego i złego.
Jedna postać jest wyjątkowo niesympatyczna, pomiata przesłuchiwanym. Druga zapewnia z kolei ludzkie ciepło i zrozumienie. Dzięki temu osłabia czujność i może wyciągnąć informacje.

Opis z boehs.org wydaje się sugerować, że coś takiego zaszło w tym przypadku. Pojawiło się konto, które wywierało presję na Lassego, właściciela całego projektu.

Interakcje można znaleźć na publicznej liście mailingowej. W dyskusji z kwietnia 2022 roku biorą udział zarówno Jia, jak i niejaki Jigar K. Ten drugi narzeka na opieszałość Lassego:

Patrząc na powolne tempo aktualizacji, niestety miną lata, zanim społeczność w ogóle dostanie tę przydatną poprawkę.

Tłumaczenia wszystkich maili i postów moje.

Jia odpowiada grzecznie, ale wydając się trzymać stronę Lassego:

Nad tym projektem pracują hobbyści. Nie możemy poświęcać ponad 40 godzin tygodniowo na szybkie wypuszczanie rzeczy wysokiej jakości. Dzięki za zrozumienie

Ale Jigar wciąż naciska, wprost sugerując, żeby Jia wziął sprawy w swoje ręce:

Czy są jakieś postępy w tej sprawie? Jia, widzę jakieś niedawne commity od ciebie. Dlaczego nie możesz sam wprowadzić zmian?

Commit to pojedynczy, często opisany zestaw zmian w kodzie źródłowym. Może mieć dowolny rozmiar, od jednego znaku po całe pliki.

Takie komentarze się powtarzały również w innych wątkach. W jednym z nich Lasse w końcu nie wytrzymał i wprost napisał, że jest zmęczony całym projektem. Przy okazji wypowiedział słowa, które niestety okazały się prorocze.

Ostatnio Jia Tan i ja trochę współpracowaliśmy nad XZ Utils poza listą [mailingową], być może odegra w przyszłości większą rolę, zobaczymy.
Warto też pamiętać, że to projekt hobbystyczny, za który nikt nie płaci.

Nawet po tych słowach Jigar nie dawał za wygraną i naciskał na zmiany.

Dusisz teraz własne repo. Po co czekasz ze zmianą właściciela do wersji 5.4.0? Po co opóźniasz to, czego potrzebuje twoje repo?

„Dej, dej”. Jak pewien znany typ ludzi, gdy wrzuci się coś darmowego na OLX-a. Możliwe, że wobec takiej presji autor nie miał nic przeciwko, żeby Jia zdjął mu z barków nieco ciężaru.

Jia przejmuje stery

Jia był jak złota rączka, angażując się w najróżniejsze działania związane z XZ. Pewien użytkownik Mastodona doliczył się 750 commitów od tej postaci.

W 2023 roku opracował nawet logo dla programu, w czterech wariantach kolorystycznych.

Zrzut ekranu strony projektu Tukaani, widać na nim logo programu XZ. Jako autor wpisany jest Jia Tan.

Poza tym opracowywał testy i dodawał pliki testowe.
To ważna część projektów open source. Ale nieraz olewana, jeśli twórcy wolą skupić się na bajerach. Poświęcanie uwagi szlifom i fundamentom mogło sugerować, że nowemu współpracownikowi autentycznie zależy na rozwoju projektu.

Z czasem Jia stał się de facto motorem napędowym XZ. Na zarchiwizowanej stronie można znaleźć informację, że od wersji 5.4.3 to on składał cyfrowy podpis na aktualizowanych plikach.

Jia zdejmuje maskę

Po zyskaniu zaufania Jia zaczął wprowadzać w tym roku subtelne, groźne zmiany w kodzie.

Schemat pokazujący, w jakich dniach i godzinach Jia wprowadzał zmiany w kodzie. Zmiany złośliwe wyróżniają się tym, że dodano je w środku nocy.

Groźne zmiany wyróżniają się tym, że dodano je w innych godzinach niż zwykle. Do wątku naprawienia błędów Valgrinda jeszcze wrócę.
Źródło: tweet użytkownika birchb0y.

26 lutego dokonał sabotażu „kropką nienawiści”. Przez umieszczenie jej w kodzie powodował błąd, przez który nie włączał się Landlock. Taki dobrowolny ogranicznik stosowany przez XZ, dzięki któremu odbierał sobie dostęp do wrażliwych funkcji systemu.

Oto historia zmian wprowadzonych tego dnia. Plusy oznaczają dodane linijki kodu.
Przy tym interfejsie, wśród wielu zmian, łatwo przeoczyć kropkę na początku linijki, zlewającą się z plusem.

Zrzut ekranu pokazujący kilka linijek dodanych do kodu. Jedna z nich to samotna kropka

Broń ukryta w testach

Zabójcza kropka była tylko pomocą przy ataku. Opus magnum naszego hakera to wykorzystanie plików testowych do ukrycia swoich narzędzi. Tak; tych samych plików, które dodawał, wydając się umacniać fundamenty projektu.

Jeden z plików z założenia miał być popsuty, żeby testy sprawdzały działanie XZ przy wadach formatu. Drugi miał normalną treść, rozpakowywał się, działał jak powinien.

Oba zawierały w sobie narzędzia hakera, głównie skrypty w języku Bash. Ukryte w plikach jak bronie partyzantów w skrytce pod ściółką leśną.

Intuicyjne wyjaśnienie

Ta dwoista natura (normalność, a zarazem złośliwość) wynika z prostego faktu – każdy plik jest ciągiem zer i jedynek.
Owszem, istnieje jakiś właściwy sposób ich czytania, przy którym plik zadziała tak, jak oczekują tego użytkownicy. Ale można również brać te same zera i jedynki, robiąc z nimi rzeczy kreatywne.

Przykład? Ktoś może wskazać swojemu programowi jakiś zero-jedynkowy plik i nakazać: „weź sześćdziesiąty piąty element (zero/jedynkę). Potem bierz kolejne, do numeru 72 włącznie”. Program po kolei je zbiera i zostaje z ciągiem 01100001.

Następnie autor każe: „zrób z tego literę w podstawowym kodowaniu (ASCII)”. Wynik to a, bo właśnie taka litera odpowiada tym zerom i jedynkom.

Te zera i jedynki z założenia nie miały być żadną literą. Były cząstką całkiem innej struktury. Ale jeśli ktoś każe zrobić z nich literę… to program posłucha.

To dlatego atakujący mógł stworzyć pełnoprawny, działający plik. W którym jednocześnie ukrywa sobie różne rzeczy. Po odpowiednich przekształceniach może je sobie wyciagnąć.

Jeśli chodzi o zawartość hakerskich skryptów, mało się znam na temacie, więc zdam się tu na opracowanie Gynvaela Coldwinda. Jeśli dobrze interpretuję:

  • Punktem początkowym jest zwięzły skrypt umieszczony wśród innych plików projektu.

    Według innego komentarza dodany nie do wersji źródłowej, lecz tylko do tej przeznaczonej do rozpowszechnienia.
    Jest uruchamiany podczas kompilacji. Czyli przekształcania kodu do postaci dostosowanej do komputera. Zachodzi ona za każdym razem, gdy ktoś tworzy z kodu źródłowego XZ nową wersję programu.

  • Ten zwięzły skrypt „naprawia” jeden z plików testowych, bad-3-corrupt_lzma2.xz (poprzez kilka działań typu „znajdź i zamień”).
    Część naprawionej zawartości pliku to skrypt ukryty tam wcześniej przez hakera.

  • Wyciągnięty skrypt zostaje uruchomiony i sięga do drugiego pliku testowego, large_compressed.lzma.
    Tym razem naprzemiennie olewa i wyciąga niektóre jego elementy. Układając z nich sobie kolejny skrypt.

  • Na tym etapie kończy się wyciąganie hakerskich narzędzi z plików testowych. Skrypt hakera gmera przy różnych ustawieniach kompilacji, a także wrzuca do wnętrza XZ własny zero-jedynkowy plik, zapewne najgroźniejszą część.

    Pełna treść skryptu jest tutaj. Nie będę udawał, że go rozumiem, ale widać że zmienia różne parametry, jak CPPFLAGS.

Ciekawostka

Jak pisze Gynvael Coldwind, w tym miejscu występuje również odwołanie do innych plików testowych, które miałyby w sobie odpowiednie ciągi zer i jedynek. Takich plików nie było w żadnej ze zmodyfikowanych wersji źródła.
Zgodnie z hipotezą Coldwinda, Jia zapewne planował dodać je w przyszłości. Pozwoliłyby rozbudowywać kolejne wersje XZ o nowe wredne funkcje.

Ostatecznie następuje normalna kompilacja. Ale przez wprowadzone zmiany powstaje wariant XZ (oraz innych bibliotek) z tak zwanym backdoorem. Cyfrową furtką do wykorzystania przez inne, wiedzące o niej programy. W tej postaci trafia do różnych Linuksów.

Nie wiem, na czym dokładnie polega zagrożenie ze strony zmienionego XZ, bo nadal trwają analizy. Ale na pewno robił coś więcej, niż niegroźna kompresja i dekompresja.

Udoskonalenie złośliwego kodu

Groźna niespodzianka została dodana w wersji 5.6.0. Ale na tym etapie program miał swoje wady. Odrobinę porównań między wersjami można znaleźć we wspomnianej analizie Coldwinda.

Jednym z problemów był fakt, że program Valgrind (do analizowania zużycia pamięci) wyłapywał różne błędy i wyświetlał ostrzeżenie na etapie kompilacji.

A to niedobrze dla hakera. Ostrzeżenia, nawet jeśli nie mówią wprost o czymś złym, kłócą się z dyskrecją.

Dlatego… po prostu nie ukrywał błędu, pytając innych o porady i dziękując za poprawki. Oczywiście nie ujawniał prawdziwych intencji. Wspólną pracą, między innymi z ludźmi od linuksowych projektów Red Hat i Fedora, udało się załatać błędy. Jia wypuścił udoskonaloną wersję 5.6.1.
Nikt się nie połapał, że coś jest na rzeczy.

Lobbowanie za przyjęciem nowinek

Haker osiągnął swój cel. Nowa wersja XZ była „zaminowana”, a najnowsza była ponadto dyskretniejsza, nie prowadząc do podejrzanych ostrzeżeń.

Kolejnym krokiem było rozpowszechnienie kodu. Sprawienie, żeby różne warianty Linuksa przygarnęły zmodyfikowane wersje.

Jak wspomina ktoś na forum HN, napastnik już wcześniej krążył wokół decyzyjnych osób od różnych Linuksów i zachęcał do przyjęcia nowej, zaminowanej wersji XZ:

autor tej furtki kontaktował się ze mną przez kilka tygodni, chcąc żebym dodał XZ w wersji 5.6.x do Fedory 40 i 41, ze względu na jego „świetne nowe funkcje”

Źródło: komentarz z HN. Fedora to jeden z wielu wariantów systemu Linux, całkiem popularny.

Również na liście mailingowej pojawiło się więcej osób wskazujących, że mają kłopoty z Valgrindem, więc chętnie by przyjęli nową wersję XZ. Naciski nieco podobne do tych wywieranych wcześniej przez Jigara.

Dodatkowe komunikaty z Valgrinda sprawiają, że nie przechodzi u mnie część testów. Ta nowa wersja powinna to rozwiązać. Chciałbym ją mieć, żeby móc dalej hakować pracować.

Pod względem skuteczności ten lobbing mógłby zawstydzić nawet trolle od firmy Monsanto! Nowy promowany XZ trafiał do kolejnych Linuksów.

Wykrycie furtki

Złośliwy kod wykrył pewien programista, Andres Freund. Łączył się z bazą i zauważył anomalię. Wszystko działało wolniej.

Dostrzegł, że dziwne działanie było związane z programem sshd. Służącym do łączenia się z serwerem w szyfrowany sposób.
To trochę jak wpisywanie hasła do swojego laptopa, żeby wyświetlił się pulpit. Tyle że maszyna może być dużo dalej, a zamiast pulpitu jest tekstowa konsola.

Kiedy dostrzegł, co się święci, dał znać autorom projektów. A po ustalonym czasie wszczął alarm. To właśnie informacje od niego wywołały poruszenie, o którym napisałem na początku.

Na tym etapie różne dystrybucje Linuksa przywróciły awaryjnie starszą wersję XZ i powiązanych narzędzi. Serwis Github zablokował konta hakera i samego projektu.

Zaś Lasse od XZ – co widać na innej, niezablokowanej stronie z kodem źródłowym – zaczął usuwać niekorzystne zmiany, takie jak wspomniana kropka grozy.

Póki repozytorium nie zostało usunięte, widać było komentarze różnych ludzi pod jego adresem. Zarzucające, że niedostatecznie mocno trzymał glob, na którym siedli.

Ciekawostka

W normalnych warunkach SSH oraz XZ byłyby rzeczami niezwiązanymi ze sobą.
Ale wersja programu OpenSSH na wielu Linuksach jest zmodyfikowana, żeby wspierać inny moduł, systemd. Który już korzysta z XZ, łącząc te dwa światy.

Swoje odkrycie autor opatrzył ironicznym komentarzem: „systemd uderza ponownie!”.

W światku Linuksa budzi on niemałe kontrowersje. To zestaw złożonych programów działających w tle i ingerujących w różne funkcje systemu. Czasem zarzuca się im próbę bycia wszystkim naraz, wbrew linuksowej konwencji drobnych i niezależnych programów.

Póki co wygląda na to, że udało się zapobiec większemu atakowi. Ludziom zaleca się cofnięcie do starszych wersji XZ. Być może nawet do tych sprzed działalności pana J. A na pewno do innych niż 5.6.0 oraz 5.6.1.

Trwa również analizowanie tej bardziej tajemniczej, nieprzejrzystej części złośliwego kodu. Postępy można śledzić chociażby na forum HN.

Podsumowanie

Sprawa wokół XZ nie jest niczym nowym. Choć zaskakuje wyrafinowaniem, jest jednym z wielu ataków na źródła powszechnie używanych programów.
Innym głośnym przykładem, tyle że z korpoświata, była afera wokół SolarWinds.

Cała historia potwierdza, że centralizacja to miecz obosieczny. Również w świecie cyfrowym.

Z jednej strony pozwala uniknąć powtarzania się, wielokrotnego wymyślania koła od nowa. Rozwój jakiegoś elementu zostawia się specom, a reszta tylko od nich czerpie.

Z drugiej – to zależność od kogoś innego. Być może nieco mniej groźna w cyfrowym świecie, gdzie łatwiej skopiować kod i się uniezależnić… Ale wciąż pozostaje wkładaniem wszystkich jajek do jednego koszyka. Jak rypnie, to potężnie.

A większość przegapia moment, gdy wiklina koszyka zaczyna się rozłazić. Bo każdy sobie myśli, że inni na pewno uważnie patrzą. Że można olać temat.

Wątek roszczeniowości

Afera ukazuje również wątek niedocenianych twórców open source. Być może Jigar z tej konkretnej historii był akurat podstawionym „złym gliną”, nie wiem. Ale wokół znalazłoby się wielu innych, którzy przejąć projektu nie planują, a są tak samo roszczeniowi.

A twórcy, próbując sprostać oczekiwaniom, z czasem tracą radochę z dzieła, które tak długo dopracowywali.

Dlatego w tym miejscu podzielę się radą.
Czytelniczko, czytelniku. Jeśli tworzysz publiczny kod albo inne utwory i ktoś wywiera presję, to pamiętaj – twoje życie ponad wszystko, masz jedno.

Póki ludzie kontaktują się w sposób cywilizowany, to super. Można powymieniać się przemyśleniami, posłuchać sugestii.

Ale gdy jakiś Jigar naciska z pasywną agresją, publicznie cię upokarza, pisze „potrzebujemy” albo „wiele osób potrzebuje” – to robi taki psychologiczny odpowiednik nadymania się jak ropucha. Próbuje wydać się większy. Rozgnieć go.

Nie ma żadnej grupy, żadnego wyższego interesu, nie trzeba trzymać globu. To tylko jakiś „dej-dej” próbuje pogorszyć twoje życie, żeby poprawić własne.
Uzasadnioną odpowiedzią wobec takiego kogoś jest blokada. Albo „spieprzaj”.

Stanowczość na pewno ratuje dobrobyt psychiczny. A może nawet, kto tam wie, zapobiegnie wejściu hakera :wink: