Alternate data streams … redux

I’ve always been fascinated by Alternate Data Streams, ever since first learning about them back in 2005 in Security 504.  Just the fact they existed was appealing to me in the same way as a book safe or secret pocket in a suitcase – someplace to hide something that no one else knows about, unless you read airline catalogs or take security classes.  It was just so sneaky sounding! Consequently, I’ve kept looking at them and the tools to work with them and especially been on the lookout for new capabilities   One of my favorites is over SMB, but not from Windows systems.  I like using my Mac.

Mounting a SMB share on a Mac (running OS X) has some interesting quirks.  Folders that would normally be hidden in a command window on the Windows host system show up as normal files over SMB. Alternate data streams are more readily visible from a command line on the Mac, as the combination of Apple’s SMB and bash interprets them as extended attributes.  I covered this in more depth on my blog last year, but the basics are as follows:

  • Use the ls -l command to locate alternate data streams – any file or folder with an ADS attached will be marked with an @ symbol after the permissions column:

rons-Mac:Temp ron$ ls -l
total 10
-rwx------  1 ron  staff  1620 Feb  9 19:39 UserList.txt
-rwx------@ 1 ron  staff    24 Apr  3 02:33 file201904030227.txt
-rwx------  1 ron  staff     0 Mar 24 00:34 fromLinux0234
-rwx------@ 1 ron  staff   395 Feb 15 14:14 sprayed-creds.txt

  • Use xattr to view, create and manipulate alternate data streams
    • By itself, the command lists the extended attributes or streams
    • – w writes to an extended attribute, -p displays the contents

rons-Mac:Temp ron$ xattr *
file201904030227.txt: ads0233.txt
sprayed-creds.txt: ads.txt
sprayed-creds.txt: nc.exe

rons-Mac:Temp ron$ xattr -w ads0239 'written ~ 0239'
file201904030227.txt
rons-Mac:Temp ron$ xattr -p ads0239 file201904030227.txt
written ~ 0239\

(Note: if the stream contains binary data, xattr converts it to hex before printing it to the console.)

So – neat!  If we can gain SMB access to a Windows share from our Mac, we can see, create and export the output from alternate data streams.  Of course, I’m a geek – like most geeks I’m all in favor of doing something just because it’s unusual, but wouldn’t it be nice if this gave us something … extra?

Turns out, when I worked on my first blogging foray into alternate data streams, I did notice something … extra.  When I used ‘xattr -w’ to create a new alternate data stream, the modified times didn’t change on the target file, either when viewing it from the Mac over SMB or viewing it in a command prompt on the Windows side – here’s the same directory I was manipulating above, viewed from the Windows 10 machine where it resided:

C:\Temp>dir /r
 Volume in drive C has no label.
 Volume Serial Number is FA12-EC34

Directory of C:\Temp

04/03/2019  02:27 AM    <DIR>          .
04/03/2019  02:27 AM    <DIR>          ..
04/03/2019  02:33 AM                24 file201904030227.txt
                                    14 file201904030227.txt:ads0233.txt:$DATA
                                    14 file201904030227.txt:ads0239:$DATA
03/24/2019  02:34 AM                 0 fromLinux0234
02/15/2019  05:14 PM               395 sprayed-creds.txt
                                     17 sprayed-creds.txt:ads.txt:$DATA
                                 59,392 sprayed-creds.txt:nc.exe:$DATA
02/09/2019  10:39 PM             1,620 UserList.txt
               4 File(s)          2,039 bytes
               2 Dir(s)   4,688,662,528 bytes free

This was totally unexpected! The ads file201904030227.txt:ads0239 was written from the Mac at about 02:39am, as the name and contents imply.  The ADS above it in the directory file201904030227.txt:ads0233.txt listing was written at 02:33am, as the name implies (yes, this kind of thing does keep me up past midnight.  Or maybe it’s the energy drinks.)

