moth/puzzles/steg/100/index.exe

81 lines
2.1 KiB
Python
Executable File

#! /usr/bin/python
## Fetch some public domain images, make a PNG of the key, and encode
## that in the Exif.Image.OriginalRawFileData tags of the images
import os
import glob
import random
import shutil
import md5
import sys
import zipfile
key = 'wilderness fishsticks'
srcdir = os.path.dirname(sys.argv[0])
exifblah = os.path.join(srcdir, 'image.cmds')
def system(cmd):
ret = os.system(cmd)
if ret:
raise OSError('return value %d: %s' % (ret, cmd))
# Download war posters
if not os.path.exists('ww0207-43.jpg'):
system('wget -r -D digital.library.northwestern.edu -A jpg -nd -l 2 "http://digital.library.northwestern.edu/otcgi/digilib/llscgi60.exe?mode=phrase&query=conserve&REGION=&SIZE=20&db=0"')
os.unlink('robots.txt')
# Store the key
open('key', 'w').write(key)
# Make a PNG of it
f = os.popen('pbmtext < key | pnmtopng -compression 0')
key_png = f.read()
# Duplicate two photos
jpegs = glob.glob('*.jpg')
random.shuffle(jpegs)
for fn in jpegs[:2]:
root, ext = os.path.splitext(fn)
nfn = '%s.dup%s' % (root, ext)
shutil.copy(fn, nfn)
jpegs.append(nfn)
random.shuffle(jpegs)
bytes_per_photo = len(key_png) / len(jpegs)
zipf = zipfile.ZipFile('archive.zip', 'w')
for i in range(len(jpegs)):
fn = jpegs[i]
cmd1 = 'set Exif.Canon.0x0019 %d' % i
offset = i * bytes_per_photo
if i == len(jpegs) - 1:
bytes = key_png[offset:]
else:
bytes = key_png[offset:offset + bytes_per_photo]
bytes_str = ' '.join(str(ord(c)) for c in bytes)
cmd2 = 'set Exif.Canon.0x0018 "%s"' % bytes_str
# First set some defaults
system('exiv2 -m %s %s' % (exifblah, fn))
# Now apply our devious stuff
system('exiv2 -M\'%s\' -M\'%s\' %s' % (cmd1, cmd2, fn))
# Read it in
contents = open(fn, 'rb').read()
# Find the new file's md5 checksum
checksum = md5.new(contents).hexdigest()
# Make a new zip file entry
zi = zipfile.ZipInfo(checksum + '.jpg')
zi.compress_type = zipfile.ZIP_DEFLATED
zi.external_attr = 0644 << 16L
zipf.writestr(zi, contents)
# We're done with this file
os.unlink(fn)