<GPS IFD> (in IFD 0) 5 entries starting at file offset 0x2b4=692 <000000= 0> VersionID [1 =BYTE 4] = 2,2,0,0 <0x0001= 1> LatitudeRef [2 =ASCII 2] = 'N' <0x0002= 2> Latitude [5 =RATIONAL 3] = @0x2f4=756 <0x0003= 3> LongitudeRef [2 =ASCII 2] = 'W\000' <0x0004= 4> Longitude [5 =RATIONAL 3] = @0x30c=780 **** next IFD offset 0 ============= VALUES, GPS IFD ============ Latitude = 42,40,16.212 Longitude = 72,33,1.548 </GPS IFD>Using the search feature on Google Maps, putting in "42 40 16.212 N 72 33 1.548 W" results in a pushpin right in the middle of Bernardston.
$ strings forensics200-5be06945190cf5ff9722d0b5f12e0013 JFIF ...Simply stripping off the first 68 bytes (likely the size of a full MACH-O header) we were able to make the file load as a JPG file. The resulting picture showed the key, which was a restaurant sign (indicated by it being circled): IDYLWOOD GRILL
$ file forensics200-5be06945190cf5ff9722d0b5f12e0013 forensics200-5be06945190cf5ff9722d0b5f12e0013: Mach-O universal binary with 3 architectures forensics200-5be06945190cf5ff9722d0b5f12e0013 (for architecture sparc): JPEG image data, JFIF standard 1.01 forensics200-5be06945190cf5ff9722d0b5f12e0013 (for architecture i386): Mach-O executable i386 forensics200-5be06945190cf5ff9722d0b5f12e0013 (for architecture ppc): Mach-O executable ppc $ ditto -arch sparc forensics200-5be06945190cf5ff9722d0b5f12e0013 forensics200.jpg
$ strings forensics300-e130c3621118e4b891fbceb67e2c94cc.dd version name state pool_guid top_guid ... >id1,cmdk@AVMware_Virtual_IDE_Hard_Drive=11000000000000000001/q ... << /Type /Page /Parent 10 0 R /Resources 3 0 R /Contents 2 0 R /MediaBox [0 0 612 792] >> ...Googling "pool_guid top_guid" makes it look like this file is a ZFS dump. The second chunk makes it look like a VMWare virtual disk. The third chunk, however, stands out as a PostScript or PDF file of some kind. Ignoring the horror that might be reading a VMWare image off a ZFS filesystem, we turned to Scalpel.
$ zcat forensics300-e130c3621118e4b891fbceb67e2c94cc.dd.gz | strings | grep -i pdf ... kenshoto.pdf ... $ perl -pi -e 's/^#\s+pdf/pdf/' scalpel.conf $ scalpel -c scalpel.conf forensics300-e130c3621118e4b891fbceb67e2c94cc.dd ... Carve lists built. Workload: pdf with header "\x25\x50\x44\x46" and footer "\x25\x45\x4f\x46\x0d" --> 0 files pdf with header "\x25\x50\x44\x46" and footer "\x25\x45\x4f\x46\x0a" --> 2 files Carving files from image. ...
... 8048787: e8 44 fe ff ff call 80485d0 <time@plt> 804878c: 83 c4 04 add $0x4,%esp 804878f: 50 push %eax 8048790: e8 5b fe ff ff call 80485f0 <srandom@plt> ...As a result, if it's the same time, the random output will be the same. The only question was how many bytes are read before starting the encryption. Assuming that the time stamp on the output file matches the time the srandom() was called, we just repeatedly reset the system clock while brute-forced a few byte lengths until something pops out.
$ stat -t "%Y%m%d%H%M.%S" key.enc 87 565264 -r-------- 1 nops nops 2258139 27 "200705101437.23" "200705101437.23" "200706071815.44" "200705101437.23" 4096 4 0 key.encShort brute-forcer to find key length:
#!/usr/local/bin/bash for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 do # clean up from prior runs rm -f key.enc.dec key.enc.enc # reset system time to key.enc's modification time date 200705101437.23 >/dev/null # get key for this time stamp OUT=$(./awesomeify -b $i key.enc) # convert from text to byte stream KEY=$(echo "$OUT" | cut -d" " -f4 | perl -ne 'while (s/(..)/print chr(hex($1))/eg) {};') # stuff calculated key back into awesomeify echo "$KEY" | ./awesomeify -D -b $i key.enc # look for words WORDS=$(cat key.enc.dec | strings -n 7) if [ -n "$WORDS" ]; then # report words echo "At length $i: '$WORDS'" fi doneWhich the spits out the needed key:
At length 8: 'infinitybitfromsupercipher'(8, as it turns out, is the default key length when not specifying -b.)
$ perl ostest.pl forensics500-88b33eb4b8a2b9a49a632394ba746088.dd ostest - parse dd-style RAM Dump to determine OS (v.0.1_20060914) ... Idle check : 2000 ... System check : 2000 OS guess based on System and Idle checks: 2000
$ perl ./ptfinder_w2k.pl forensics500-88b33eb4b8a2b9a49a632394ba746088.dd No. Type PID TID Time created Time exited Offset PDB Remarks ---- ---- ------ ------ ------------------- ------------------- ---------- ---------- ---------------- ... 14 Proc 728 2007-05-10 01:23:24 0x00167860 0x00b6c000 foo.exe ...
$ perl ./memdump.pl forensics500-88b33eb4b8a2b9a49a632394ba746088.dd 0x00b6c000 $ cat 0xb6c000.map virt. addr. file offset size ------------ ------------ -------- 0x10000 0 0x1000 0x20000 0x1000 0x1000 0x12e000 0x2000 0x1000 ... 0xc04ff000 0xc1000 0x1000 0xc0502000 0xc2000 0x1000
$ strings --radix=x 0xb6c000.mem | grep "forensics challenge" 1f034 forensics challenge 7c034 forensics challengeA quick look into 0xb6c000.map shows the file offset of 0x1f000 is 0x407000:
$ grep 0x1f000 0xb6c000.map 0x407000 0x1f000 0x1000This means our virtual address would be 0x407034 or 0x00407034 per Kenshoto's notation requirement. (0x1f034 - 0x1f000 + 0x407000 == 0x00407034)