While I don’t have an exhaustive Mac lab, containing every version known to man, I’ve tested this on multiple versions of OS X and found the behavior consistent, and used several different target OS’s and systems.  This has shown to work the exact same way from Yosemite, Sierra, High Sierra and Mojave, and against targets including Windows 10, Windows Server 2012r2 NTFS and ReFS partitions and even a Synology BTRFS volume shared via SMB. (My other NAS, a Seagate ReadyNAS, does not support them.  I believe the volume is formatted EXT4.)

This means we can create, access and delete alternate data streams via SMB without changing modification times on files. This gives us a potential new way to run under the radar.  If we don’t change file times, we’re less likely to be noticed. 

One example comes to mind – what if we take a directory where alternate data streams are expected to exist, and use that directory to hide data, scripts, or even executables?  If you consider the User Downloads folder, it’s generally full of alternate data streams.  We usually ignore them.  If you were hunting for alternate data streams to look for bad things, you’d probably ignore this folder – too many false positives. We could add extra streams to some of them, or add the information we’re trying to hide to the contents of a Zone.Identifier. Were someone to compare the modified dates and times of the files in the download folder to the browser history information, they’d find nothing unusual.  Now, a very sharp-eyed person could see that the average Zone.Identifer file is 26 bytes long, and take note of file sizes that differ.  But, of course we can deal with this and script a way to stitch together multiple chunks strewn among data streams.  Or, we could roll the dice that nobody notices, or that they assume that some third-party browser has changed the way they write Zone.Identifiers. (Which could be true – I’ve noticed in the past slight differences between Chrome, Edge and Firefox Zone.Identifier files – I’ve seen some in the past that included the full URL the file was downloaded from.  If I saw a Zone.Identifier file with some funky Base64 inside it, I might investigate, or I might just assume the browser found some fun new way to monetize tracking me.  I’d delete it – but I wouldn’t catch the real attacker!)

There’s another problem with this tactic – the Downloads folder can be temporal.  Files are downloaded to the directory, then moved to another folder, or deleted if no longer needed because the user is going through their every other month pruning cycle because they’re running out of disk space. We need something more permanent, something that won’t be deleted, like maybe one of the standard Windows directories!

Directories present all kinds of ways to take advantage of alternate data streams, but here again, we’ve got to be careful.  If you’re specifically looking for them you’ll see them – frankly they’ll kind of jump out at you.  We need a directory that won’t be looked at, and won’t be deleted.   

$Recycle.bin to the rescue.

The Recycle Bin is normally hidden.  When you look at a directory listing in cmd or Powershell, it’s typically hidden – on most folders and systems, “Hide protected operating system files” is checked, and you get a very scary warning if you try to uncheck it. Even checked, it doesn’t show up when you run a directory in cmd.exe or Powershell.  It’s rather hard to address it directly in a command line – you sometimes have to use a format called DOS Device Path Naming to access it – \\?\c:\$Recycle.bin, and even then, Powershell does not like this – it throws an error in the Get-Item cmdlet. You can find it with the /ah switch on dir, but again, it’s almost always overlooked.

But from the Mac?  It’s totally visible and totally ready to manipulate! Here’s the root directory of the Windows 10 image we use in Security 504:

Olorin:c$ ron$ ls -l

Olorin:c$ ron$ ls -l
total 1344753
drwx------@ 1 ron  staff      16384 Dec 16  2016 $Recycle.Bin
-rwx------  1 ron  staff          1 Jul 16  2016 BOOTNXT
-rwx------  1 ron  staff       8192 Dec 16  2016 BOOTSECT.BAK
drwx------@ 1 ron  staff      16384 Dec 16  2016 Boot
drwx------  1 ron  staff      16384 Dec 16  2016 Documents and Settings
drwx------  1 ron  staff      16384 Jul 16  2016 PerfLogs
drwx------  1 ron  staff      16384 Jul  5  2018 Program Files
drwx------  1 ron  staff      16384 Apr  7 20:33 Program Files (x86)
drwx------  1 ron  staff      16384 Jul  5  2018 ProgramData
drwx------  1 ron  staff      16384 Dec 16  2016 Recovery
drwx------  1 ron  staff      16384 Jul 18  2018 System Volume Information
drwx------  1 ron  staff      16384 Apr  3 04:14 Temp
drwx------  1 ron  staff      16384 Mar 24 02:16 Tools
drwx------  1 ron  staff      16384 Dec 16  2016 Users
drwx------@ 1 ron  staff      16384 Mar 24 00:56 Windows
-rwx------  1 ron  staff     389408 Dec  9  2016 bootmgr
-rwx------  1 ron  staff  671088640 Apr  3 04:11 pagefile.sys
-rwx------  1 ron  staff   16777216 Apr  3 04:11 swapfile.sys
drwx------  1 ron  staff      16384 Jun  1  2018 tmp
drwx------@ 1 ron  staff      16384 Jul 18  2018 wiki

