Skip to content

Instantly share code, notes, and snippets.

@ctfaddict

ctfaddict/defcon21replay.py Secret

Created Apr 24, 2014
Embed
What would you like to do?
#!/usr/bin/python
import psycopg2
import sys
def bubbleSort(data, begin):
idx = [x for x in range(len(data))]
for j in range(begin, len(data) - 1):
swap = False
for k in range(begin, len(data) - j):
if data[idx[k]] < data[idx[k + 1]]:
t = idx[k]
idx[k] = idx[k + 1]
idx[k + 1] = t
swap = True
if not swap:
break
return idx
class Replay:
def __init__(self):
self.pollPlus = [0 for x in range(21)]
self.pollMinus = [0 for x in range(21)]
self.capturePlus = [0 for x in range(21)]
self.captureMinus = [0 for x in range(21)]
self.teamFlags = [2500 for x in range(21)]
self.legitFlags = 0
self.history = [(0, list(self.teamFlags))]
def runTheGame(self, cur):
cur.execute("select min(id), max(id) from rounds;")
row = cur.fetchone()
minRound = row[0]
maxRound = row[1]
cur.execute("select min(id), max(id) from services;")
row = cur.fetchone()
minService = row[0]
maxService = row[1]
for r in range(minRound, maxRound + 1):
for s in range(minService, maxService + 1):
up = []
down = []
cur.execute("select i.team_id, a.status from availabilities a, instances i where a.round_id = %s and i.service_id = %s and a.instance_id = i.id and i.team_id != 21", (r, s, ))
failPool = 0
while True:
row = cur.fetchone()
if row == None:
break
team = row[0]
status = row[1]
if status != 0:
down.append(team)
flags = min(19, self.teamFlags[team])
self.teamFlags[team] -= flags
self.pollMinus[team] += flags
failPool += flags
else:
up.append(team)
if len(up) > 0:
share = failPool / len(up)
for t in up:
self.teamFlags[t] += share
self.pollPlus[t] += share
self.legitFlags += failPool % len(up)
else:
self.legitFlags += failPool
for s in range(minService, maxService + 1):
pwners = [list() for x in range(21)]
cur.execute("select r.team_id as attacker, i.team_id as victim from redemptions r, tokens t, instances i where t.round_id = %s and i.service_id = %s and r.token_id = t.id and t.instance_id = i.id", (r, s, ))
while True:
row = cur.fetchone()
if row == None:
break
pwners[row[1]].append(row[0])
for v in range(1, 21):
if len(pwners[v]) > 0:
flags = min(19, self.teamFlags[v])
self.teamFlags[v] -= flags
self.captureMinus[v] += flags
share = flags / len(pwners[v])
for a in pwners[v]:
self.teamFlags[a] += share
self.capturePlus[a] += share
self.legitFlags += flags % len(pwners[v])
self.history.append((r, list(self.teamFlags)))
if __name__ == "__main__":
conn = psycopg2.connect("dbname=scorebot_production user=postgres")
cur = conn.cursor()
teams = {}
cur.execute("select id, name from teams;")
rows = cur.fetchall()
maxNameLen = 0
for r in rows:
teams[r[0]] = r[1]
maxNameLen = max(maxNameLen, len(r[1]))
pad = " " * maxNameLen
replay = Replay()
replay.runTheGame(cur)
print "LegitBS remainder flags: %d\n" % replay.legitFlags
idx = bubbleSort(replay.teamFlags, 1)
print "Estimated final scores"
for i in range(1, 21):
print " %s | %d" % ((teams[idx[i]] + pad)[:maxNameLen], replay.teamFlags[idx[i]])
idx = bubbleSort(replay.capturePlus, 1)
print "\nFlags gained per team from captures"
for i in range(1, 21):
print " %s | %d" % ((teams[idx[i]] + pad)[:maxNameLen], replay.capturePlus[idx[i]])
idx = bubbleSort(replay.captureMinus, 1)
print "\nFlags lost per team from captures"
for i in range(1, 21):
print " %s | %d" % ((teams[idx[i]] + pad)[:maxNameLen], replay.captureMinus[idx[i]])
idx = bubbleSort(replay.pollPlus, 1)
print "\nFlags gained per team from polls"
for i in range(1, 21):
print " %s | %d" % ((teams[idx[i]] + pad)[:maxNameLen], replay.pollPlus[idx[i]])
idx = bubbleSort(replay.pollMinus, 1)
print "\nFlags lost per team from polls"
for i in range(1, 21):
print " %s | %d" % ((teams[idx[i]] + pad)[:maxNameLen], replay.pollMinus[idx[i]])
if len(sys.argv) == 2:
f = open(sys.argv[1], "w")
for h in replay.history:
scores = h[1]
# f.write("%d:" % h[0])
for i in range(1, 21):
f.write("%d%s" % (scores[i], "," if i != 20 else ""))
f.write('\n')
f.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment