codezen.fr code hacking, zen coding

30Apr/12Off

PlaidCTF 2012 – Potpourri 100 – The Game Writeup

Posted by aXs

Robots enjoy some strange games and we just can't quite figure this one out. Maybe you will have better luck than us.
23.22.16.34:6969

We have a game running on that port:

You have gotten 0 of 75
Choice 1 = 98d00c65d341be04600f915b32c01c81ab
Choice 2 = 7a859a01731c050797ac952d82b895882a
Which one is bigger? (1 or 2)
1
1
Correct!
--------------------
You have gotten 1 of 75
Choice 1 = d6e4fbe0e4cd99e8fac2b40fbaa80ea8b0
Choice 2 = 9535d4c5a1a007f302c3f2cc6d1733989f
Which one is bigger? (1 or 2)
1
1
Wrong 🙁

As you can see, "bigger" is not related to the number expressed in hexadecimal has being really greater than the other. We tried many different things to try to find a relation (modulo, adding the digits, ...) ... until I starred for a few minutes at our script that was playing the game in a loop and noticed the hashes were coming back.. it wasn't random numbers!

My first approach was to "learn" all the possible round. If a similar round comes back, we know the answer. I noticed that if we know only one of the number, if this number has won before, there is a slightly (slightly!) chance that it will won this match again. This approach kinds of worked but was very slow.. after 6 hours of learning, we weren't going higher than ~30-40 winning round in a row.

The next approach was to consider this challenge as a bubble sort: we will maintain an ordered list of the numbers and swap them around depend of which is considered bigger, basically using the service as an oracle.

This version worked much better and can solve The Game in around ~30 minutes.

I'm still learning Python so this isn't anything Im proud of on the point of view of the Python style of whatever 🙂

#!/usr/bin/env python
# -*- coding: latin-1 -*-

import socket
import sys
import re

if len(sys.argv) != 3:
  print '\nUsage:\t./bigger.py [host] [port]'
  sys.exit(1)

host = sys.argv[1]
port = int(sys.argv[2])

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

fs=s.makefile()

regex = re.compile(".*= (.*)")

matchs = {}
winner = []
numbers = []

while 1:
  welcome = fs.readline()
  print welcome

  if welcome == 'Ya