Akademia NIS2/KSC2 od sekuraka. 19 października start drugiej edycji!

Zobacz nasz aktualny kalendarz szkoleń!

 

Pralnia zaufania: VeraCrypt, Mark of the Web, i luka architektoniczna Windows

26 października 2026, 07:35 | Aktualności | 0 komentarzy

Pobierasz z Internetu zaszyfrowany kontener VeraCrypt. Windows, zgodnie ze swoimi zasadami, oznacza plik strumieniem Zone.Identifier – Mark of the Web, czyli elektroniczną zawieszką mówiącą: „przybyło z sieci”. Podajesz hasło, kontener montuje się jako zwykły wolumen NTFS i właśnie wtedy dzieje się coś, co na pierwszy rzut oka wygląda na drobiazg, a w rzeczywistości jest jedną z ciekawszych luk logicznych, jakie ostatnio analizowałem: każdy plik wewnątrz zamontowanego woluminu staje się dla systemu identyczny z plikiem, który leży na Twoim dysku od lat. Żadnego dziedziczenia strefy, żadnego ostrzeżenia SmartScreen, żadnego śladu pochodzenia.

To nie błąd w AES ani w implementacji kryptografii – szyfrowanie działa dokładnie tak, jak powinno. To też nie jest „zła linijka kodu”, którą da się załatać w kolejnym wydaniu. Jak pokazała wspólna analiza z twórcą projektu VeraCrypt, Mounirem Idrassim, mamy do czynienia z luką architektoniczną: mechanizm, którego Windows używa do przenoszenia kontekstu zaufania, nie obejmuje wolumenów montowanych przez sterowniki firm trzecich. Pobrany z Internetu kontener potrafi więc działać jak pralnia zaufania: przyjmuje pliki ze strefy Internetu, a oddaje je „czyste” – lokalne dla SmartScreena.

Mark of the Web, czyli jak Windows pamięta, skąd pochodzi plik

Mark of the Web (MotW) to mechanizm, na którym Windows opiera ocenę zaufania do plików spoza lokalnego systemu. Technicznie jest to alternatywny strumień danych NTFS (ADS) o nazwie Zone.Identifier, w którym przeglądarka albo klient poczty zapisuje strefę pochodzenia pliku – najczęściej ZoneId=3, czyli strefę Internetu. Na podstawie tego znacznika system uruchamia ostrzeżenia SmartScreen, blokuje makra w dokumentach Office pobranych z sieci i w ogóle inaczej traktuje pliki wykonywalne. Plik bez strumienia Zone.Identifier jest dla Windowsa w praktyce plikiem lokalnym – czyli takim, za którego pochodzenie odpowiada użytkownik, a nie sieć.

Wagę tego mechanizmu najlepiej widać po historii łatek. Microsoft wielokrotnie naprawiał problemy z propagacją MotW, a skuteczne obejścia trafiały do katalogu KEV i dostawały numery CVE. Dla nas istotne są dwa przypadki: CVE-2022-41091 – „Windows Mark of the Web Security Feature Bypass Vulnerability”, dotyczące natywnego montowania obrazów ISO – oraz CVE-2025-0411 w 7-Zip, gdzie ekstraktor archiwów nie przenosił MotW na wypakowywane pliki. Oba będą nam jeszcze potrzebne, bo właśnie do nich porównywałem wyniki tego badania.

Zgłoszenie: znacznik, który ginie przy montowaniu

To nie jest moje pierwsze spotkanie z VeraCrypt w roli zgłaszającego. Wcześniej, we współpracy z Mounirem Idrassim, powstały zgłoszenia CVE-2024-54187 oraz CVE-2025-23021 – oba skutkowały poprawkami w kodzie projektu. Gdy tym razem na biurku wylądował wynik testów z Mark of the Web, pierwszym krokiem było pismo do znanego adresata.

