Prefetch file names and UNC paths

In one of the older posts, I talked about how the Prefetch file names are created. Today I was looking at program execution from network shares i.e. originating from the UNC paths and realized that I have not included these in the original article.

VM Shares

To test what happens, I launched WinXP under windbg and put a breakpoint on the hashing function and then executed a test file from a shared VM folder – the screenshot shows the mapping between the drive and the UNC path where the executable is placed:

Once executed, the windbg popped up and I could trace the full path to a file in a Memory window

As it seems, nothing really surprising:

  • z:\test.exe is executed
  • it is mapped to its UNC path \\vmware-host\Shared Folders\X\test.exe
  • which is then prepended with a device name responsible for HGFS file system (used internally by VM) to form a final string used in a hash calculation
  • \DEVICE\HGFS\VMWARE-HOST\SHARED FOLDERS\X\TEST.EXE

Real share

Now, that was the case with a ‘fake’ share created by the VM software.

What about a real share?

Following the same procedure:

  • I mapped a host \\H\C$ drive as N: inside the guest system with ‘net use’
  • and then executed N:\test.exe

The result shown below is not very surprising either as now the path refers to LANMANREDIRECTOR:

  • \DEVICE\LANMANREDIRECTOR\H\C$\TEST.EXE

Substed paths

And in case you are curious what happens to drives created with subst…

For drives mapped locally using ‘subst drive: path’ e.g.

subst g: .

there is no difference as the device will refer to HARDDISKVOLUME### (where ### is hard drive’s number) – I don’t include screenshot here as I hope this example doesn’t need one.

However, using subst in a slightly different way i.e. referring to target path via localhost’s IP: e.g.

subst g: \\127.0.0.1\c$

will make the Prefetch file name to be created using the following path:

  • \DEVICE\LANMANREDIRECTOR\127.0.0.1\C$\TEST.EXE

As you can see, each of the test files created a different hash

In other words, there is plenty of ways to abuse the file naming creation of the prefetch file and it’s quite hard to write an universal hash calculator to cover all these cases – it really depends on the environment and there are lots of tricks to confuse the system + I bet there are a few more that wait to be uncovered.

Finding Alternate Data Streams (ADS) with HMFT

Finding Alternate Data Streams  (ADS) on the whole drive may be quite time consuming so in this quick post I will show you how to do it faster with HMFT.

As you probably know, the latest version of HMFT supports listing of basic attributes directly from $MFT – from both images and live systems. Amongst the features it currently supports is showing type of attribute and its name. Turns out, that this is enough information to find out what named DATA streams are hidden inside the FILE records – and this is essentially what ADSs are.

So…

First, let’s test how HMFT shows ADS-related data:

  • First let’s create a few sample ADSs
echo > f:\test
echo > f:\test:ads
echo > f:\test:ads2
echo > f:\test:ads3
  • Next, we run hmft over the drive and saving it to a file
