Alternate Data Streams in NTFS

Lang geleden dat we nog eens echt een artikeltje voor de geeks schreven. Hoewel dit artikeltje misschien ook wel geschikt is voor Jan Modaal die een beetje CSI of Bond wil naspelen. ūüôā

Sinds Windows NT is NTFS het te verkiezen bestandssysteem. Voor wie niet vertrouwt is met NTFS of bestandssystemen tout court … het systeem draagt zorg voor je bestanden. Voor elk bestand wordt wat informatie bijgehouden in een tabel. Die tabel noemt bij NTFS de ‘Master File Table’, kortweg MFT.

In die tabel houdt NTFS voor elk bestand een aantal attributen bij zoals de naam van het bestand, de grootte van het bestand, wie toegang heeft tot het bestand en natuurlijk een verwijzing naar het bestand zelf, de data. Elk van die attributen heeft een naam, het attribuut dat de verwijzing naar de eigenlijke data bevat noemt bvb. $DATA.

Het $DATA-attribuut kan niet √©√©n maar meerdere parallelle ‘stromen’ informatie beheren, nl. de standaard stroom en de alternatieve stromen. Vandaar de naam ‘alternate data stream’.

Open je bv. een afbeelding dan krijg je de informatie te zien die in de standaard $DATA stroom zit. Het vergt wat IT-kennis om de alternatieve stroom te kunnen inkijken en te wijzigen. Aan de slag!

  • Open een opdrachtprompt (dos-prompt)
  • Tik het commando ‘DIR /R’ in. Bemerk in mijn voorbeeld dat er √©√©n bestandje in mijn mapje staat nl ‘1.png’ (een afbeelding die ik toegestuurd kreeg in Facebook Messenger en opsloeg) maar dat er een extra stream beschikbaar is genaam ‘Zone.Identifier’. Even kijken wat daarin zit?
  • Tik het commando ‘more < 1.png:Zone.Identifier’. Zoals je in het screenshot ziet staat hier behoorlijk wat tekst. Deze tekst werd door mijn webbrowser opgeslagen in de alternatieve stroom van het bestandje en vertelt waar dit bestandje vandaan komt (uit Facebook Messenger). Virusscanners maken gebruik van deze stroom om het gevaar van een bestand dat werd gedownload in te schatten.
  • Tik het commando ‘echo Dit is geheim > 1.png:Geheim.$DATA’. We hebben nu een nieuwe stroom toegevoegd met de naam ‘Geheim’ en als inhoud ‘Dit is geheim’.
  • Even controleren?

Behalve CSI of James Bond spelen zijn er ook heel wat praktische toepassingen van deze alternate data streams. Zo maakt Dropbox er intensief gebruik van om te weten welke bestanden nog moeten gesynchroniseerd worden.

Als je vragen hebt, aarzel niet mij te contacteren.

NTFS rechten instellen op remote server (in C#)

Quasi alle taken kunnen gescript worden maar moeilijker wordt het als je zaken wil uitvoeren op een server waarop je code niet draait, maar moeilijk gaat ook.

Voor veel zaken heb je de ‚ÄúSystem.Management‚ÄĚ en ‚ÄúSystem.Management.Instrumentation‚ÄĚ objecten nodig.¬† Vergeet zeker niet om die dus te referencen.¬† Het zijn standaard .NET objecten die je zoiezo op elk toestel hebt.

 1: public void CreateFolder(String foldername)
 2: {
 3:         String path = "\" + FileServer + "" + FileDrive + "$" + FileRoot + "" + foldername;
 4:         System.IO.Directory.CreateDirectory(path);
 5: }

FileServer, FileDrive, … zijn properties van de class waaruit ik deze functie heb gepulkt en die vb. kunnen gevuld worden door de constructor.  We gebruiken in deze en andere stukjes voorbeeld code vaak UNC paden waarbij we altijd via de administratieve share gaan (driveletter$) omdat dat zowat de enige share is waarvan je zeker bent. Andere shares kunnen verdwijnen en daarmee ook de goede werking van je code.

Een mapje delen doen we aan de hand van WMI classes (binnen C#)

 1: public void CreateShare(string Sharenaam, string Sharepad)
 2: {
 3:         ManagementScope MgScope = new ManagementScope("\" + FileServer +"rootcimv2");
 4:         ManagementPath MgPathShare = new ManagementPath("Win32_Share");
 5:         ManagementClass classObj = new ManagementClass(MgScope, MgPathShare, null);
 6:         ManagementBaseObject inParams = classObj.GetMethodParameters("Create");
 7:         inParams["Name"] = Sharenaam;
 8:         inParams["Path"] = Sharepad;
 9:         inParams["Type"] = 0; // Type = 0 => Het gaat om een DISK resource
 10:
 11:         ManagementBaseObject outParams = classObj.InvokeMethod("Create", inParams, null);
 12:         uint ret = (uint)(outParams.Properties["ReturnValue"].Value);
 13: }

In regel 3 geven we aan dat we WMI classes gaan aanspreken op onze FileServer, op regel 4 zien we dat het om de Win32_Share class gaat. In regel 5 wordt op basis van die twee zaken een object aangemaakt. De laatste parameter (null) wijst erop dat we geen specifieke connection paramters willen meegeven.  Om de Create functie te gebruiken moeten we een array van parameters meegeven met daarin de ShareNaam, het SharePath en het ShareType (0 = Disk).
En tenslotten NTFS rechten instellen kan op deze manier

 1: public void SetNTFS(string folder, byte[] SID)
 2: {
 3:     string path = @"" + FileServer + "" + FileDrive + "$" + FileRoot + "" + folder;
 4:
 5:     DirectoryInfo info = new DirectoryInfo(path);
 6:     DirectorySecurity security = info.GetAccessControl(AccessControlSections.All);
 7:     security.SetAccessRuleProtection(false, false);
 8:     InheritanceFlags flags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
 9:     SecurityIdentifier sid = new SecurityIdentifier(SID, 0);
 10:     security.AddAccessRule(new FileSystemAccessRule(sid, FileSystemRights.Modify, flags, PropagationFlags.None, AccessControlType.Allow));
 11:     info.SetAccessControl(security);
 12: }

Ook deze code is vrij recht door zee ‚Ķ We spreken de map waarvan we de NTFS settings willen wijzigen aan via het UNC pad.¬†¬† We zouden hier kunnen opmerken dat we mogelijks een korter UNC pad kunnen gebruiken door rechtstreeks de ShareNaam van de map te gebruiken ipv via de Administratieve Share te gaan. MAAR god mag weten waarom maar bij het direct aanspreken van de share worden de ‚Äúinherited NTFS instellingen‚ÄĚ verwijderd.¬† We nemen dus het omwegje om dit niet voor te hebben.

In lijn 6 vragen we de huidige NTFS settings op, in lijn 10 voegen we er een extra regel aan toe om het geheel opnieuw weg te schrijven in regel 11.  Voor de nieuwe ACL in regel 10 hebben we een SID nodig dat we maken in regel 9. Op basis van het SID van ene gebruiker maken we een SecurityIdentifier. De 0 is de offset in de byte[], tenzij er nog iets anders in de byte[] zou zitten is dit dus altijd 0.  We hebben ook de inheritance flags nodig en die maken we in regel 8 we zeggen hierbij dat zowel mappen als bestanden de NTFS settings mogen overnemen.

Deze code kan makkelijk ge√Įntegreerd worden in een ASP.NET of Winforms.NET project maar hou rekening met de nodige machtigingen.¬† Mogelijks moet je hier een beroep doen op Identity Impersonation. (ASP.NET Impersonation voor Active Directory bewerkingen)