Zgłosiłem prostą, ale podejrzanie brzmiącą obserwację: kontener VeraCrypt pobrany z Internetu dostaje od Windowsa strumień Zone.Identifier ze strefą Internetu, natomiast pliki widoczne po zamontowaniu woluminu nie mają go wcale. Do e-maila dołączyłem PoC w PowerShellu:

Get-Content "C:\Downloads\container" -Stream Zone.Identifier
# [ZoneTransfer]
# ZoneId=3
# Mount container as K:
Get-Item "K:\test.exe" -Stream Zone.Identifier
# AlternateDataStreamNotFound

Zaznaczyłem istotny szczegół: wolumen wewnątrz kontenera sformatowałem na NTFS, a NTFS – jak każdy NTFS – obsługuje alternatywne strumienie danych. Potwierdziłem to ręcznie: plikowi wewnątrz zamontowanego woluminu można bez problemu nadać własny strumień Zone.Identifier, po czym SmartScreen zaczyna traktować go zgodnie z nadaną strefą. Innymi słowy, całego mechanizmu nic nie blokuje – brakuje jedynie automatycznego przekazania kontekstu z kontenera na jego zawartość w chwili montowania.

Do zgłoszenia dołączyłem też kontekst branżowy: Microsoft naprawił analogiczny problem propagacji MotW dla obrazów montowanych natywnie (CVE-2022-41091), więc uzasadnione wydawało się oczekiwanie spójnego podejścia do innych formatów kontenerów. Sedno ująłem tak:

The concern is that a downloaded VeraCrypt container can carry MOTW while executable content inside it loses the Internet-origin security context after mounting, potentially bypassing MOTW-dependent Windows security controls.
– fragment e-maila autora do Mounira Idrassiego

Pierwsza odpowiedź: „taki jest VeraCrypt”

Idrassi odpowiedział i od razu postawił sprawę precyzyjnie. Jego wyjaśnienie to najlepsze możliwe wprowadzenie do architektury, o której będzie mowa przez resztę artykułu:

What you describe is consistent with how VeraCrypt works. The driver decrypts disk sectors, while Windows handles the filesystem inside the volume. That filesystem is separate from the one holding the container, so mounting doesn’t copy the container Zone.Identifier stream onto the files inside it.
– Mounir Idrassi

To zdanie warto przeczytać dwa razy, bo zawiera istotę całego problemu. VeraCrypt widzi wyłącznie zaszyfrowane sektory – nie interpretuje filesystemu i nie wie nic o plikach, które Windows „na niego” składa. Windows zaś montuje filesystem wewnątrz woluminu jak zupełnie nowy, niezależny system plików: dla niego to świeży NTFS, który nie ma żadnego związku z plikiem-kontenerem, z którego powstał. Nikt w tym układzie nie przenosi kontekstu zaufania z jednej strony na drugą, bo – z perspektywy każdej z nich – druga strona po prostu nie istnieje.

Co ważne, Idrassi nie zamknął sprawy, lecz poprosił o dowód behawioralny. Wskazał przy okazji, że dla obrazów montowanych przez natywne mechanizmy Windows potrafi konsultować znacznik obrazu nadrzędnego – szeroko opisuje to Eric Lawrence w artykule „Mark of the Web – Additional Guidance” (textslashplain.com):

I don’t think the missing stream alone gives us enough to call this a VeraCrypt vulnerability, so I’m not proposing a CVE at this point. I will reconsider that in light of evidence showing an effect on a Windows protection.
– Mounir Idrassi

Mieliśmy więc wspólny mianownik: samego brakującego strumienia nie da się nazwać podatnością. Trzeba było pokazać, jak Windows faktycznie traktuje pliki w środku – i co to zmienia dla realnych zabezpieczeń systemu.

Test na żywo: i… SmartScreen pokonany

