Skip to content

Instantly share code, notes, and snippets.

@wanqizhu
Created November 13, 2015 17:46
Show Gist options
  • Save wanqizhu/86e11ec012489c53c212 to your computer and use it in GitHub Desktop.
Save wanqizhu/86e11ec012489c53c212 to your computer and use it in GitHub Desktop.

Faster Math

If you connect to programming.easyctf.com:10300 enough times, you'll see the 4 types of problems:

  1. Fill in missing operations, which we can just brute force since there are only 27 possiblities;
  2. Find # of ways to get a certain value from a subset of the coins, which can be solved efficiently with Dynamic Programming
  3. Find distance traveled after being projected from a desk, a simple physics question
  4. Find greatest/least root, solve using quadratic formula

So it suffices to detect which type the problem is, gather useful information, and solve them. None of them require much time. You can connect to the server and do 100 problems using socket in Python.

Running the code, you get the flag is easyctf{A+_for_A+_eff0rt!}

import socket, math
TCP_IP = '104.131.228.101'
TCP_PORT = 10300
BUFFER_SIZE = 1024
MESSAGE = "1"
COINS = [1, 5, 10, 25, 100, 500, 1000]
AVALIABLE = [0] * 7
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #socket connection to server
s.connect((TCP_IP, TCP_PORT))
data = s.recv(BUFFER_SIZE) #irrelevant header
data = s.recv(BUFFER_SIZE)
arr = data[173:].split(' ') # gets rid of padding -- not necessary, just to speed things up
for cnt in range(101):
print '\nSTART\n\n', data
if 'projected' in arr:
# case 1
# basic physics problem
v = int(arr[arr.index('m/s.')-1])
h = int(arr[arr.index('m')-1])
MESSAGE = str(int(v * math.sqrt(2*h/10)))
elif 'checkout' in arr:
# case 2
AVALIABLE = [0] * 7
i = arr.index('purchase,')-1
cost = int(float(arr[i][1:])*100)
print 'cost: ', cost, '\n'
i = data.index('using just')
data = data[i+10:]
if "pennies" in data:
AVALIABLE[0] = 1
if "nickels" in data:
AVALIABLE[1] = 1
if "dimes" in data:
AVALIABLE[2] = 1
if "quarters" in data:
AVALIABLE[3] = 1
if " dollar" in data:
AVALIABLE[4] = 1
if "five-" in data:
AVALIABLE[5] = 1
if "ten-" in data:
AVALIABLE[6] = 1
# Dynamic Programming
DP = [0]*(cost+1)
DP2 = [0]*(cost+1)
DP[0] = 1
for i in range(7):
if AVALIABLE[i] and COINS[i] <= cost:
for j in range(cost+1):
DP2[j] = DP[j]
k = j
while (j>=COINS[i]):
j -= COINS[i]
DP2[k] += DP[j]
for j in range(cost+1):
DP[j] = DP2[j]
#print DP
MESSAGE = str(DP[cost])
elif 'operations' in arr:
# case 3
# Brute force
a1 = int(arr[-9][3:])
a2 = int(arr[-7][:-1])
a3 = int(arr[-5][:-1])
a4 = int(arr[-3][:-1])
a5 = int(arr[-1][:-1])
op = ['+', '-', '*']
op1 = ['+', '-', 'x']
for i in range(27):
k = i%3
j = (i/3)%3
i = (i/9)%3
# eval is super insecure lol, should probably hardcode instead of using eval
if (eval('(((a1' + op[i] + 'a2)' + op[j] +'a3)' + op[k] + 'a4)==a5')):
MESSAGE = op1[i] + op1[j] + op1[k]
break
else: #'Find the value' in data
# case 4
# quadratic equation
a = int(arr[-5][:-3])
b = int(arr[-3][:-1])
c = int(arr[-1][:-1])
if arr[-4] == '-':
b = -b
if arr[-2] == '-':
c = -c
determinant = math.sqrt(b*b-4*a*c)
if 'greater' in arr:
MESSAGE = str(int((-b + determinant)/2/a))
else:
MESSAGE = str(int((-b - determinant)/2/a))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
print data, '\nmsg: ', MESSAGE
data = s.recv(BUFFER_SIZE)
arr = data.split(' ')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment