EASYCTF - Zippity

description: I heard you liked zip codes! Connect via nc c1.easyctf.com 12483 to prove your zip code knowledge.

category: Miscellaneous

When we start the connection with the server (nc c1.easyctf.com 12483), it displays this message:

Welcome to Zippy! We love US zip codes, so we’ll be asking you some simple facts about them, based on the 2010 Census. Only the brightest zip-code fanatics among you will be able to succeed! You’ll have 30 seconds to answer 50 questions correctly

First thing to do: determine how many type of questions the program can ask. So after repeating the connection several times, I figured out every type of questions:

Now let’s try to get the database from 2010 Census because the program expects to receive those values. Somehow I ended up on this page: http://proximityone.com/cen2010_zcta_dp.htm. It contains all the data we need. After looking at the javascript of the page, I ran a JS command on the website to list the needed infos:

for(i = 0 ; i < 33120 ; i++){
	console.log(obj.getCellValue(0, i) + "/" + obj.getCellValue(1, i) + "/" + obj.getCellValue(2, i) + "/" + obj.getCellValue(7, i) + "/" + obj.getCellValue(8, i))
}

It will generate output like this :

#zipcode/LandArea/WaterArea/Latitude/Longitude 00601/166659789/799296/18.180556/-66.749961 00602/79288158/4446273/18.362268/-67.17613 …

Now we put this output on a file (zipcode.txt) and we will make the connection with the server using python and socket. To parse the question we will use regex:

import socket
import re

# Will send the response
def sendResponse(arg):
	zipcode = re.findall(regex, tmp)
	for i in content:
		test = i.split('/')
		if test[0] == zipcode[0]:
			response = test[arg].rstrip()
			break
	print response
	s.send(response + '\n')

regex = r"zip code (.*)\?"
response = ""
HOST = 'c1.easyctf.com'
PORT = 12483

# Lets load the file data before starting the connection
with open("zipcode.txt", "r") as f:
	content = f.readlines()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

tmp = "Starting . . ."

# Main loop, will we get an answer, we keep parsing it
while tmp:
	tmp = s.recv(1024)
	print tmp
	if "land area" in tmp:
		sendResponse(1)

	if "water area" in tmp:
		sendResponse(2)

	if "latitude" in tmp:
		sendResponse(3)

	if "longitude" in tmp:
		sendResponse(4)

We have the flag ! easyctf{hope_you_liked_parsing_tsvs!}