Przygotowałem środowisko testowe i prosty, surowy, niepodpisany plik wykonywalny, którego jedynym zadaniem było wyświetlenie okienka z alertem. Dzięki temu wynik nie pozostawiał miejsca na interpretację: albo SmartScreen przerwie uruchomienie, albo nie.

Scenariusz kontrolny wyglądał dokładnie tak, jak oczekuje każdy, kto zna model bezpieczeństwa Windows. Plik pobrany bezpośrednio z Internetu dostawał strumień Zone.Identifier, a przy uruchomieniu natychmiast pojawiało się ostrzeżenie SmartScreen, skutecznie blokując egzekucję.

Drugi scenariusz różnił się jednym szczegółem: ten sam plik umieściłem w kontenerze VeraCrypt sformatowanym na NTFS, kontener pobrałem z Internetu (a więc to on nosił ZoneId=3), zamontowałem go i uruchomiłem zawarty w środku payload. Binarka wykonała się bez najmniejszego problemu – okienko alertu wyświetliło się, a jedyną reakcją systemu był… jej brak. Zero ostrzeżeń SmartScreen, zero interwencji. Całość nagrałem na wideo i dołączyłem do korespondencji (demo jest publiczne: youtu.be/bomjQW89hGY). W e-mailu podsumowałem wynik obu testów:

1. Control Test (direct download): A raw, unsigned executable (programmed to display an alert box) downloaded directly from the internet receives the Zone.Identifier Alternate Data Stream (MotW). When executed, Windows SmartScreen immediately triggers and prevents it from running.
2. VeraCrypt Test (container smuggle): Placing that exact same binary inside a VeraCrypt container, downloading the container from the internet (so the container file itself holds ZoneId=3), mounting it, and running the payload results in the binary executing normally without any problem, successfully displaying the alert box with zero SmartScreen warnings or intervention, because the inner files completely lack the Zone.Identifier stream.
– fragment e-maila autora.

W tym samym piśmie sformułowałem wniosek, który uważam za najkrótsze streszczenie całego problemu:

When an internet-sourced container is mounted and inner files are exposed without propagating that context, the container acts as a trust-laundering mechanism that neutralizes Windows execution controls.
– fragment e-maila autora.

Dodałem jeszcze jeden argument: branża już raz przeszła przez identyczny problem. 7-Zip otrzymał CVE-2025-0411 za to, że wypakowywane z pobranych archiwów pliki nie dziedziczyły MotW – a efekt końcowy (obejście SmartScreen) był dokładnie taki sam jak w moim teście. Powstało więc naturalne pytanie: jeśli ekstraktor archiwów ma obowiązek propagować znacznik, dlaczego montowany wolumen miałby być z tej samej zasady zwolniony?

Diagnoza Idrassiego: ten sam plik, dwa różne wyroki

Na finałową analizę trzeba było chwilę poczekać – Mounir Idrassi utrzymuje VeraCrypt w wolnym czasie, a skrzynkę ma ostatnio wyjątkowo wymagającą. Jego otwarcie dobrze obrazuje realia disclosure w 2026 roku:

I have been working through a large number of AI-generated security reports. Most turn out to be invalid, but each one still needs to be checked. Since I maintain VeraCrypt in my spare time, I have fallen behind on correspondence.
– Mounir Idrassi

Potem przyszła właściwa treść – i była ciekawsza, niż mogłem oczekiwać. Idrassi nie tylko obejrzał wideo i potwierdził moje wyniki, ale odtworzył je samodzielnie, rozszerzając testy o inne produkty. Kluczowe ustalenie brzmi tak:

The key finding is that Windows treats the same program differently depending on how the container is mounted. In my tests, the container or image carried a MOTW, indicating that it came from the Internet, while the program inside had no mark of its own:
– Inside a mounted VeraCrypt NTFS container, Windows treated the program as local content.
– Inside an ISO mounted by Windows, Windows used the ISO’s Internet mark when assessing the program.
– Mounir Idrassi

