Tags: python 

Rating:

# 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:

* "What is the land area (m^2) of the zip code " + zipcode + "?"
* "What is the water area (m^2) of the zip code " + zipcode + "?"
* "What is the latitude (degrees) of the zip code " + zipcode + "?"
* "What is the longitude (degrees) of the zip code " + zipcode + "?"

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!}`

Original writeup (https://ctfshellclub.github.io/2018/02/21/easyctf-Zippity/).