Notice the ampersands?  Yeah, I’ve already muddled around with this particular image.  In this case I was spelunking through the directory structure looking for places to hide things.  I found that some directories could not accept an alternate data stream whether created from Windows or a Mac, particularly the user libraries.  These folders are rather special in Windows, and are treated differently, although over SMB and to the user they present as normal folders.

However, some other special folders allowed me to add alternate data streams just fine, like Boot and Windows … and the Recycle Bin.

Now, adding text using xattr is easy – you can use the -w option.  The format is

xattr -w <ads-name> <ads-content> <file to attach to>

It works very well, and if you need spaces, just put quotes around the content text.  However, binary data is a little harder.  What if we want to copy our little friend netcat into a stream?  It’s small – 59,392 bytes to be exact – but it’s not exactly text-friendly.  Fortunately, xattr can handle this – if you want to write binary data, you just have to pass it the hex equivalent and use the -x flag. So, if we can convert the binary to hex, we can put anything we want into a stream attached to almost any Windows file, all over SMB.  The trick is to string everything together in the right way.

xattr -x -w nc.exe "`xxd -ps Temp/nc.exe`" \$Recycle.bin

Because not everyone gets to script in bash regularly, let’s break this down.  The -x option tells xattr it’s receiving binary data in hex format.  The -w tells it to write an extended attribute (which will be converted to an alternate data stream by the OS X SMB stack.). The next section is where we create the hex: the double quotes are necessary to keep it all as one token for the xattr command.  The backward quotes (or backticks if you prefer) tell bash to run the command inside them and capture the output as text.  The xxd command with -r and -p reads a binary file and prints the hex equivalent.  The last part is the file name, which we have to fiddle with because the $ is a special character in Bash – so we escape it.

The outcome? Hop over to Windows and see if it worked:

C:\>streams64 c:\$Recycle.bin

streams v1.60 - Reveal NTFS alternate streams.
Copyright (C) 2005-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

c:\$Recycle.Bin:
          :nc.exe:$DATA 59392

Woot! We’ve created an alternate data stream, containing an executable, on a file that most Windows users and admins will never pay a second thought to. If you run dir /r to look for alternate data streams, it won’t show up:

C:\>dir /r
 Volume in drive C has no label.
 Volume Serial Number is FA12-EC34

 Directory of C:\

04/02/2019  01:51 AM             6,148 .DS_Store
                                    60 .DS_Store:AFP_AfpInfo:$DATA
07/16/2016  06:47 AM    <DIR>          PerfLogs
07/05/2018  09:53 PM    <DIR>          Program Files
04/07/2019  08:33 PM    <DIR>          Program Files (x86)
04/09/2019  04:24 PM    <DIR>          Temp
06/01/2018  02:04 PM    <DIR>          tmp
03/24/2019  02:16 AM    <DIR>          Tools
12/16/2016  01:37 AM    <DIR>          Users
07/18/2018  07:56 PM    <DIR>          wiki
                                    22 wiki:ads0141:$DATA
03/24/2019  12:56 AM    <DIR>          Windows
                                    28 Windows:ads0055:$DATA
                                    22 Windows:ads0137:$DATA
               1 File(s)          6,148 bytes

