CSAW CTF - Reversing 500

Monday, October 01, 2012 » airmack, csaw, ctf, luks, robbje, spq

Reversing 500 challenge of CSAW CTF

Description

We got two files, 8086100f.mrom and 8086100f.mrom.tmp.
The first 8086100f.mrom looked like a pxe boot image but i did not work much with the file.
The second file - 8086100f.mrom.tmp - was an elf file which is most probably the base for the first file, some of the sections are packed in there i think.
Anyway, i only worked with the 8086100f.mrom.tmp file after some search i found an interesting string:

1
2
3
4
5
6
7
8
iPXE script:
#!ipxe
:retry
dhcp || goto retry
prompt --key 0x03 --timeout 5000 (Quick, Quick!) Press CTRL+C for GDB UDP stub && gdbstub udp net0 ||
kernel https://secure-doomsday-client-loader.c0.cx/boot/vmlinuz
initrd https://secure-doomsday-client-loader.c0.cx/boot/initrd.gz?include_flag=0
boot

the url https://secure-doomsday-client-loader.c0.cx/boot/initrd.gz?include_flag=0 looked interesting, but the server reqested a client certificate.
nice that there was something that looked like a part of a certificate: the string "OpenSSL Generated Certificate" which came some bytes after the above string.
So we want that certificate and the corresponding pkey. Fortunately the elf file contained debug informations and i was able to find the offset and length of these two:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ objdump -x 8086100f.mrom.tmp
[...]
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
[...]
  5 .textdata     0001dc2c  00000000  000014a0  000014d4  2**2
                  CONTENTS, ALLOC, LOAD, CODE
[...]
SYMBOL TABLE:
[...]
000193fd l       .textdata      0000038b .hidden client_certificate_data
0000038b l       *ABS*  00000000 .hidden client_certificate_len
00019788 l       .textdata      000004a7 .hidden client_private_key_data
000004a7 l       *ABS*  00000000 .hidden client_private_key_len
[...]

So the cert should be at 0x193fd in the section .textdata(which begins at 0x14d4 in the file) and has a length of 0x38b.
The key should be at 0x19788 in the same section and has a length of 0x4a7.
Let's see what we get:

1
2
3
4
5
$dd if=8086100f.mrom.tmp bs=1 skip=$((0x193fd + 0x14d4)) count=$((0x38b)) of=8086100f.mrom.tmp.cert
$dd if=8086100f.mrom.tmp bs=1 skip=$((0x19788 + 0x14d4)) count=$((0x4a7)) of=8086100f.mrom.tmp.key
$file 8086100f.mrom.tmp.cert 8086100f.mrom.tmp.key
8086100f.mrom.tmp.cert: data
8086100f.mrom.tmp.key:  data

hmm, looks bad... but after some reading of makefiles and sourcecode of the iPXE project, i found out that they are DER formatted files.

lets see what openssl says about the files:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ openssl x509 -in 8086100f.mrom.tmp.cert -inform DER -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 4096 (0x1000)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=YO, ST=LO, L=None, O=None, OU=None
        Validity
            Not Before: Sep  5 22:35:59 2012 GMT
            Not After : Dec  4 22:35:59 2012 GMT
        Subject: C=YO, ST=LO, O=None, OU=None, CN=client
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
[...]
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
[...]
$ openssl rsa -in 8086100f.mrom.tmp.key -inform DER -text -noout
Private-Key: (2048 bit)
modulus:
[...]

this looks good, so we have our cert and key, lets bring them to pem format for curl:

1
2
$ openssl x509 -in 8086100f.mrom.tmp.cert -inform DER -out 8086100f.mrom.tmp.cert.pem
$ openssl rsa -in 8086100f.mrom.tmp.key -inform DER -out 8086100f.mrom.tmp.key.pem

fine, now we were able to download the file, i downloaded it a second time, now with include_flag=1 just to see what happens:

1
2
3
4
5
$ curl --insecure --cert 8086100f.mrom.tmp.cert.pem --key 8086100f.mrom.tmp.key.pem 'https://secure-doomsday-client-loader.c0.cx/boot/initrd.gz?include_flag=0' -o initrd_flag0.gz
$ curl --insecure --cert 8086100f.mrom.tmp.cert.pem --key 8086100f.mrom.tmp.key.pem 'https://secure-doomsday-client-loader.c0.cx/boot/initrd.gz?include_flag=1' -o initrd_flag1.gz
$ ls -l initrd_flag?.gz
-rw-r--r--+ 1 Kris None 6698028 Sep 30 23:34 initrd_flag0.gz
-rw-r--r--+ 1 Kris None 6701791 Sep 30 23:35 initrd_flag1.gz

indeed! the files differ, initrd_flag1.gz is bigger, lets see what is inside

1
2
3
$ gzip -d initrd_flag1.gz > initrd_flag1
$ file initrd_flag1
initrd_flag1: ASCII cpio archive (SVR4 with no CRC)

ah, as thought - a cpio initrd file...

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ mkdir initrd_flag1.unpack
$ cd initrd_flag1.unpack
$ cpio -i < ../initrd_flag1
33269 blocks
$ ls -l
total 24
drwxr-xr-x  2 501 dialout 4096 Sep 30 22:19 bin
drwxr-xr-x  2 501 dialout    6 Sep 30 22:19 dev
drwxr-xr-x 11 501 dialout 4096 Sep 30 22:19 etc
-rw-r--r--  1 501 dialout   33 Sep 30 22:19 flag.txt
-rwxr-xr-x  1 501 dialout  426 Sep 30 22:19 init
drwxr-xr-x 11 501 dialout 4096 Sep 30 22:19 lib
drwxr-xr-x  2 501 dialout    6 Sep 30 22:19 media
drwxr-xr-x  2 501 dialout    6 Sep 30 22:19 mnt
drwxr-xr-x  2 501 dialout    6 Sep 30 22:19 proc
drwxr-xr-x  2 501 dialout 4096 Sep 30 22:19 sbin
drwxr-xr-x  2 501 dialout    6 Sep 30 22:19 sys
drwxr-xr-x  2 501 dialout    6 Sep 30 22:19 tmp
drwxr-xr-x  6 501 dialout   49 Sep 30 22:19 usr
drwxr-xr-x  6 501 dialout   48 Sep 30 22:19 var
$ cat flag.txt
ebef709401cd0ce3665f541c00c0d512

voila! we have the flag.