Parsing .DS_Store Files

TLDR: Recently I had cause to revisit an old script I wrote to parse .DS_Store files I discover on web application tests. I have released this tool to the community in the hope it can be helpful to others:

https://bitbucket.org/grimhacker/ds_store_parser

What is a .DS_Store file?

In the Apple macOS operating system, .DS_Store is a file that stores custom attributes of its containing folder, such as the position of icons or the choice of a background image. The name is an abbreviation of Desktop Services Store, reflecting its purpose. It is created and maintained by the Finder application in every folder, and has functions similar to the file desktop.ini in Microsoft Windows. Starting with a full stop (period) character, it is hidden in Finder and many Unix utilities. Its internal structure is proprietary.

https://en.wikipedia.org/wiki/.DS_Store

Why should I care?

On a web application security assessment, if you find a .DS_Store file served by the web server you can parse it in order to identify file and directory names. This may disclose “hidden” resources which could constitute a security vulnerability, for example a backup file with a non-predictable name which contains sensitive information.

How do I parse the file?

The .DS_Store is an undocumented proprietary format, luckily Mark Mentovai and Wim Lewis have taken the time to document large portions of it: https://metacpan.org/pod/distribution/Mac-Finder-DSStore/DSStoreFormat.pod

Even more fortuitously Alastair Houghton (al45tair) has written a library in python to manipulate .DS_Store files: https://github.com/al45tair/ds_store

So what have I done?

I have written a simple script which uses al45stair’s library to parse the file, and output the identified filenames.

Initially the script made no distinction between directories and files, however at the request of my colleague @anantshri I have included this functionality. The code in the .DS_Store file entry is used to accomplish this, Wim’s notes indicate several which are only used for directories therefore any filename which has an entry with one of these codes is assumed to be a directory and any without is assumed to be a file. Note that this distinction may not be entirely reliable, however it has worked with the test cases I have.

The script!

https://bitbucket.org/grimhacker/ds_store_parser

Dependencies

The following dependencies are required:

  • python3
  • ds_store
  • argparse

Assuming you have python3, the libraries can be installed with the following command:

python3 -m pip install --user ds_store argparse

Example

The only required argument is the input file, the script will output a list of directories and a list of files:

python3 ds_store_parser.py -i Example_DS_Store
Type: directories :
images
includes


Type: files :
robots.txt
sqlbackupMay2019.tar.gz

There is also a JSON output option which should make further processing trivial:

python3 ds_store_parser.py -i Example_DS_Store -o example.json
Type: directories :
images
includes


Type: files :
robots.txt
sqlbackupMay2019.tar.gz

This will output a file such as the following:

{
    "directories": [
        "images",
        "includes"
    ],
    "files": [
        "robots.txt",
        "sqlbackupMay2019.tar.gz"
    ]
}

Defence

Ensure that your web server is free of .DS_Store files on a regular basis.

Take care when deploying files to your web server that the hidden files are not copied over.

If you mount the web server as a network share, note that Finder will create a .DS_Store file unless you configure it not to: https://blog.tcs.de/prevent-ds_store-file-creation-on-network-drives/

Leave a Reply

Your email address will not be published. Required fields are marked *