plaidCTF 2014 - curlcore (for250)
Last week we played plaidCTF with Eindbazen under the name 0xffa (can you figure out why that name?). Write-ups are mandatory in the rules, so let’s start with an easy one :-)
curlcore
Forensics (250 pts)
-------------------
We managed to grab a memory dump off of The Plague's computer while
he was making a secure download. We think he may have been looking
for new places to hide the Prime Factorizer. Can you figure out what
messages were sent through his computer?
For this challenge, you get 3 files:
- capture (a network capture)
- corefile (a memory dump)
- coremaps (the process’s memory map)
and the shell script which helped generating those files
#/bin/sh
sudo rm /tmp/capture 2>/dev/null
sudo dumpcap -i eth0 -w /tmp/capture &
DUMPCAPPID=$!
sleep 1
OUTPUT="`/usr/bin/env -i /bin/dash -c 'ulimit -c unlimited; curl -k https://curlcore.local.plaidctf.com/flag.html & PID=$!; sleep 5; printf "generate-core-file\ninfo proc mappings\ndetach\n" | sudo gdb attach $PID; wait'`"
sleep 1
sudo kill -INT $DUMPCAPPID
wait
sudo chown `whoami` /tmp/capture
echo "$OUTPUT"
sudo mv "`echo "$OUTPUT" | grep -o 'Saved corefile .*$' | cut -c 16-`" /tmp/corefile
sudo chown `whoami` /tmp/corefile
echo "$OUTPUT" | awk '/Mapped address spaces/,/(gdb)/' | grep -v '(gdb)' > /tmp/coremaps
rm /tmp/curlcore.tgz 2>/dev/null
tar czf /tmp/curlcore.tgz `grep -o ' /.*$' /tmp/coremaps | sort -us | tr '\n' ' '` /tmp/corefile /tmp/coremaps /tmp/capture "$0"
Since we have a network capture of the https download, we need to find a way to decrypt the SSL communication…
Step 1 - Wireshark to the rescue!
The first step is to open the capture under wireshark and copy the session ID from the server Hello message.
19ab5edc02f097d5074890e44b483a49b083b043682993f046a55f265f11b5f4
Step 2 - Finding the SSL master key
With this session ID at hand, we can search for it in the memory dump (corefile) using any hexeditor
0004fbe0 30 00 00 00 19 1e 50 42 e6 b3 13 71 aa 65 25 8e |0.....PB...q.e%.|
0004fbf0 13 b2 dc 71 4d 98 4d f8 d6 8f ad 67 8f f0 a2 fc |...qM.M....g....|
0004fc00 49 47 6d 65 c3 a1 61 f7 18 57 2c 3f 5d b8 56 6a |IGme..a..W,?].Vj|
0004fc10 0d e8 9e 58 20 00 00 00 19 ab 5e dc 02 f0 97 d5 |...X .....^.....|
0004fc20 07 48 90 e4 4b 48 3a 49 b0 83 b0 43 68 29 93 f0 |.H..KH:I...Ch)..|
0004fc30 46 a5 5f 26 5f 11 b5 f4 00 00 00 00 00 00 00 00 |F._&_...........|
Not boring you with too much details, what we have just found is the ssl_session_st struct from ssl.h
struct ssl_session_st
{
// [...]
int master_key_length;
unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
unsigned int session_id_length;
unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
// [...]
};
At 0x0004fc14 you can see the session ID length, at 0x0004fc18 the session ID and of course the SSL master key at 0x0004fbe4.
The master key is therefore:
191E5042E6B31371AA65258E13B2DC714D984DF8D68FAD678FF0A2FC49476D65C3A161F718572C3F5DB8566A0DE89E58
Armed with both the session ID and the master key we can now create a file ‘key.txt’:
RSA Session-ID:19ab5edc02f097d5074890e44b483a49b083b043682993f046a55f265f11b5f4 Master-Key:191E5042E6B31371AA65258E13B2DC714D984DF8D68FAD678FF0A2FC49476D65C3A161F718572C3F5DB8566A0DE89E58
load this file in wireshark with Edit->Preferences->Protocols->SSL:‘(Pre)-Master-Secret log filename’ and apply.
Step 3 - Profit!
Right-click on any of the https messages and select ‘Follow SSL Stream’
Your flag is: congratz_you_beat_openssl_as_a_whitebox
The fastest 250 points you could get ;-)