-
Notifications
You must be signed in to change notification settings - Fork 0
/
web_server.py
61 lines (54 loc) · 1.79 KB
/
web_server.py
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
import SimpleHTTPServer
import BaseHTTPServer
import re
import os
import binascii
import time
from hashes import *
hmac_key = os.urandom(16)
print binascii.hexlify(hmac_sha1(hmac_key, 'some_malicious_payload'))
class Hackable(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
match = re.match(r'\/test\?file=(.*)\&signature=(.*)$', self.path)
code=200
if match is None:
code=400
message = 'Unknown Parameters'
else:
groups = match.groups()
file = groups[0]
sig = groups[1]
if self.check_hmac_with_timing_leak(file, sig):
code=200
message = 'Valid File'
else:
code=500
message='Invalid File'
self.send_response(code)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(message)
return
def check_hmac_with_timing_leak(self, file, sig):
hmac_calc = hmac_sha1(hmac_key, file)
bin_sig = binascii.unhexlify(sig)
if len(hmac_calc) != len(bin_sig):
return False
for user_sig_byte, server_sig_byte in zip(bin_sig, hmac_calc):
if user_sig_byte != server_sig_byte:
return False
time.sleep(0.0005)
return True
def run_while_true(server_class=BaseHTTPServer.HTTPServer,
handler_class=Hackable):
"""
This assumes that keep_running() is a function of no arguments which
is tested initially and after each request. If its return value
is true, the server continues.
"""
server_address = ('', 8000)
httpd = server_class(server_address, handler_class)
while True:
httpd.handle_request()
run_while_true()
s = Hackable()