To jest sedno sprawy: identyczny plik, identyczny kontener z ZoneId=3, a wyrok systemu zależy wyłącznie od tego, czyj kod zamontował zawartość. Gdy obraz ISO obsługuje sam Windows, system sięga do znacznika obrazu nadrzędnego. Gdy wolumen wystawia sterownik VeraCrypt – zawartość staje się lokalna. Idrassi potwierdził przy tym drugą stronę medalu: Windows bez problemu odczytuje i stosuje znacznik przypięty do pojedynczego pliku wewnątrz wolumenu VeraCrypt. Brakuje wyłącznie połączenia:

The gap is in connecting that file to the mark on the container itself.
– Mounir Idrassi

Co więcej, problem nie jest specyficzny dla VeraCrypt. Idrassi powtórzył testy na BestCrypt od Jetico:

I found similar behavior with Jetico’s BestCrypt. Downloading helloworld.exe directly through Firefox gave it an Internet mark (ZoneId=3) and produced a SmartScreen warning when I opened it. Launching the program from a downloaded BestCrypt NTFS container produced no Windows or SmartScreen warning.
–  Mounir Idrassi

Testy warstwy storage dały spójny wynik dla obu produktów: 

GetStorageDependencyInformation zwracało „not a virtual disk” i nie dostarczało żadnej ścieżki do pliku-kontenera podpierającego zamontowany wolumen. To mocna wskazówka, że brakujące połączenie wolumen-kontener to szerszy problem, a nie przypadkowość jednego sterownika.

Dlaczego więc ISO działa inaczej? Odpowiedź Idrassiego domyka obraz:

For an ISO mounted by Windows, Microsoft provides both the filesystem and the virtual storage components. Their integration lets Windows trace a file back to the original ISO and consult its mark without modifying the files inside it. The same lookup does not find the backing container for a VeraCrypt volume.
–  Mounir Idrassi

Sektory, nie pliki: dlaczego nie ma CVE w VeraCrypt

Wracając do porównania z 7-Zipem – Idrassi wyjaśnił, dlaczego analogia, choć trafna w efekcie, nie przekłada się na podział odpowiedzialności:

An 7zip archive extractor creates individual files and can attach a mark as it writes them. VeraCrypt’s driver works with disk sectors; Windows handles the filesystem and the individual files above that layer. The driver doesn’t interpret the filesystem, so it can’t attach marks to individual files or change their metadata. So, the responsibility described in the archive case doesn’t directly carry over to a disk encryption driver.
– Mounir Idrassi

Ekstraktor archiwów sam tworzy pliki na dysku, więc może – i powinien – nadawać im MotW w chwili zapisu; tak właśnie wyglądała naprawa CVE-2025-0411. Sterownik szyfrujący działa o warstwę niżej: odszyfrowuje sektory i oddaje je Windowsowi, a pliki „powstają” wyżej, w systemie plików budowanym przez system. VeraCrypt fizycznie nie ma możliwości nadania znacznika czemuś, czego nie widzi.

Została najciekawsza kwestia techniczna: czy VeraCrypt mógłby w ogóle ujawnić Windowsowi relację wolumen-kontener? Idrassi prześledził mechanizm odpytywania:

The lookup uses FSCTL_QUERY_DEPENDENT_VOLUME with support from Microsoft’s FsDepends filesystem filter. Although the query structures are public, I haven’t found Microsoft documentation explaining how an independent disk driver should register that relationship. Because the query operates in the filesystem stack, I don’t see any way for adding support for it to VeraCrypt’s disk IOCTL handler.
– Mounir Idrassi

To moment, w którym historia przekracza granicę pojedynczego projektu. Mechanizm, którym Windows odpytuje zamontowane wolumeny o ich pochodzenie, działa w stacku filesystemu i – mimo publicznych struktur zapytań – nie ma udokumentowanej ścieżki, po której niezależny sterownik dyskowy mógłby zarejestrować relację z kontenerem nadrzędnym. Inaczej: nawet gdyby VeraCrypt chciał współpracować, obecnymi API nie ma jak tego wyrazić.

