DEFCON2K12 Prequals: gb300 writeup
For this challenge, we had an IP, a port and a password. Like most of the other exercices, it was first waiting for the password and then sent us some stuff. Format of the datas was as follow:
DD GOTP ATM sckimmer v0.0000001
Sun Jun -9 20:58:58
4 2 3 1 2 3
1 8 9 9 6 0
7 6 0 7 8 4
0 2 8 0 9 2
7 3 6 8 6 3
1 9 4 4 1 7
User entered: 1 4 8 3
The matrix thing was displayed 4 times with only 3 user inputs (linked to the 3 first matrices). We were asked to enter the right input for the last matrix.
While observing what was sent and trying to answer, one of us noticed that by stacking the matrices and the user inputs, we were generating lists of 4 and 3 values respectively. The user inputs lists could be matched with 4 of the matrices lists. The answer could then be obtained from the last value of the four matched lists. Sadly there was a timeout and it was really difficult to find the right answer in time by sight, so we decided to write a python script.
#! /usr/bin/env python2
import re
import sys
import socket
sckt = socket.create_connection(('140.197.217.85', 10435))
def discard(message):
print sckt.recv(len(message) + 1)
COLOR = {'c': '\x1b\[\d+;\d+;\d+m'}
LINE = re.compile(
'^%(c)s (\d) %(c)s (\d) %(c)s (\d) %(c)s (\d) %(c)s (\d) %(c)s (\d) %(c)s$' % COLOR
)
UINPUT = re.compile('^%(c)sUser entered: (\d) (\d) (\d) (\d) $' % COLOR)
def get_matrix(matrix):
for nb_line in xrange(6):
line = sckt.recv(89)
if len(line) < 89:
line += sckt.recv(89 - len(line))
print line
match = LINE.match(line)
if match is None:
sys.exit('Failed to parse number line.')
else:
for column in xrange(6):
matrix[nb_line * 6 + column].append(int(match.group(1 + column)))
def get_user_input(user_input):
line = sckt.recv(32)
print line
match = UINPUT.match(line)
if match is not None:
for x in xrange(4):
user_input[x].append(int(match.group(1 + x)))
sckt.send('5fd78efc6620f6\n')
discard('\x1b[0;37;40m')
discard('DD GOTP ATM skimmer v0.0000001')
for _ in xrange(5): # [1]
matrix = [[] for _ in xrange(36)]
user_input = [[] for _ in xrange(4)]
for x in xrange(4):
if x != 3:
discard('Sun Jun-10 20:58:58 2012')
discard(' ')
get_matrix(matrix)
get_user_input(user_input)
print matrix
print user_input
if x != 3: discard(' ')
else:
res = [0] * 4
for it in xrange(4):
inpt = user_input[it]
for lst in matrix:
if lst[:-1] == inpt:
res[it] = lst[-1]
break
result = '%d %d %d %d\n' % (res[0], res[1], res[2], res[3])
print result,
sckt.send(result)
After some loops it finally gave something that looked like a menu of a cash
machine, the balance of the account, and closed the connection. The balance was
the flag: 9238740982570237012935.32
.
[1] for
here is due to some tests we did to find how many times was necessary
to win, but we didn’t find it and since we already had the key we moved on
after 5 minutes.