One final test – can we run it? We can use wmic:

wmic process call create \\?\c:\$Recycle.bin:nc.exe

And the result?

using WMIC to launch an executable from an alternate data stream

A working netcat executable, attached to a folder that few people will even look at, let alone consider checking for alternate data streams, and if you noticed the modified date on the directory listing I pulled (from the Mac), the file times didn’t change.

Here’s the file times viewed from the Windows side (with protected file viewable checked.)

Explorer window, showing file modified time has not changed

Ok, putting back on my blue team hat (it feels so comfy), how can we detect this.  Well, we have to dig into our toolbag, because native Windows doesn’t have a lot of ability for this. 

For example – Powershell’s Get-Item cmdlet can find alternate data streams with the -streams * option added on:

PS C:\> get-item -path * -stream *


PSPath        : Microsoft.PowerShell.Core\FileSystem::C:\.DS_Store::$DATA
PSParentPath  : Microsoft.PowerShell.Core\FileSystem::C:\
PSChildName   : .DS_Store::$DATA
PSDrive       : C
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : False
FileName      : C:\.DS_Store
Stream        : :$DATA
Length        : 6148

PSPath        : Microsoft.PowerShell.Core\FileSystem::C:\.DS_Store:AFP_AfpInfo
PSParentPath  : Microsoft.PowerShell.Core\FileSystem::C:\
PSChildName   : .DS_Store:AFP_AfpInfo
PSDrive       : C
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : False
FileName      : C:\.DS_Store
Stream        : AFP_AfpInfo
Length        : 60

But it doesn’t see the streams we already know are attached to Windows, Boot and the Recycle Bin.

PS C:\> get-item -path Windows\ -stream *
PS C:\> get-item -path Boot\ -stream *
get-item : Could not find item C:\Boot\.
At line:1 char:1
+ get-item -path Boot\ -stream *
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Boot\:String) [Get-Item], IOException
    + FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetItemCommand

PS C:\>

PS C:\> get-item -path \\?\c:\$Recycle.bin  -stream *
Get-Item : A parameter cannot be found that matches parameter name ‘stream’.
At line:1 char:37
+ get-item -path \\?\c:\$Recycle.bin  -stream *
+                                     ~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Item], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetItemCommand

Fortunately, we have some other handy tools: lads and Streams.

PS C:\> c:\tools\lads\lads