Stąd finalny werdykt:

Based on these findings, I don’t currently consider this a VeraCrypt vulnerability, and I don’t plan to request a CVE for it. This is a general limitation affecting all Windows-based file container products.
– Mounir Idrassi, oficjalne stanowisko udostępnione do cytowania

Idrassi zadeklarował otwartość na dalsze dowody techniczne, które mogłyby zmienić tę ocenę, i wskazał, że wyniki powinny trafić także do Microsoftu oraz do Jetico, dewelopera BestCrypt. Zgodził się przy tym na opublikowanie swojej odpowiedzi jako oficjalnego stanowiska – i dlatego artykuł ten mógł powstać.

Tabela: cztery sposoby wystawienia zawartości kontenera

Zebrane przez nas wyniki najlepiej porządkuje jedno zestawienie. Pokazuje ono, że o tym, czy zawartość kontenera zachowa kontekst Internetu, nie decyduje ani format, ani szyfrowanie – decyduje wyłącznie sposób, w jaki warstwa storage została zintegrowana z systemem:

WektorKto wystawia pliki systemowiPowiązanie z MOTW konteneraWynik dla zawartości
ISO/VHD montowany natywnieWindows: filesystem i warstwa wirtualnego dysku, integracja przez FsDependsTak – system sięga do znacznika obrazu nadrzędnegoPliki traktowane poprawnie (po naprawie CVE-2022-41091)
Kontener VeraCrypt NTFSSterownik VeraCrypt odszyfrowuje sektory; filesystem wewnątrz buduje WindowsBrak – GetStorageDependencyInformation zwraca „not a virtual disk”Pliki wyglądają jak lokalne; SmartScreen nie zadziała
Kontener BestCrypt NTFSArchitektura analogiczna do VeraCryptBrak – wynik identyczny jak dla VeraCryptPliki wyglądają jak lokalne; SmartScreen nie zadziała
Archiwum 7-ZipEkstraktor aplikacji tworzy pliki na dyskuTak – ekstraktor nadaje MOTW w chwili zapisu (po naprawie CVE-2025-0411)Pliki zachowują Mark of the Web

Zestawienie robi dwie rzeczy. Po pierwsze, pokazuje, że linia podziału nie biegnie między „bezpiecznym” a „niebezpiecznym” produktem, lecz między integracją w standardzie Microsoftu a sterownikami, które pozostają poza nią. Po drugie, obnaża asymetrię: producenci formatów natywnych dostają od systemu gotową ścieżkę propagacji MotW, a twórcy wolumenów firm trzecich – choć ich użytkownicy podlegają tym samym zabezpieczeniom SmartScreen – nie mają w ogóle jak się do tego mechanizmu podłączyć.

Gdzie leży odpowiedzialność – i co dalej

W całej historii nie ma złego programisty. AES działa, sterownik odszyfrowuje sektory, Windows buduje na nich system plików – każdy element funkcjonuje jak należy. Problem leży na styku: w brakującym ogniwie między oznaczonym strefą Internetu plikiem-kontenerem a wolumenem, który z tego kontenera powstaje. Idrassi nazwał to wprost ogólnym ograniczeniem wszystkich produktów kontenerowych dla Windows i wskazał adresatów dalszych zgłoszeń: Microsoft – jako właściciela FsDepends i API odpytywania o zależności wolumenów – oraz Jetico.

Z mojej strony dodam jedno. Werdykt „to nie jest podatność VeraCrypt” nie oznacza „to nie jest problem bezpieczeństwa”. Efekt końcowy – obejście SmartScreen dla zawartości pochodzącej z Internetu – jest realny, powtarzalny i znamy go już z dwóch numerów CVE (CVE-2022-41091 oraz CVE-2025-0411).