hmft -l f: f_mft.txt
  • Finally, let’s see the content of the file – scroll down to see file name, first unnamed DATA attribute that is then followed by 3 named DATA attributes – ADS names:
  [FILE]
    SignatureD                    = 1162627398
    OffsetToFixupArrayW           = 48
    NumberOfEntriesInFixupArrayW  = 3
    LogFileSequenceNumberQ        = 4204637
    SequenceValueW                = 1
    LinkCountW                    = 1
    OffsetToFirstAttributeW       = 56
    FlagsW                        = 1
    UsedSizeOfMFTEntryD           = 448
    AllocatedSizeOfMFTEntryD      = 1024
    FileReferenceToBaseRecordQ    = 0
    NextAttributeIdD              = 6
   --

    RESIDENT ATTRIBUTE
      AttributeTypeIdentifierD = 16
      LengthOfAttributeD       = 96
      NonResidentFlagB         = 0
      LengthOfNameB            = 0
      OffsetToNameW            = 0
      FlagsW                   = 0
      AttributeIdentifierW     = 0
      --
      SizeOfContentD          = 72
      OffsetToContentW        = 24
      --
        MFTA_STANDARD_INFORMATION
            CreationTimeQ         = 129938289425003390
            ModificationTimeQ     = 129938289502223390
            MFTModificationTimeQ  = 129938289502223390
            AccessTimeQ           = 129938289425003390
            FlagsD                = 32
            MaxNumOfVersionsD     = 0
            VersionNumberD        = 0
            ClassIdD              = 0
            OwnerIdD              = 0
            SecurityIdD           = 261
            QuotaQ                = 0
            USNQ                  = 0
            CreationTime (epoch)    = 1349355342
            ModificationTime (epoch)  = 1349355350
            MFTModificationTime (epoch)  = 1349355350
            AccessTime (epoch)           = 1349355342
   --

    RESIDENT ATTRIBUTE
      AttributeTypeIdentifierD = 48
      LengthOfAttributeD       = 104
      NonResidentFlagB         = 0
      LengthOfNameB            = 0
      OffsetToNameW            = 0
      FlagsW                   = 0
      AttributeIdentifierW     = 2
      --
      SizeOfContentD          = 74
      OffsetToContentW        = 24
      --
        MFTA_FILE_NAME
            ParentID6             = 5
            ParentUseIndexW       = 5
            CreationTimeQ         = 129938289425003390
            ModificationTimeQ     = 129938289425003390
            MFTModificationTimeQ  = 129938289425003390
            AccessTimeQ           = 129938289425003390
            CreationTime (epoch)    = 1349355342
            ModificationTime (epoch)  = 1349355342
            MFTModificationTime (epoch)  = 1349355342
            AccessTime (epoch)           = 1349355342
            AllocatedSizeQ        = 0
            RealSizeQ             = 0
            FlagsD                = 32
            ReparseValueD         = 0
            LengthOfNameB         = 4
            NameSpaceB            = 3
     FileName = test
   --

    RESIDENT ATTRIBUTE
      AttributeTypeIdentifierD = 128
      LengthOfAttributeD       = 40
      NonResidentFlagB         = 0
      LengthOfNameB            = 0
      OffsetToNameW            = 24
      FlagsW                   = 0
      AttributeIdentifierW     = 1
      --
      SizeOfContentD          = 13
      OffsetToContentW        = 24
      --
        MFTA_DATA
   --

    RESIDENT ATTRIBUTE
      AttributeTypeIdentifierD = 128
      LengthOfAttributeD       = 48
      NonResidentFlagB         = 0
      LengthOfNameB            = 3
      OffsetToNameW            = 24
      FlagsW                   = 0
      AttributeIdentifierW     = 3
      --
      SizeOfContentD          = 13
      OffsetToContentW        = 32
      --
        MFTA_DATA
    AttributeName = ads
   --

    RESIDENT ATTRIBUTE
      AttributeTypeIdentifierD = 128
      LengthOfAttributeD       = 48
      NonResidentFlagB         = 0
      LengthOfNameB            = 4
      OffsetToNameW            = 24
      FlagsW                   = 0
      AttributeIdentifierW     = 4
      --
      SizeOfContentD          = 13
      OffsetToContentW        = 32
      --
        MFTA_DATA
    AttributeName = ads2
   --

    RESIDENT ATTRIBUTE
      AttributeTypeIdentifierD = 128
      LengthOfAttributeD       = 48
      NonResidentFlagB         = 0
      LengthOfNameB            = 4
      OffsetToNameW            = 24
      FlagsW                   = 0
      AttributeIdentifierW     = 5
      --
      SizeOfContentD          = 13
      OffsetToContentW        = 32
      --
        MFTA_DATA
    AttributeName = ads3

 

  • Knowing all this, we can quickly put together a perl script that can walk through the data and pick up all ADS from the output file:
use strict;
my $f='';
my $l='';
while (<>)
{
  s/[\r\n]+//g;
  $f = $1 if /FileName = (.+)$/;
  print "$f:$1\n" if ($l =~ /MFTA_DATA/&&/AttributeName = (.+)$/);
  $l = $_;
}
  • Save it as ads.pl
  • Run it using the following syntax
perl ads.pl <hmft output>

e.g.:

perl ads.pl f_mft.txt

The output for the example file system is:

$Repair:$Config
test:ads
test:ads2
test:ads3

I suggest you running a test on your local drives  – you are probably going to be quite surprised 🙂

Not only you may find plenty of files with ADS, but you may also get to know less-known good ADSs – many of them I have listed previously and a few more e.g. internal ADSs used by OS:

  • $Info in $UpCase:$Info
  • $Config in $Repair:$Config
  • $Max in $UsnJrnl:$Max

and also MAC-related streams (resource forks) added by Safari  (kinda equivalents of IE’s Zone.Identifier)

  • com.apple.quarantine
  • com.apple.metadata:kMDItemWhereFroms

Note on a small bug here: with a larger number of ADSs the ads.pl script will show incorrect entries as ADS attributes that don’t fit within one FILE record will be stored elsewhere and w/o FILENAME attribute, hence the associated file name will be incorrect. Some may be also stored under ATTRIBUTE_LIST that is not supported by HMFT yet.