LADS - Freeware version 3.21
(C) Copyright 1998-2003 Frank Heyne Software (http://www.heysoft.de)
This program lists files with alternate data streams (ADS)
Use LADS on your own risk!

Scanning directory C:\

      size  ADS in file
----------  ---------------------------------
     59392  C:\$Recycle.Bin\:nc.exe
        60  C:\.DS_Store:AFP_AfpInfo
        22  C:\Boot\:ads0202
Error 32 opening C:\pagefile.sys: The process cannot access the file because it is being used by another process
Error 32 opening C:\swapfile.sys: The process cannot access the file because it is being used by another process
        22  C:\wiki\:ads0141
        28  C:\Windows\:ads0055
        22  C:\Windows\:ads0137

The following summary might be incorrect because there was at least one error!

     59546 bytes in 6 ADS listed

PS C:\> streams c:\*.*

streams v1.60 - Reveal NTFS alternate streams.
Copyright (C) 2005-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

c:\$Recycle.Bin:
          :nc.exe:$DATA 59392
c:\.DS_Store:
     :AFP_AfpInfo:$DATA 60
c:\Boot:
         :ads0202:$DATA 22
Error opening c:\pagefile.sys:
The process cannot access the file because it is being used by another process.

Error opening c:\swapfile.sys:
The process cannot access the file because it is being used by another process.

c:\wiki:
         :ads0141:$DATA 22
c:\Windows:
         :ads0055:$DATA 28
         :ads0137:$DATA 22
PS C:\>

Note:  Lads does not work on ReFS volumes, only NTFS.  If you run lads in a directory on an ReFS volume, it will complain the ReFS does not support alternate data streams, which at one time was true, but not today. Streams is perfectly happy on both NTFS and ReFS and even on BTRFS served over SMB.

So, we do have the ability to hunt for this, if we have an inkling that an attacker is using this tactic. Of course, you can use a Mac to do this as well, as long as the folder you’re checking is accessible via SMB.  Or you can use the Linux smbclient – new versions include the allinfo command, which will identify the existence of alternate data streams, even on special directories like Boot and $Recycle.bin. Finally, it’s a good bet that your EDR, if you use one, also will detect this behavior, although the jury’s out on if it will raise an alert or simply create an event that you’d have to hunt for.

One final note:  When I turned on file access auditing, file access times did change when using xattr, both to view and to write streams.  Modified times remained the same.

Handy ASCII chart for packet and script decoding

When I took the GIAC Certified Intrustion Analyst (GCIA) exam, I had not yet mastered the skill of calculating binary numbers in my head. Truth be told, I doubt I ever will! As an aid in the exam, I brought an ASCII chart with me, one that had columns for Hex and Binary as well as decimal. Not only does it let me match a number to a character quickly, a task I do countless times in obfuscated script analysis, it makes converting any 8-bit number to its corresponding hex and decimal values very quick. If you don’t do this math often enough to become good at the math, I offer this spreadsheet for you to download, customize the colors and fonts to your liking, and then either print it out or convert it to HTML or PDF for a quick reference on the job or on an open book exam like GIAC’s GCIA.

Accessing Alternate Data Streams from a Mac

Most of you have probably heard of alternate data streams, a semi-obscure means of attaching additional data to a file on Windows machines, specifically under NTFS (and now ReFS.) Alternate data streams, often abbreviated as ADS, were originally intended to store metadata about files. For example, in order to make NT a better file server for the Macintosh systems of the day when it was developed, Microsoft added ADS to allow Mac clients to save files with resource forks, the metadata used at the time for icons and other attributes of mac files. 

This would seem to imply that ADS are small pieces of data, but there’s really not any size limit imposed by the NTFS filesystem – nor is there a limit on the types of data.  You can store text like text files, source code, and XML and HTML documents or binary data, including images, audio files and even executables and libraries. ADS don’t have many applications on Windows today, but one very common use still is marking the source of a files downloaded using a web browser. IE, Edge, Chrome and other browsers will add an ADS named Zone.Identifier to a file downloaded using the browser with some info about the source, some browsers even adding other details about the file downloaded like source and referrer URLs.  A few DLP solutions mark files with ADS to help track files leaving the organization in ways they aren’t supposed to.  And of course, malicious parties can hide data or even executables inside ADS.

There are several means to access them on Windows, but just to be different, I want to demonstrate ways to access ADS using a Mac.  Next time we’ll look at some of the best ways on modern Windows systems to see ADS and manipulate them. Note:  this technique also works on Linux, I’ll likely be testing this for a future blog post.

For this demonstration I’m going to connect to a Windows file share over SMB, then locate ADS using the ls command, and access the contents with the xattr command.

First, I need to make sure I have some ADS to view:

I created file1.txt and its ADS, file1.txt:ads.txt using notepad.  You can see I used the command “dir/r” to list the contents of the C:\Temp directory.

Next, I need to connect to a file share from the Mac.  For simplicity I’ll be using the C$ default share, which gives me access to the entire C drive, as long as I use an account with administrative privileges.

 

Once I’ve connected, Finder shows I have access to the C drive on the target system:

And the contents of Temp:

This view in Finder, like Explorer in Windows, doesn’t show the ADS, just the parent file it’s “riding” on. For that, we’ll need to switch to the command line

First, I’ll check that the share is mounted and where:

Olorin:~ ron$ mount
/dev/disk1 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)
/dev/disk3s2 on /Volumes/SSDExternal (exfat, local, nodev, nosuid, noowners)
//XXXXXX@10.11.76.100/c$ on /Volumes/c$ (smbfs, nodevnosuid, mounted by ron)

Switching to the Temp directory and running the ‘ls’ command gives me this:

