1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env python3
 
# SY 301 Fall 2016
# Project 2
# YOUR NAME HERE
 
from datetime import datetime
import sys
 
def usage():
    print('This program is to be run with two arguments, and an optional third')
    print('argument.  The first is the filename of your precomputed hash table, such as')
    print('hashedRockyou.txt or shortHashedRockyou.txt.  The second is the file you are')
    print('trying to crack, which was likely created by shadowgen.py, and')
    print('contains usernames and the hashes of passwords.  If you include a third')
    print('argument, it should be the filename of a file that contains common passwords')
    print('and their frequencies, such as rockyouwithcount.txt.')
    print('EXAMPLE:')
    print('python3 brute.py hashRockyou.txt outHashes.txt rockyouwithcount.txt')
    print('OR')
    print('python3 brute.py hashRockyou.txt outHashes.txt')
 
 
'''
THIS IS THE FUNCTION YOU WILL WRITE.
There are three arguments:
    - hashes is a list containing every line of precomputed hashes
    - shadow is a list with every line from the username-hash file
    - counts is a list with a number of times each password appears
      (or an empty list if the program was run with just two arguments).
The code you write in this function needs to use the data in these
lists to compute plaintext username/password pairs. The function should
return a list of strings that each contain a username, then a tab, and
then the corresponding password. If you want to change this to return
something other than a list, that's fine, but you need to change the loop
that prints things out at the end of the __main__ code block too.
Of course, you can create any other classes or helper functions that
you need, as long as everything is clearly commented.
'''
def crack(hashes, shadow, counts):
    answers = []
    # of course you should change this!!!
    answers.append('roche' + '\t' + 'cycling1sCool')
    return answers
 
'''YOU SHOULD NOT HAVE TO CHANGE THIS PART.
It is dealing with getting the filenames, reading them in,
setting up a timer, and calling your code.
'''
if __name__ == '__main__':
    if len(sys.argv) != 3 and len(sys.argv) != 4:
        usage()
        exit(1)
 
    # read in the files
    try:
        with open(sys.argv[1],'r') as f:
            hashes = f.read().splitlines()
 
        with open(sys.argv[2],'r') as f:
            shadow = f.read().splitlines()
 
        if len(sys.argv) == 4:
            with open(sys.argv[3],'r') as f:
                counts = f.read().splitlines()
        else:
            counts = []
    except OSError as e:
        usage()
        print("Error opening files:", e)
        exit(1)
 
    start = datetime.now()
    # this is the line that calls your code
    answers = crack(hashes, shadow, counts)
    stop = datetime.now()
 
    # you might need to change this loop if you change the type
    # of structure returned from the crack() function
    for ans in answers:
        print(ans)
 
    print("Runtime:", stop-start)