Różnica polega wyłącznie na tym, że tym razem naprawa wymaga ruchu ze strony Microsoftu: udokumentowania ścieżki integracji dla sterowników firm trzecich albo wbudowania w system propagacji kontekstu dla wszystkich wolumenów mających oznaczony kontener nadrzędny. Dopóki to nie nastąpi, każdy produkt wystawiający wolumeny przez własny sterownik będzie – niezależnie od intencji autora – pełnił rolę pralni zaufania.

Co to oznacza w praktyce

Warto sprowadzić całość do konkretnego scenariusza. Atakujący nie musi łamać żadnego szyfrowania: przygotowuje kontener NTFS z payloadem, publikuje go w sieci (kontener dostaje ZoneId=3) i dostarcza ofierze link wraz z hasłem – na przykład jako rzekomo „poufne dane” do przejrzenia. Ofiara sama podaje hasło i sama montuje wolumen, bo to przecież VeraCrypt – narzędzie kojarzone z ochroną danych, a nie z ryzykiem.

Od tego momentu każdy plik w środku jest dla Windowsa lokalny: SmartScreen milczy, ostrzeżenia się nie pojawią, a zawartość może zostać uruchomiona bez przeszkód.

Dopóki Microsoft nie udokumentuje ścieżki integracji dla sterowników firm trzecich, rozsądna obrona spada na konfigurację i nawyki. 

Traktuj kontenery pobrane z sieci tak samo podejrzliwie jak każdy inny plik z niepewnego źródła – szyfrowanie nie jest atestem zawartości. Wrażliwe kontenery montuj w odizolowanej maszynie wirtualnej, a nie na stacji roboczej z dostępem do zasobów firmowych. Pamiętaj, że żaden plik wewnątrz zamontowanego wolumenu nie dostanie ostrzeżenia SmartScreen, nawet jeśli cały kontener przychodzi prosto z Internetu – a jeśli chcesz zweryfikować konkretny plik, możesz ręcznie odpytać go o strumień Zone.Identifier (Get-Item ze ścieżką i parametrem -Stream Zone.Identifier).

Podsumowanie

Nigdzie w tej historii nie złamano AES ani nie znaleziono błędu w kryptografii – VeraCrypt przez cały czas zachowywał się zgodnie ze swoją specyfikacją. Opisałem za to coś znacznie ciekawszego: lukę na styku warstw, z których każda uważa problem za czyjąś inną odpowiedzialność. Kontener nosi znacznik Internetu, ale zawartości oznaczyć nie może; Windows potrafi propagować kontekst zaufania, ale tylko dla formatów, do których ma zintegrowaną ścieżkę; sterownik firm trzecich nie ma sposobu, by się do tej ścieżki podpiąć. 

Efekt? Zaszyfrowany kontener z sieci staje się pralnią zaufania, a SmartScreen – jedno z najbardziej rozpoznawalnych zabezpieczeń Windowsa – nawet nie próbuje zaprotestować.

Z perspektywy disclosure’u to zresztą przykład, jak taki proces powinien wyglądać: zgłoszenie, rzeczowa dyskusja, niezależna reprodukcja wyników przez autora projektu, uczciwy werdykt (bez CVE w VeraCrypt) i konkretne wskazanie, gdzie naprawdę leży problem. Teraz piłka jest po stronie Microsoftu i Jetico. Wrócimy do tematu, gdy któraś z tych firm zabierze głos.

O autorze

Patryk Ptak (SivertPL) – polsko-amerykański badacz bezpieczeństwa. Zajmuje się vulnerability researchem oraz analizą podatności na styku aplikacji, systemów operacyjnych, sterowników i firmware. Autor zgłoszeń CVE-2024-54187 oraz CVE-2025-23021 dotyczących VeraCrypt, we współpracy z autorem projektu, Mounirem Idrassim.

~Patryk Ptak, SivertPL

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



Komentarze

Odpowiedz