Olorin:~ ron$ cd /Volumes/c\$/Temp/
Olorin:Temp ron$ ls -l
total 1
rwx——@ 1 ron  staff  21 Jul 23 02:51 file1.txt

Looks like a normal output for ls, but look just to the right of the permissions block and you’ll see an ‘@’ symbol.  This is the ls command telling you that that file has an extended attribute.

Extended attributes is the *NIX name for metadata not usually interpreted by the filesystem, unlike typical attributes like size and permissions. Extended attributes allow the operating system and applications to apply their own metadata to file that will usually stay “stuck” to the file when copied to other volumes that support extended attributes. (great writeup here: https://en.wikipedia.org/wiki/Extended_file_attributes)

The ls command shows you a file has extended attributes.  If we run it again with another option, @, we’ll see more:

Olorin:Temp ron$ ls -l@
total 1
rwx——@ 1 ron  staff  21 Jul 23 03:33 file1.txt
    ads.txt 49

The xattr command can view names and contents, create and delete extended attributes. And as you’ve probably guessed by now, the Mac operating system treats ADS as just another extended attribute, so we can use xattr to access ADS as well!

Using xattr with no options will give us the name:

Olorin:Temp ron$ xattr file1.txt
ads.txt

If we run xattr with the -l option, it lists the name and the contents:

Olorin:Temp ron$ xattr -l file1.txt
ads.txt: This is the contents of an alternate data stream.

What if the ADS is a binary file? Can we access those as well?  Turns out, we can! 

I’ll create a binary ADS on the Windows side just by copying an executable into the ADS, in this case, our beloved netcat.

Back to the Mac:

Olorin:Temp ron$ ls -l@
total 1
rwx——@ 1 ron  staff  21 Jul 23 03:33 file1.txt
    ads.txt 49
    nc.exe 59392
Olorin:Temp ron$ xattr
file1.txt
ads.txt
nc.exe

So we can see from both ls and xattr that file1.txt has two ADS attached.  Can we view the contents?

Olorin:Temp ron$ xattr -l file1.txt
ads.txt: This is the contents of an alternate data stream. nc.exe:
00000000  4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00  |MZ…………..|
00000010  B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00  |……..@…….|
00000020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |…………….|
00000030  00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00  |…………….|
00000040  0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68  |……..!..L.!Th|
00000050  69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F  |is program canno|
00000060  74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20  |t be run in DOS |
00000070  6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00  |mode….$…….|
00000080  50 45 00 00 4C 01 04 00 B9 8E AE 34 00 00 00 00  |PE..L……4….|
00000090  00 00 00 00 E0 00 0F 01 0B 01 05 00 00 98 00 00  |…………….|
000000A0  00 62 00 00 00 00 00 00 00 4C 00 00 00 10 00 00  |.b…….L……|
000000B0  00 B0 00 00 00 00 40 00 00 10 00 00 00 02 00 00  |……@………|
000000C0  04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00  |…………….|
000000D0  00 30 01 00 00 04 00 00 00 00 00 00 03 00 00 00  |.0…………..|
000000E0  00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00  |…………….|
000000F0  00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00  |…………….|
00000100  00 20 01 00 3C 00 00 00 00 00 00 00 00 00 00 00  |. ..<………..|
00000110  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |…………….|
00000120  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |…………….|
00000130  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |…………….|
00000140  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |…………….|
00000150  00 00 00 00 00 00 00 00 A0 21 01 00 64 01 00 00  |………!..d…|
00000160  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |…………….|
00000170  00 00 00 00 00 00 00 00 2E 74 65 78 74 00 00 00  |………text…|
00000180  70 97 00 00 00 10 00 00 00 98 00 00 00 04 00 00  |p……………|
00000190  00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60  |………… ..`| …
(many, many, lines followed this)

Well, yes, but it’s kind of messy.  (note though the characteristic MZ right at the beginning, the magic number that clues us in that this is a Windows portable executable file.)

Let’s use some other options on xattr.

The -p option prints the contents of a specific extended attribute, just by specifying the name in the command:

Olorin:Temp ron$ xattr -p
ads.txt file1.txt
This is the contents of an alternate data stream.

Using -p on the binary file gives us

Olorin:Temp ron$ xattr -p nc.exe file1.txt
4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00
B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00
0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68
69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F
74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20
6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00
50 45 00 00 4C 01 04 00 B9 8E AE 34 00 00 00 00
00 00 00 00 E0 00 0F 01 0B 01 05 00 00 98 00 00
00 62 00 00 00 00 00 00 00 4C 00 00 00 10 00 00
00 B0 00 00 00 00 40 00 00 10 00 00 00 02 00 00
04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
00 30 01 00 00 04 00 00 00 00 00 00 03 00 00 00
00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00
00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
00 20 01 00 3C 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 0 …

Much cleaner: we have the raw bytes in hexadecimal format.   We can now use another *NIX stalwart tool to extract the binary file, xxd.

Most *NIX versions include xxd, a command line tool that can convert bytes for display in hex format and convert hex formatted bytes back to binary data that can be used as the original.  We’re going to use the options on xxd that allows the hex stream by itself to be reassembled and converted, -r to reverse from hex and -p to accept plain streams of hex without offsets in the left column.

Olorin:Temp ron$ xattr -p nc.exe file1.txt | xxd -r -p > /tmp/nc.exe
Olorin:Temp ron$ ls -l /tmp/nc.exe
rw-r–r— 1 ron wheel  59392 Jul 23 03:53 /tmp/nc.exe

And if I check the sha1 hash for the extracted data I can see it’s the exact same file – the hash matches what I calculated in Windows from the original copy of nc.exe:

Olorin:Temp ronshasum /tmp/nc.exe
57f0839433234285cc9df96198a6ca58248a4707  /tmp/nc.exe

I can even create an ADS using xattr -w

Olorin:Temp ron$ xattr -w ads2.txt “This is also an alternate data stream.” file1.txt

Olorin:Temp ron$ ls -l@
total 1
rwx——@ 1 ron  staff  21 Jul 23 03:33 file1.txt
    ads.txt 49
    ads2.txt   38
    nc.exe 59392

And going back to my Windows machine:

Of course, the final thing we might want to try is get rid of an ADS, which xattr can do with the -d option:

Olorin:Temp ron$ xattr -d ads2.txt file1.txt
Olorin:Temp ron$ ls -l@
total 1
rwx——@ 1 ron  staff  21 Jul 23 03:33 file1.txt
    ads.txt 49
    nc.exe 59392

So, what could we use this capability for?  If we can connect via SMB, we can pull data from  an ADS, we can add a new ADS, and we can use it to delete ADS from a file.  One particular use case as a pentester (or attacker) might be to modify the Zone.Identifier for a file in the Downloads directory or get rid of the Zone.Identifier entirely to obscure the origin of a file on a system. Or, as fellow instructor Mick Douglas suggests, use this capability to look  for interesting DLP tags.

On the DFIR side, you could use this technique to remotely look for these files using command line tools on your Mac.  This appears to have an interesting advantage: accessing the file using xattr over SMB seems to not change access or modified times. I just noticed this – it’s not fully tested, but when I created an ADS using the xattr command over SMB, the write time didn’t change, but when I used the type command at the cmd.exe prompt, it did. You can see in the screen shots above that when I added the ADS file1.txt:nc.exe, the modified time changed to 02:33 AM, but when I added the ADS file1.txt:ads2.txt, it did not change the file modified time. File created and access times weren’t changed by any operations on ADS, regardless of whether they were done on the Windows command line or by xattr via SMB.  More testing on this oddity is warranted!

I hope this was an interesting diversion, and if you find this helpful, please let me know in the comments or drop me a message!

*I’d love to give full credit to the original blog I learned about xattr from, but I didn’t bookmark it.  If I find it again, I’ll be sure to post a link here to give credit where credit is due!

ron hamann, Janky Robot Security, LLC