master
1#!/usr/bin/env python
2
3import hashlib
4import os.path
5import sys
6
7# From this package
8import lib.error as error
9import lib.http_client as http_client
10import lib.test_framework as test_framework
11import lib.util as util
12import runner
13
14# Deprecated in 2.7 in favor of argparse but not yet removed.
15from optparse import OptionParser
16
17class Harness(test_framework.AbstractHarness):
18 LEVEL = 0
19 VERSION = 1
20 DEFAULT_TEST_CASES = [
21 "level0-R5ez7L9mIu",
22 "level0-HhC91MrU7B",
23 "level0-znKqYRKUDB",
24 "level0-ws8xCiPURG",
25 "level0-JjIHof09MH"
26 ]
27 DICTIONARY_SHA1 = '6b898d7c48630be05b72b3ae07c5be6617f90d8e'
28
29 def __init__(self, ids_or_urls=[], options={}):
30 self.dictionary_path = options.get("dictionary_path")
31 super(Harness, self).__init__(ids_or_urls, options)
32
33 def hook_preexecute(self):
34 self.configure_dictionary()
35
36 def hook_create_runner(self):
37 return runner.Runner({'dictionary_path': self.dictionary_path})
38
39 def sha1(self, input):
40 if sys.version_info >= (3,0) and not isinstance(input, bytes):
41 input = input.encode('utf-8')
42 return hashlib.sha1(input).hexdigest()
43
44 def configure_dictionary(self):
45 if self.dictionary_path:
46 return
47
48 default_dictionary_path = '/usr/share/dict/words'
49
50 try:
51 f = open(default_dictionary_path, "rb")
52 except IOError:
53 dictionary_sha1 = None
54 else:
55 dictionary_sha1 = self.sha1(f.read())
56 f.close()
57
58 if dictionary_sha1 == self.DICTIONARY_SHA1:
59 self.dictionary_path = default_dictionary_path
60 else:
61 self.dictionary_path = os.path.join(os.path.dirname(__file__), "data", "words-" + self.DICTIONARY_SHA1)
62 self.download_dictionary(self.dictionary_path)
63
64 def download_dictionary(self, dictionary_path):
65 if os.path.isfile(dictionary_path):
66 util.logger.debug('Not downloading dictionary to already-existing path: %s', dictionary_path)
67 return
68
69 url = "https://s3-us-west-2.amazonaws.com/stripe-ctf-3/level0-statics/words-%s" % self.DICTIONARY_SHA1
70 util.logger.info("Downloading dictionary. (This will happen once. It's 2.4M, so it may take a while...). URL: %s", url)
71 content = self.fetch_s3_resource(url)
72 if self.sha1(content) != self.DICTIONARY_SHA1:
73 raise error.StripeError("We tried to download the dictionary, but we got content with an unexpected hash. If this persists, please contact ctf@stripe.com")
74 f = open(dictionary_path, "w")
75 f.write(content)
76 f.close()
77
78def main():
79 default_options = {"task": "execute", "raw": False, "dictionary_path": None}
80 usage = "usage: %prog [options] [test case URL or id]"
81 parser = OptionParser(usage=usage)
82 parser.add_option("-r", "--raw", action="store_true", dest="raw", help="Print the raw output of your solution.")
83 parser.add_option("-p", "--dictionary-path", action="store", type="string", dest="dictionary_path")
84 (options, args) = parser.parse_args()
85 options_dict = vars(options)
86
87 for key in default_options:
88 options_dict.setdefault(key, default_options[key])
89
90 harness = Harness(args, options_dict)
91 harness.run()
92
93if __name__ == "__main__":
94 main()