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śli 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, że 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:

Przerobiony obrazek pokazujący rzymską statuę półleżącego brodatego mężczyzny, trzymającego w ręku róg obfitości. Jego twarz otacza jasna ramka o czerwonych rogach, zaś reszta obrazka, na której widać jego półnagie ciało, jest przyciemniona, tak jakby tylko twarz miała zostać wycięta z obrazka. U dołu widać napis Acropalypse.

Źródło: Wikipedia, zdjęcie Erin Silversmith oraz 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!

Za podstawową „jednostkę budulcową” obrazka możemy uznać piksel. Zazwyczaj przedstawia się go w postaci RGB (ang. Red, Green, Blue).
Na czym to polega? Ano na tym, że 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, że mamy taki minimalistyczny obrazek:

Cztery kwadratowe piksele ustawione w jednej linii. Pierwsze trzy mają taki sam seledynowy kolor, zaś ostatni ma kolor czerwony

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:

1. Masz piksel w kolorze (0,255,209)
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, że w każdej instrukcji umieszczamy informację o tym, ile mamy pod rząd pikseli w jednym kolorze:

1. Masz 3 piksele w kolorze (0,255,209)
2. Masz 1 piksel w kolorze (255,0,0)

Na pierwszy rzut oka widać, że 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 dobrą 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

Uwaga

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 że dla większej elastyczności – że obrazek PNG nie będzie się tak po prostu kończył na ostatnim pikselu.

Wyobraźmy sobie, że zawiera osobną instrukcję. Mówiącą, że już koniec, można przestać czytać plik.
Problem w tym, że 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, że w obrazku ukrywa się coś jeszcze.

Ktoś z Google’a, zapewne 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:

Schemat pokazujący w górnej części post na platformie Discord, w którym ktoś chwali się nową kartą, a pod spodem widać zdjęcie tej karty. Od tego miejsca odchodzi w dół strzałka, podpisana 'Pobranie zdjęcia i użycie specjalnego programu'. W dolnej części widzimy pełen obrazek, z widocznymi danymi dotyczącymi karty

Ź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ł, że rozmiar obrazu po przycięciu jest identyczny albo prawie identyczny jak rozmiar oryginału. Ani że obrazek zawiera dane nawet 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ć, że „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, że mocno popsuła nam się linijka 3.

Obstawiam, że 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 artefakty zakryją nam akurat te poufne informacje, które wolelibyśmy pozostawić uciętymi.

Windows dołącza do gry

Ktoś mógłby powiedzieć, że telefony Pixel, w dodatku o określonej wersji, to przypadek dość rzadki, więc nasza apokalipsa mało komu zaszkodziła. 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ł, że 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, że badacze zaczęli się rozglądać za podobnymi lukami bezpieczeństwa.
Jeden z nich, Chris Blume, napisał 21 marca na Twitterze, że widzi podobne nieścisłości w rozmiarach plików edytowanych przez Narzędzie Wycinania.

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, że 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, że 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, że 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.

Ciekawostka

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ł, że 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 nadal się rozwija. Na fali odkrycia zapewne 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 prowadzić do ujawnienia tajemnic, warto zaznaczyć że dotyczy tylko szczególnych okoliczności. Musi zajść kilka rzeczy naraz:

  1. Poza wyciętym obszarem jest coś prywatnego, czego byśmy nie chcieli ujawniać;
  2. Otwieramy plik konkretnym programem (Narzędzie Wycinania na Windowsie, Markup na Pixelu, ew. jakieś dotąd nieodkryte kombinacje), przycinamy go i zapisujemy pod taką samą nazwą

    (nie mam tu 100% pewności, ale zapewne błąd nie miałby miejsca przy samym łapaniu pierwszego screena, jedynie przy otwieraniu i przycinaniu wcześniej zapisanego pliku obrazkowego);

  3. Dane spoza wycinka nie zostaną przykryte artefaktami (kwestia być może losowa);
  4. 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ę, że 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, że niektóre mogą być ł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 już 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ś zapewne trafią się takie przypadki.
Najgorsze jest to, że zagrożenie działa wstecz. Kiedy pechowy screen raz zostanie zapisany na dysku, to można do niego wrócić w dowolnym momencie. Zapewne 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ę.

Powiązane wpisy

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 miejsca, w których je zrobiono.
Pułapka druga – gdy edytujemy niektóre formaty plików, jak PDF, nie wystarczy zakrycie tekstu czarnym prostokątem. Bo cały tekst nadal 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: