Rating:

# Plaid CTF 2014: curlcore

**Category:** Forensics
**Points:** 250
**Description:**

> We managed to grab a [memory dump](curlcore-b9b2bc016a796db9db66be6365d48a6b.tar.bz2) 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?

## Write-up

Unzip [the provided tarball](curlcore-b9b2bc016a796db9db66be6365d48a6b.tar.bz2). This results in the following file/directory structure:

```bash
$ tree
.
├── curlcore.sh
├── lib
│   └── x86_64-linux-gnu
│   ├── ld-2.17.so
│   ├── libc-2.17.so
│   ├── libcom_err.so.2.1
│   ├── libcrypt-2.17.so
│   ├── libcrypto.so.1.0.0
│   ├── libdl-2.17.so
│   ├── libgcrypt.so.11.7.0
│   ├── libgpg-error.so.0.10.0
│   ├── libkeyutils.so.1.4
│   ├── libnsl-2.17.so
│   ├── libnss_compat-2.17.so
│   ├── libnss_files-2.17.so
│   ├── libnss_nis-2.17.so
│   ├── libpthread-2.17.so
│   ├── libresolv-2.17.so
│   ├── libssl.so.1.0.0
│   └── libz.so.1.2.8
├── tmp
│   ├── capture
│   ├── corefile
│   └── coremaps
└── usr
├── bin
│   └── curl
└── lib
└── x86_64-linux-gnu
├── libasn1.so.8.0.0
├── libcurl.so.4.3.0
├── libgnutls.so.26.22.6
├── libgssapi.so.3.0.0
├── libgssapi_krb5.so.2.2
├── libhcrypto.so.4.1.0
├── libheimbase.so.1.0.0
├── libheimntlm.so.0.1.0
├── libhx509.so.5.0.0
├── libidn.so.11.6.11
├── libk5crypto.so.3.1
├── libkrb5.so.26.0.0
├── libkrb5.so.3.3
├── libkrb5support.so.0.1
├── liblber-2.4.so.2.8.3
├── libldap_r-2.4.so.2.8.3
├── libp11-kit.so.0.0.0
├── libroken.so.18.1.0
├── librtmp.so.0
├── libsasl2.so.2.0.25
├── libsqlite3.so.0.8.6
├── libtasn1.so.3.2.0
└── libwind.so.0.0.0

7 directories, 45 files
```

`curlcore.sh` is a shell script that was used to create the tarball. It contains this piece of code:

```bash
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
```

Apparently, `https://curlcore.local.plaidctf.com/flag.html` was requested while the dump was created. The flag we’re looking for is probably part of the response.

Open `tmp/capture` in Wireshark. It shows that `https://curlcore.local.plaidctf.com/flag.html` was indeed requested, but since it was downloaded over HTTPS the plain text response isn’t available as part of the capture. We _do_ know that `TLS_RSA_WITH_AES_256_CBC_SHA` is used, i.e. the data is encrypted with AES-256 and the key is exchanged using basic RSA encryption. Wireshark also displays the RSA session ID, `19AB5EDC02F097D5074890E44B483A49B083B043682993F046A55F265F11B5F4`:

![](wireshark-capture.png)

Now that we have the session ID, [we could decrypt the entire session if we also had the SSL master secret](http://www.cloudshield.com/blog/advanced-malware/how-to-decrypt-openssl-sessions-using-wireshark-and-ssl-session-identifiers/):

![Wireshark → Edit → Preferences → Protocols → SSL](wireshark-ssl-master-secret-log-format.png)

But where could we find this SSL master key? `curl` depends on OpenSSL for TLS support… So [let’s see how OpenSSL stores the SSL master key in memory](https://github.com/openssl/openssl/blob/300b9f0b704048f60776881f1d378c74d9c32fbd/ssl/ssl.h#L586-L590).

```h
struct ssl_session_st
{
// […]
int master_key_length;
unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
/* session_id - valid? */
unsigned int session_id_length;
unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
// […]
}
```

Turns out the SSL master key is close to the session ID, in the same struct.

Let’s see if the session ID occurs in any of the other files:

```bash
$ grep '\x19\xAB\x5E\xDC\x02\xF0\x97\xD5\x07\x48\x90\xE4\x4B\x48\x3A\x49\xB0\x83\xB0\x43\x68\x29\x93\xF0\x46\xA5\x5F\x26\x5F\x11\xB5\xF4' -r .
Binary file ./tmp/capture matches
Binary file ./tmp/corefile matches
```

A-ha, `tmp/corefile` also contains the session ID. Let’s look near the session ID in this file, for anything that might be the SSL master key for the connection.

```bash
$ hexdump -C tmp/corefile | grep --before=5 --after=3 '19 ab 5e dc'
0004fbc0 20 20 00 00 00 00 00 00 70 01 00 00 00 00 00 00 | ......p.......|
0004fbd0 01 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
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._&_...........|
0004fc40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
```

And indeed: right before the session ID, starting with `19 1e 50 42` and ending with `0d e8 9e 58` there is something that might be a valid master key (consisting of exactly `96` hexadecimal digits).

Let’s write the session ID and this master key to [a file in the format described by Wireshark](session-master-secret.log):

```
RSA Session-ID:19AB5EDC02F097D5074890E44B483A49B083B043682993F046A55F265F11B5F4 Master-Key:191E5042E6B31371AA65258E13B2DC714D984DF8D68FAD678FF0A2FC49476D65C3A161F718572C3F5DB8566A0DE89E58
```

Go to Wireshark → Edit → Preferences → Protocols → SSL and select the `session-master-secret.log` file in the (Pre-)Master-Secret log filename input field.

After that, you can right-click on any TLS/SSL packet and select ‘Follow SSL Stream’ to view the decoded payload.

![](wireshark-flag.png)

The flag is `congratz_you_beat_openssl_as_a_whitebox`.

## Other write-ups and resources

* <https://cesena.ing2.unibo.it/2014/04/14/plaidctf-2014-curlcore-forensic-250/>
* <https://fail0verflow.com/blog/2014/plaidctf2014-for250-curlcore.html>
* <https://docs.google.com/a/google.com/file/d/0B1Q3-q0eaImNSlNJbTNKVzNtV3c/edit>
* [Source code for this challenge, released after the CTF](https://github.com/pwning/plaidctf2014/tree/master/forensics/curlcore)
* [Indonese](http://blog.rentjong.net/2014/04/plaidctf2014-write-up-curlcore.html)
* <http://j00ru.vexillium.org/dump/ctf/curlcore.zip>

Original writeup (https://github.com/ctfs/write-ups/tree/master/plaid-ctf-2014/curlcore).