Posted on by and filed under Tracer FIRE 5 2013.

In a trend of what seems to be gently breaking casually run/newer CTFs, we at Knightsec found the source code for the TracerFire competition.

Fellow student Alex Lynch Googled around for Neale Pickett and/or went to http://dirtbags.net/ and found the git repository for the competition. We found the source code for the WOPR challenge, its tokens, several token files including the HOST challenge tokens hosted by Sandia, and the submission hash scheme for all of the teams.

Having trouble holding all of these tokens, I did the following.

wget http://dirtbags.net/g.cgi/ctf/snapshot/ctf-master.tar.gz
tar xzvf ctf-master.tar.gz
cd ctf-master
find . -name tokens.* -exec cat {} ;  > tokens.txt
# clean up some false positives
nano tokens.txt
# script code below
nano submit_everything.py
chmod u+x submit_everything.py
crontab -e
Then I added one line to my crontab… (time in EST; the competition ended at 11 AM MST) 0 11 * * * ~/ctf/tf5/submit_everything.py …which executed the code in submit_everything.py below, which is a modified brute forcing script that I rarely use.
#! /usr/bin/env python
import time
import urllib2
from urllib import urlencode

GO = True

URL = 'http://project2.dirtbags.net/claim.cgi'
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(),
                              urllib2.HTTPRedirectHandler()
                              )

opener.addheaders = [('User-Agent', 'GentleBrute/im.s0rry')]

def make_gentle(seconds):
    """
    Makes something that runs really hot run colder with sleeps.

    Decorator that returns a decorator!!1!!1
    """
    def wrapper(fn):
        def wrapped(*args, **kwargs):
            x = fn(*args, **kwargs)
            time.sleep(seconds)
            return x
        return wrapped
    return wrapper

@make_gentle(1)
def submit_token(team_hash, token, valid_string=''):
    "Submits a token to the URL. Opah!"

    data = {'t': team_hash, 'k': token}
    try:
        print 'Submitting', token + ':',
        resp = opener.open(URL, urlencode(data))
        print 'good'
    except urllib2.HTTPError as e:
        print e

def main():

    if not GO:
        print 'Not yet!'
        return

    print 'GO!'
    for line in open('all_tokens.txt'):
        token = line.strip()
        submit_token('8eebd63c', token)

if __name__ == '__main__':
    main()


And so we notified Neale Pickett (got his blessing, too!) and claimed the entire host and WOPR categories to ourselves. We did have 14 WOPR points and ~4300 host points beforehand before pulling the trigger, for legitimate point references. Thanks to Mr. Pickett for creating and hosting such this nice CTF and condoning our actions.

Lesson of the day: be careful with what you check into a repository! :P

Credit: Alex Lynch, Mark Ignacio