Zapewne większości z nas zdarzyło się wysłać komuś screenshota, nazywanego krócej screenem albo, po polsku, zrzutem ekranu. W ten sposób możemy łatwo podzielić się z innym człowiekiem tym, co widzimy u siebie na ekranie.
Ale czasem kopia całego naszego ekranu to za dużo, a interesująca jest tylko niewielka część. Po co dzielić się górnym paskiem telefonu? Nie ma tam nic cennego – co najwyżej ktoś pośmieszkuje, jeżeli według licznika zostało nam 3% baterii.
Na szczęście zwykle łatwo możemy przyciąć screeny przed wysłaniem.
Włączamy jakiś domyślny systemowy program, zaznaczamy obszar na większym obrazku. Na naszych oczach reszta obrazka znika, a w podglądzie widzimy już tylko nasz wycinek. Wysyłamy go swoim odbiorcom.
I tutaj właśnie pojawił się problem. Niedawno wyszło na jaw, iż domyślne funkcje wbudowane w Pixele (telefony Google’a) oraz system Windows nie zawsze usuwały przycięte rzeczy, zostawiając w pliku z obrazkiem potencjalnie prywatne dane.
W tym wpisie w jak najprzystępniejszy sposób omówię całą sprawę. Zapraszam! :smile:
Źródło: Wikipedia, zdjęcie Erin Silversmith + post Simona Aaronsa. Przeróbki moje.
P.S. Brodacz to bóg Tiberinus, a to coś w jego dłoni to róg obfitości :wink:
O obrazkach słów kilka
Żeby wpis miał jakąkolwiek wartość edukacyjną, pozwolę sobie dodać parę podstawowych, bardzo luźnych informacji na temat obrazków i kodowania. Bez obaw, będzie bezboleśnie!
A jeżeli ktoś już to wszystko wie – albo wiedzieć nie chce – to może przeskoczyć prosto do aferki.
Za podstawową „jednostkę budulcową” obrazka możemy uznać piksel. zwykle przedstawia się go w postaci RGB (ang. Red, Green, Blue).
Na czym to polega? Ano na tym, iż każdemu pikselowi odpowiadają trzy liczby. Wskazują, jakie jest w nim natężenie kolorów: czerwonego, zielonego i niebieskiego. 0 to najmniejsza możliwa wartość koloru, zaś 255 – największa.
Załóżmy, iż mamy taki minimalistyczny obrazek:
Składa się on z trzech pikseli (0,255,209) oraz jednego piksela (255,0,0) (czystej czerwieni).
Chcemy zapisać ten obrazek jako szereg instrukcji, które pozwolą różnym programom wyświetlać go na ekranie. W najprostszym przypadku opiszemy go piksel po pikselu, od lewej do prawej:
2. Masz piksel w kolorze (0,255,209)
3. Masz piksel w kolorze (0,255,209)
4. Masz piksel w kolorze (255,0,0)
Taki sposób jest jednak strasznie niewydajny, kilka razy się powtarzamy!
Dlatego zastosujmy jakąś bida-kompresję. Na przykład zapisując nasz obrazek w tak zwanym kodowaniu Run-Length Encoding.
Polega ono na tym, iż w każdej instrukcji umieszczamy informację o tym, ile mamy pod rząd pikseli w jednym kolorze:
2. Masz 1 piksel w kolorze (255,0,0)
Na pierwszy rzut oka widać, iż metoda druga jest bardziej zwięzła, prawda? :wink: A będzie tym bardziej wydajna, im więcej mamy identycznych pikseli pod rząd. Jedynym wymogiem jest to, żeby programy odczytujące obrazek „rozumiały” nasze instrukcje.
Wniosek jest prosty – kompresja się opłaca, zwłaszcza w obecnych czasach, gdy obrazki przesyła się na masową skalę. Dlatego od dawna są czymś więcej niż prostą listą pikseli. Ba, w praktyce bywają naszpikowane hardkorowymi metodami kompresji.
Cały czas opracowuje się nowe formaty, lepiej dopasowane do współczesnych obrazków. HEIF, WEBP, JPEG-XL… Dlatego gdyby ktoś zapytał, czym są za kulisami obrazki, to najsensowniejszą odpowiedzią wydaje się „to zależy”.
W naszym przypadku problemy nie dotyczą jednak tych nowych formatów, tylko leciwego już (i bardzo popularnego) PNG. Który, choć stary, jest również dość złożony.
Problem fałszywego zakończenia
Opis problemu w moim wykonaniu będzie bardzo luźny i nieścisły. Raczej nijak się ma do tego, jak naprawdę działa format PNG. Chodzi mi po prostu o pokazanie pewnej intuicji, modelu myślowego. Kto pragnie ścisłej wiedzy, ten może przeczytać post Davida Buchanana.
Ktoś z twórców formatu PNG uznał – z tego czy innego powodu, ale obstawiam iż dla większej elastyczności – iż obrazek PNG nie będzie się tak po prostu kończył na ostatnim pikselu.
Wyobraźmy sobie, iż zawiera osobną instrukcję. Mówiącą, iż już koniec, można przestać czytać plik.
Problem w tym, iż po tej instrukcji może się znajdować więcej danych.
3. Masz piksel w kolorze (0,255,209)
4. Masz piksel w kolorze (255,0,0)
5. KONIEC
6. Masz piksel w kolorze (66,66,66)
...
Każdy sensowny program będzie czytał ten plik „linijka po linijce”. Zatrzyma się na punkcie 5 – bo po co dalej pracować, kiedy każą przestać?
Wyświetli nam to, czego się spodziewaliśmy. A my nie będziemy mieli najmniejszego pojęcia, iż w obrazku ukrywa się coś jeszcze.
Ktoś z Google’a, prawdopodobnie nie znając niuansów formatu, wpadł w pułapkę. I teraz oficjalnie przechodzimy do naszej aferki.
Google Pixel i początek historii
Wszystko odkryła dwójka badaczy zajmujących się cyberbezpieczeństwem – David Buchanan i Simon Aarons. Zgłosili sprawę Google’owi, a kiedy firma już naprawiła lukę, to dokładniej ją opisali.
Otrzymała ona kryptonim Acropalypse, czasem dla czytelności zapisują ją również aCropalypse. To połączenie słów crop (przycięcie/kadrowanie obrazka) oraz apocalypse (apokalipsa).
17 marca Aarons opublikował krótki opis zagrożenia na Twitterze. Dzień później podał również link do stronki pozwalającej osobiście sprawdzić, czy nasze zdjęcia mają ukryte dane.
Problem dotyczył aplikacji systemowej Markup – domyślnie zainstalowanej na telefonach marki Pixel, produkowanych przez Google’a. Służy ona do prostej obróbki obrazków.
Aplikacja, zamiast zapisać wycinek do nowego pliku, wstawiała go na początek poprzedniego. Jak pokazałem wyżej, z punktu widzenia użytkownika nowy obrazek działał normalnie, bo większość apek czyta dane tylko do czasu, aż napotkają instrukcję kończącą. A reszta pikseli spokojnie sobie tkwi w obrazku.
Gdyby ktoś wszedł w posiadanie takiego nadpisanego obrazka, to mógłby użyć specjalnego programu do odzyskiwania danych. I wyciągnąć sporą część oryginału, sprzed przycięcia, wraz z wrażliwymi danymi:
Źródło: schemat Aaronsa, przeróbki moje.
Całe zagrożenie nie jest ponoć takie stare, bo wiąże się ze zmianą wprowadzoną przez Google w wersji 10 Androida.
Zmienili tam działanie pewnej funkcji zapisującej. Zamiast nadpisywać pliki, po prostu wrzucała nowe dane na początek istniejących. Apka Markup z tej funkcji korzystała, zapisując pliki PNG.
W ten sposób powstał nam swoisty łańcuszek niefortunnych zdarzeń.
Nikt nie wychwycił, iż rozmiar obrazu po przycięciu jest identyczny albo prawie identyczny jak rozmiar oryginału. Ani iż obrazek zawiera dane choćby po oficjalnym znaczniku kończącym (co wychwyciłby choćby program exiftool).
Intuicyjnie o artefaktach
A skąd wzięły się te dziwne kolorowe kreski na obrazku (fachowo zwane artefaktami)?
Intuicyjnie możemy sobie wyobrazić, iż „naklejamy” nowy mniejszy obrazek na początek naszego starego, przez co wartości częściowo się nakładają. I zostajemy z czymś takim:
1. Masz piksel w kolorze (0,255,209)
2. Masz piksel w kolorze (0,255,209)
3. KONIEC 5, 209)
4. Masz piksel w kolorze (255,0,0)
...
Widzimy, iż mocno popsuła nam się linijka 3.
Obstawiam, iż wiele normalnych programów nie wyrzuci żadnego błędu. Bo zatrzymają się na instrukcji KONIEC i nie zrobią dalszego kroku w przepaść – tam, gdzie zderzyłyby się z błędami w formacie.
Programy specjalnie dopasowane do takich sytuacji, jak ten napisany przez badaczy, będą czytały dalej. Ale nie odzyskają wszystkiego, bo, jak widzimy, wartość została częściowo nadpisana. Nie da się w całości ustalić, co tam było.
W praktyce tymi nakładającymi się rzeczami nie będą oczywiście pojedyncze piksele, tylko jakieś bardziej złożone struktury, z których korzysta PNG. Ale efekt końcowy będzie zbliżony – przez chwilę mamy syf i chaos (artefakty), a potem już normalne, czytelne piksele.
Jeśli mamy szczęście, to zakryją nam akurat te poufne informacje, na których nam zależy.
Windows dołącza do gry
Ktoś mógłby powiedzieć, iż telefony Pixel, w dodatku o określonej wersji, to przypadek dość rzadki, więc raczej mało komu zaszkodził. Do tego wiele serwisów i portali społecznościowych od dawna kompresuje obrazki, czego nie przetrwałyby żadne nadmierne piksele.
Platforma Discord, podana przez badaczy jako przykład, również od jakiegoś czasu czyści obrazki.
Telefony inne niż Pixele niekoniecznie korzystają z feralnej funkcji. Autor alternatywnego systemu GrapheneOS wprost napisał, iż nie dotyczy ich to zagrożenie.
Czy zatem luka dotyczy nielicznych i została załatana, mamy szczęśliwe zakończenie? Wręcz przeciwnie, napięcie rośnie :smiling_imp:.
Odkrycie sprawiło, iż badacze zaczęli się rozglądać za podobnymi lukami bezpieczeństwa.
Jeden z nich, Chris Blume, napisał 21 marca na Twitterze, iż widzi podobne nieścisłości w rozmiarach plików edytowanych przez Narzędzie Wycinania
(ang. Snip & Sketch; według niektórych problem dotyka też dawnego Snipping Tool, ale nie za bardzo mam jak sprawdzić).
To domyślny program do screenshotów, dołączony od dawna do systemu Windows. A zatem znacznie bardziej popularny.
David Buchanan przyjrzał się tej sprawie. I zareagował dość żywiołowo. Pozwolę sobie zacytować (z mikrocenzurą, coby mi bloga nie strącili):
David Buchanan
holy F*CK.Windows Snipping Tool is vulnerable to Acropalypse too.
An entirely unrelated codebase.
The same exploit script works with minor changes (the pixel format is RGBA not RGB)
Tested myself on Windows 11
Przyczyny podobne jak u Google’a. Systemowe funkcje do zapisywania plików nie zawsze działały intuicyjnie, ktoś oparł na nich systemowe narzędzie do screenów, format PNG nie protestował, testy nie wyłapały różnic w rozmiarze plików.
Całość dokładniej opisał inny badacz, Steven Murdoch.
Ludzie z Windowsa dowiedzieli się o sprawie i podobno załatali wszystko aktualizacją z 22 marca.
Nie zmienia to faktu, iż we wcześniej zrobionych screenach już mogą tkwić sekrety. Zaś nasza aferka oficjalnie wyszła poza jakiegoś niszowego Pixela i stała się czymś znacznie ogólniejszym, mogącym dotykać większe grono użytkowników.
Kwestia Worda
Skoro już jesteśmy przy Microsofcie, to rozwinę wątek. Pewien użytkownik Twittera zwrócił uwagę na to, iż również z dokumentami Worda trzeba uważać, bo pierwotny obrazek może pozostać w pliku wraz z wersją przyciętą. Wskazuje tam również ustawienie, które pozwoliłoby się przed tym chronić.
Od siebie dodam, iż do wnętrza takich dokumentów wbrew pozorom łatwo się dobrać. Można je rozpakować jak zwykły plik ZIP – co w przypadku Windowsa może wymagać zmiany rozszerzenia z .docx na .zip. A po rozpakowaniu wnętrze pliku stoi otworem, wraz ze wszystkimi obrazkami.
Znany jest przypadek co najmniej jednej osoby (prezenterki telewizyjnej), która miała przykrości przez przycięte zdjęcie – choć akurat przez metadane, a nie piksele po znaczniku kończącym.
Na swoim blogu umieściła zdjęcie twarzy, ale ktoś pobrał plik i odkrył, iż znajdowała się w nim miniaturka fotki oryginalnej, sprzed przycięcia, nieusunięta przez Photoshopa. Fotki, dodajmy, częściowo nagiej.
Pewien użytkownik wspomina ten przypadek w wątku pod pierwszym tweetem Aaronsa.
Inne wątki
Sprawa przez cały czas się rozwija. Na fali odkrycia prawdopodobnie przybyło badaczy prześwietlających inne programy. Wszystko, co nie nadpisywało całkowicie pliku PNG, tylko „nakładało” nowy obrazek na jego początek, również może być podatne na Acropalypse.
Z tego względu zainteresowani mogą dalej śledzić rozwój wypadków – hasło acropalypse jest na szczęście bardzo unikalne, więc łatwo je znaleźć.
Dla ułatwienia podsyłam parę miejsc, w które warto zerkać:
- wyniki ze strony HackerNews;
- wyniki z Nittera (gdyby link nie działał, można wpisać hasło w wyszukiwarkę Twittera);
Czy to dla nas groźne?
Choć Acropalypse jak najbardziej może ujawniać niektóre dane, warto zaznaczyć, iż na szczęście byłby groźny tylko w szczególnych okolicznościach. Muszą zajść wszystkie naraz:
- Poza wyciętym obszarem jest coś prywatnego, czego byśmy nie chcieli ujawniać;
-
Otwieramy plik konkretnym programem (Narzędzie Wycinania na Windowsie, Markup na Pixelu, ew. jakieś dotąd nieodkryte kombinacje) i go przycinamy
(nie mam tu 100% pewności, ale prawdopodobnie błąd nie miałby miejsca przy samym łapaniu pierwszego screena, jedynie przy otwieraniu i przycinaniu wcześniej zapisanego pliku);
- Dane spoza wycinka nie zostaną przykryte artefaktami (kwestia być może losowa);
- Końcowy obrazek nie zostanie poddany dalszym przekształceniom, konwersji itp.
Ostatni punkt wymaga odrobiny wyjaśnienia.
Wiele serwisów (Facebook, Google Photos) dla oszczędności miejsca kompresuje obrazki, które na nich umieszczamy. W tym celu dość mocno je przekształcają, czasem zmieniają format. A to daje nam sporą szansę, iż sekrety ukryte w obrazkach staną się niemożliwe do odczytania.
Gdybyśmy natomiast trzymali obrazki gdzieś, gdzie pozostają w stanie niezmiennym (dysk własnego urządzenia, Discord sprzed paru lat czy choćby Dysk Google’a), to sekrety jak najbardziej byłyby dostępne.
Te punkty wydają się dość gęstym sitem przesiewowym. Nie wykluczam, iż niektóre wydają się całkiem łatwe do spełnienia (pkt.1 – przycinamy specjalnie po to, żeby coś ukryć; pkt. 2 – domyślny program jest najłatwiej dostępny). Ale żeby zaszło wszystko naraz, to musielibyśmy mieć pecha.
W związku z tym osobiście wątpię, żeby wiele osób bezpośrednio ucierpiało przez Acropalypse. Ale świat jest wielki, więc gdzieś prawdopodobnie trafią się takie przypadki.
Najgorsze jest to, iż zagrożenie działa wstecz. Kiedy pechowy screen raz zostanie zapisany na dysku, to można do niego wrócić w dowolnym momencie. prawdopodobnie różnej maści zbieracze danych już zaktualizowali skrypty i przeszukują swoje kolekcje, szukając nowych tropów.
Podsumowanie i porady
Sprawa Acropalypse może być dla nas przestrogą – zagrożenia dla prywatności mogą przyjść z najmniej spodziewanej strony. I działać wstecz, więc rzecz wrzucona przed laty do internetu może nas kiedyś ugryźć.
W tej sprawie wyróżniłbym kilku głównych „winowajców”:
- złożoność współczesnych formatów,
- niefrasobliwe wprowadzanie zmian w „złączkach” między systemem a programami,
- dziurawy proces testowania i weryfikacji u Google’a i Microsoftu.
Pierwszy punkt może być trudny do naprawienia, ale firmy jak najbardziej mogłyby co nieco uszczelnić po swojej stronie. Tym niemniej, zamiast na nich polegać, warto samodzielnie zadbać o bezpieczeństwo.
Na pewno nie zaszkodzi minimalizacja danych na jak najwcześniejszym etapie. Skoro programy mogą nas zawodzić, to na nich nie polegajmy.
W praktyce: zadbajmy o to, żeby już na początkowym screenshocie nie było nic cennego ani tajnego. Chcąc dodać zdjęcie swojej twarzy, nie wycinamy go z rozebranej fotki. Robimy całkiem osobne zdjęcie.
Chcemy zrobić screena pokazującego tylko fragment ekranu, zaś obok jest coś wrażliwego? Zmniejszamy okno, ustawiamy rozmiar powiększenia (w przeglądarkach – opcje z prawego górnego rogu, obok słowa Powiększenie). Następnie naciskamy Alt+PrintScreen, żeby zrobić zdjęcie wyłącznie naszego aktywnego okna, a nie całego ekranu.
Jeśli szczególnie się obawiamy, to można otworzyć plik w programie graficznym, a następnie zapisać go w innym formacie niż początkowy. Mało co poza samymi pikselami – czyli tym, co chcemy – przetrwa taką konwersję.
Warto przy tym pamiętać o innych potencjalnych pułapkach związanych z plikami, które miałem przyjemność opisać na blogu.
Pułapka pierwsza – w zdjęciach mogą być czasem zaszyte dane z GPS-a, jasno pokazujące miejsce, w którym zrobiono zdjęcie.
Pułapka druga – gdy edytujemy niektóre formaty plików, jak PDF, nie wystarczy zakrycie tekstu czarnym prostokątem. Bo cały tekst przez cały czas będzie pod spodem, łatwy do skopiowania.
Życzę Wam fotek bez tajemnic i (jakkolwiek to brzmi) żeby nikt Wam nie przywracał rzeczy uciętych :smile: