Write-up - Defcon-20-quals 2012 - Forensic 400
by @Jiss and @Jonathan Salwan - 2012-06-04We download the file, and we unzip all.
$ gzip -d ./for400-411f6273d434317ccdb567a8e345eddc.gz $ tar -xf for400-411f6273d434317ccdb567a8e345eddc $ ls -l total 2.1G -rw-r--r-- 1 jonathan users 1.1G Jun 3 18:28 for400-411f6273d434317ccdb567a8e345eddc -rw-r----- 1 jonathan users 1.0G May 28 09:06 memory.dmp $
We now have a 'memory.dmp' file. So we use 'volatility' tool to extract some informations about this file.
First of all, let's see which type of dump it is:
$ vol.py imageinfo -f ./memory.dmp Volatile Systems Volatility Framework 2.0 Determining profile based on KDBG search... Suggested Profile(s) : Win7SP1x86, Win7SP0x86 AS Layer1 : JKIA32PagedMemoryPae (Kernel AS) AS Layer2 : FileAddressSpace (C:\Users\Jiss\defcon\for400\memory.dmp) PAE type : PAE DTB : 0x185000 KDBG : 0x82948c28L
Let's list all the processes:
> vol.py pslist --profile=Win7SP1x86 -f ./memory.dmp Volatile Systems Volatility Framework 2.0 Offset(V) Name PID PPID Thds Hnds Time ---------- -------------------- ------ ------ ------ ------ ------------------- 0x84138c40 System 4 0 86 496 2012-05-28 02:31:14 0x846ea308 smss.exe 244 4 2 29 2012-05-28 02:31:14 [...] 0x84945030 chrome.exe 3884 3440 6 126 2012-05-28 02:36:37 0x8494dd40 rundll32.exe 3916 3440 2 84 2012-05-28 02:36:37 0x8494ed40 chrome.exe 3924 3440 6 209 2012-05-28 02:36:37 0x8495d508 chrome.exe 4004 3440 6 124 2012-05-28 02:36:41 0x85716d40 thunderbird.ex 2372 2176 36 432 2012-05-28 02:47:24 0x849e2540 gpg.exe 2804 2372 0 ------ 2012-05-28 02:50:29 0x84a16168 gpg-connect-ag 3616 2372 0 ------ 2012-05-28 02:50:29 0x84a25d40 gpg-agent.exe 4036 3128 1 72 2012-05-28 02:50:30 0x848a8d40 gpg.exe 2360 2372 0 ------ 2012-05-28 02:54:56 0x84a25030 gpg.exe 2464 2372 0 ------ 2012-05-28 02:54:56 [...] 0x84a22a38 pinentry.exe 3692 4036 0 ------ 2012-05-28 02:56:27 0x849fb620 pinentry.exe 3868 4036 0 ------ 2012-05-28 02:56:30
We have two interesting processes, '2372' and '4036' (thunderbird & gpg-agent). So, wo dump the memory of this two process.
$ vol.py --profile=Win7SP1x86 -f ./memory.dmp -p 2372 memdump -D out/ Volatile Systems Volatility Framework 2.0 ************************************************************************ Writing thunderbird.ex [ 2372] to 2372.dmp $ vol.py --profile=Win7SP1x86 -f ./memory.dmp -p 4036 memdump -D out/ Volatile Systems Volatility Framework 2.0 ************************************************************************ Writing gpg-agent.exe [ 4036] to 4036.dmp
Running a "strings" on the thunderbird memory dump reveals some interesting informations:
vulcan.ddtek@gmail.com Poseidon ddtek <poseidon.ddtek@gmail.com>
If we grep "ddtek" we get something else:
"Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>"
Let's take a look:
jiss@fistouille:$ strings 2372.dmp | grep "Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>" -B 5 [GNUPG:] GOOD_PASSPHRASE [GNUPG:] ENC_TO 21877E7CEC1B51DB 1 0 gpg: encrypted with RSA key, ID EC1B51DB [GNUPG:] NO_SECKEY 21877E7CEC1B51DB gpg: encrypted with 1024-bit RSA key, ID D7A51CC5, created 2012-05-26 "Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com>"
Well, we have some informations concerning the key used to cipher some messages :). Now let's try to find those messages in gpg-agent memory dump, by searching PGP headers ("-----BEGIN PGP MESSAGE-----"). We get two different ones:
-----BEGIN PGP MESSAGE----- Charset: ISO-8859-1 hIwDsrGmc9elHMUBBACfm/ebMfFiOfxmpBCpfHQbB/XFdh1T1KiGJBJkLe1WMCyE T8TVgNTzs3Bljuy4DjUMv8rz0jkCV8nR0e6GxZGkoPLIuoYoovy2ctS9w49C8F9p LOkWKq7/Sun+XQQEBqzAyIjj8/7wz6lE1t7UKHjpepVK+0AibNAq5s+oRqi1SIUB DAMhh3587BtR2wEH/3kyO9ITIML9XK+6/7TRwQqaVZSUk86fUSQXvLStJa47dVDp jjj1CiGWp+B+kLsiVgXZHUT8g+D/ILlDzF5xBmHF6q3u0lsE+eNzhS+h+ogq+y9j bCNn+vYnzuOt8DoOrY4rFHtEnXKrhPQOntYIvsu1cPxVk2UMGJhdF1npi0wiaAK3 1vPCZCsyZaRog3sXfufIdVQTiRiYNSZv1BJUqxK0cr3hXaH71hy2Y5nyEc467PNw 6Tw8jhCt8idoqYHaxFfOe4BKiJU5mlR0UXgE+V8gVc97wtJeAVX13QlxYh1A/jqh WruoYer5HGBAtNjJjjfbIFrFQRFfXxcPVJrV3CHSwO0BdsXm3EYtcjwuWdrAgMrn SF3/mMy8jl5Lozqu7uBNlprVm3ruPnEQnevGF990Yhh8333Ibj7Vuh69pYISAGHZ Vl2iUhhaioaqVV9Z3K9p5Pyc4bvmPLw4Mk08gpFpjRJsu3A1GgwfHa18wlphe9eP er/a+mNvGBfvG8a0rxOCxyG8CpCx1cKwp4g11wk2mmSnX4wmthf1kBuZk7XLBti+ 9P9UfaZ5ejKq6hoKmAhJqjuYNfXiYJQtJDCZtv2vrnkE0+pozt65EZLm5bxUz+dH TYTv9axHvPC60ECEWZh6qo1RhJ6zJqRn96l60T0w3+6Er3yWB+JgRBWj8tSAaVOh SfMz+n7gjpsVqcOgcR9/5Al2Kk4TumqHjguStuDRRk4WP5ShLFNRRI0TaqoBo/ie KXmw/Vf+23hgM4oQctqTgLbCSKcJANlCgJRLDRGtt4FkVLUW3+WQW0m8ECfYJtEz Ev1crVOvnKdrg/VpE+fOMEYZTlIgeNplbJCEwSF15ExXIc6G2c2xirFK31GLNi7Y aCDT4u89x/vAm0eM5BIVecolcUJtQLW0Q9vu5QI= =pAdV -----END PGP MESSAGE----- -----BEGIN PGP MESSAGE----- Charset: ISO-8859-1 hIwDsrGmc9elHMUBA/9aYQWeLQ9tSBdFK9mNKNZKuJ5KbTNtt4irHXnxqDXhFTgW j77y3oFg6v1MKiEFqVJY1dBsmVYVa6N9pL/hJ5jZswSng6j8bZAGj1DxVobgoSDR lwXC/UGatkCrB20TvUMlMUgiz3lKFiqwtQBkhvOgAc+NUVpnoyOCkItqx+RV0IUB DAMhh3587BtR2wEIAMb9yaOBY17hSr01i4594PYBZlW1P4fdQgoK+DskDQRFoYeQ YFlaR1v0pjTGYz8imFF2KVVym83MRElU/BirXavWaWN3oIIROePp82KgnVKUcoKi pfFhw5hnHchkhlo4AateQgHBOibknzfZ38jUyqAoY75k5RV42IfZlAlgizSaGdfs gZKeeBSkPTH0GEbvDh116PCZEtP3eY7WpbZ+meSp2kooXZ2qjWF6O84BE6YeguDd r5cD5AzkwSpV4kjt9tWZCC0o/eUDZ2yXb1PLYrppdX9kChw+Xc6nkp7nJwvARQNv o4vAPwP2iibPcttTqsNgRvPUmUstM3Xr20D/sk7SewHWQlEuKSWyMyTdWKNwSU82 MxBcDAODNV1Wju7q8KYYdfPcPXgsIHF0MNPCKnX6J6gyf9H45ERMsPzWGKnJQaIJ gJQLWPUi6pnqOqf+c68JuINTOmhv7W9XyfyNKEHb/zYcZtF46dK8xYSjyIHzR14E uzHweaqnPPHo4w== =x441 -----END PGP MESSAGE-----
Ok right now, we have some messages ciphered and information concerning the private key. Let's inspect the initial memory.dmp, searching the string "(defcon ctf quals key)". We finally find this string among something which seems to be a binary blob. Let's dump this and take a look:
jiss@fistouille:$ file try_key.dmp try_key.dmp: PGP key security ring
Great !
jiss@fistouille:$ gpg --import try_key.dmp gpg: cle FB9C695E: cle secrete importee (secret key!) gpg: cle FB9C695E: cle publique " Poseidon (defcon ctf quals key) <poseidon.ddtek@gmail.com> " importee gpg: Quantite totale traitee: 1 gpg: importee: 1 (RSA: 1) gpg: cles secretes lues: 1 gpg: cles secretes importees: 1
Let's decipher messages:
jiss@fistouille:$ for i in $(seq 1 2); do gpg --decrypt $i.txt ; done * g o a t s e x * g o a t s e x * g o a t s e x * g g o / \ \ / \ o a| | \ | | a t| `. | | : t s` | | \| | s e \ | / / \\\ --__ \\ : e x \ \/ _--~~ ~--__| \ | x * \ \_-~ ~-_\ | * g \_ \ _.--------.______\| | g o \ \______// _ ___ _ (_(__> \ | o a \ . C ___) ______ (_(____> | / a t /\ | C ____)/ \ (_____> |_/ t s / /\| C_____) | (___> / \ s e | ( _C_____)\______/ // _/ / \ e x | \ |__ \\_________// (__/ | x * | \ \____) `---- --' | * g | \_ ___\ /_ _/ | g o | / | | \ | o a | | / \ \ | a t | / / | | \ |t s | / / \__/\___/ | |s e | / | | | |e x | | | | | |x * g o a t s e x * g o a t s e x * g o a t s e x * the key is: as it turns out, Phil Zimmermann also likes sheep.
Well, the goatse ASCII-art might not be the validation key...
So, here it is: as it turns out, Phil Zimmermann also likes sheep.