On název "Atribut" je v případě Windows zavádějící. Tam se to jmenuje Stream (velmi pěkný popis) a lze tam narvat cokoli, o jakékoli velikosti a může jich být více.
Zákeřné je to v tom, že standardní nástroje a většina správců souborů je vůbec neukazuje a ani se nemění udávaná velikost původního souboru (což je zle z principu, jak se ukládají OK).
Příklad: Vytvořím si textový soubor test.txt s obsahem 123456
C:\Temp>echo 123456 >test.txt
Velikost má 9 byte:
C:\Temp>dir
27.12.2018 06:21 9 test.txt
Obsah je očekávaný (na konci je mezera + CRLF):
0000000000: 31 32 33 34 35 36 20 0D │ 0A 123456
Teď do streamu k tomuto souboru, který si pojmenuji "stream1", přidám např. výpis z nslookup:
C:\Temp>nslookup portal.gov.cz >test.txt:stream1
Ještě třeba do streamu s názvem "stream2" přidám obsah www.root.cz:
C:\Temp>D:\Programy\#Internet\CUrl\curl.exe www.root.cz >test.txt:stream2
Velikost souboru se ale stále nezměnila, datum zápisu ano:
C:\Temp>dir
27.12.2018 06:24 9 test.txt
Když se na to podívám nějakým nástrojem (např. Streams ze Sysinternals nebo AlternateStreamView or NirSoft), který se streamy umí pracovat, tak je ukáže:
C:\Temp>D:\Programy\#System\SysInternals\streams64.exe C:\Temp\test.txt
streams v1.60 - Reveal NTFS alternate streams.
Copyright (C) 2005-2016 Mark Russinovich
Sysinternals - www.sysinternals.com
C:\Temp\test.txt:
:stream1:$DATA 214
:stream2:$DATA 305
Takže je vidět, že v souboru test.txt jsou dva streamy, stream1 s velikostí 214 byte a stream2 s velikostí 305 byte.
Obsah souboru se ale pro standardní nástroje nezměnil:
C:\Temp>more test.txt
123456
Vypíšu si obsah streamů.
stream1:
C:\Temp>more <test.txt:stream1
Server: dynamic-2a00-1008-81d8-1ac2-0000-0000-0000-0001.ipv6.broadband.iol.cz
Address: 2a00:1018:81dc:1aba::1
Name: gov.cz
Addresses: 2a03:2320:b944:1c60::96
185.68.28.96
Aliases: portal.gov.cz
stream2 (před konce tagů jsem dal #, aby to root.cz nechápal jako řídící tagy):
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"#>
<html#><head#>
<title#>301 Moved Permanently</title#>
</head#><body#>
<h1#>Moved Permanently</h1#>
<p#>The document has moved.... (zkráceno)
Klidně mohu vytvořit soubor s velikostí 0 byte, ve kterém nic nebude a vše bude "schované" jen ve streamech. Ale streamy přežijí pouze v rámci NTFS. Když se soubor se streamy překopíruje např. na Google Drive (nebo na flash s FAT32), tak o ně přijde.
Velikost souboru znamená velikost primárníáho (nepojmenovaného) streamu. Na ty pojmenované se musíte zeptat zvlášť. A ano, je potřeba externí utility.
> Ideální způsob jak skrýt nějaká data.
> Vytvořím soubor recept.txt s receptem na svíčkovou. Přitom si do tohoto souboru
> umístím recept na výrobu drogy.
> Koho by z expertů (policii apod) napadlo se podívat do streamu.
Tahle vlastnost je již velmi velmi dlouho známá. Dokonce i ve světě malware. Takže jako schovka nic moc extra.
Pokud se chceme přiblížit pojmu "atribut", je třeba se podívat na tzv. rozšířené atributy (extended attributes). Případně by něco šlo uložit jako reparse point (standardně se tam ukládají symlinky, ale ten mechanismus je obecnější).
Žiji jsem v představě, že NTSF streamy jsou jen jeden z dalších možných uložení "tajných" informací o souboru. Ovšem, že stále ještě existují i klasické rozšířené atributy (z dob OS/2) a je to něco jiného než stream.
Pro současné windows však nejsou přístupné přímo z user API, musí se asi níže. K nastavení jsem kdysi tuším zkoušel (undocumented? tenkrát?) NtSetEaFile a teď by snad měla být (documented?, co jsem v rychlosti našel na netu) obdoba ZwSetEaFile. https://msdn.microsoft.com/en-us/library/windows/hardware/ff961908%28v=vs.85%29.aspx
Microsoft extended attributes, tuším, sám o sobě nově oživil ve WSL, kde si tam ukládá *nix-like vlastnosti souborů. A mám pocit, že tam při tom něco zblbli a snad už i proběhla oprava a mělo by být ok. Tedy, pokud nezmatkuji a nespletl jsem dohromady dvě různé věci. Oživili právě proto, aby se rozšířené informace neztratily, když k souborům přistupují paralelně z WIN32 i WSL.
Ale v principu, pokud by někdo chtěl (ale asi jen na driver úrovni?, pro win32, WSL netuším), asi by mohl přidat "tajné" rozšířené atributy i nyní. Ještě mino streamy.
> Žiji jsem v představě, že NTSF streamy jsou jen jeden z dalších možných uložení
> "tajných" informací o souboru. Ovšem, že stále ještě existují i klasické rozšířené atributy
> (z dob OS/2) a je to něco jiného než stream.
Ano, WSL je používá. Pak jsem jejich použití viděl u rozhraní Transport Driver Interface (TDI), což jsou takové "sockety" pro ovladače (naštěstí od Windows Vista deprecated). Tam se myslím používaly pro specifikaci IP adres. Je ale pravda, že tyhle atributy nikdy neviděly disk.
NtQueryEa/NtSetEa by jde volat i normálně z usermode, ač je pravda, že tyhle nízkoúrovňové API (jde vlastně o systémová volání) jsou dokumentovány zejména pro potřeby ovladačů. Pokud vytváříte nový soubor, tak je ani nepotřebujete, protože systémové volání NtCreateFile vám dovoluje rozšířené atributy přímo specifikovat.
Na rozdíl od alternativních datových proudů mají ale rozšířené atributy omezenou velikost
(celkově max. 64 KB pro jeden soubor?), takže se nehodí na všechno.