aboutsummaryrefslogtreecommitdiff
path: root/flags/rsa.py
blob: 96fc947a423a9f98e36fa9d97a91d72883de8cb1 (plain)
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
#!/usr/bin/env python

# Load up the goods.
with open('rsa.flag', 'r') as f:
	flag = f.read(32)

from Crypto.PublicKey import RSA
from Crypto.Hash import MD5
from Crypto import Random
from SocketServer import TCPServer, StreamRequestHandler
import pickle

# Load up our keystore.
# This should be a dict of names (strings) to RSA keys.
with open('/flags/rsa.keys', 'r') as f:
	keys = pickle.load(f)

def keyid(key):
	return MD5.new(key.publickey().exportKey('DER')).digest()

def getkey(by_id):
	for key in keys.values():
		if keyid(key) == by_id:
			return key

def digest(msg):
	buf = MD5.new(msg.keyid + ':' + msg.request).digest()
	print "Message digest is {0}".format(buf.encode('hex'))
	return buf

def sign(msg):
	rng = Random.new().read
	return getkey(msg.keyid).sign(digest(msg), rng)

def verify(msg):
	return getkey(msg.keyid).verify(digest(msg), msg.signature)

class Request:
	pass

class Handler(StreamRequestHandler):
	def start(self):
		# Ask Bob for his flag, this should be fun.
		msg = Request()
		msg.name = 'Alice'
		msg.request = 'get_flag'
		msg.keyid = keyid(keys[msg.name])
		msg.signature = sign(msg)
		pickle.dump(msg, self.wfile)
	
	def get_flag(self, request):
		# Make sure it's from someone we trust
		if(request.name not in keys.keys()
				or request.keyid not in
				[keyid(key) for key in keys.values()]
				or request.name == 'Alice'):
			print "We don't trust this person"
			return
		# Verify the signature
		if(not verify(request)):
			print "This message was altered"
			return
		# Send the goods.
		pickle.dump(flag, self.wfile)

	def handle(self):
		request = pickle.load(self.rfile)
		print "we got: {0}".format(request)
		if(request.request == 'start'):
			self.start()
		if(request.request == 'get_flag'):
			self.get_flag(request)

for port in range(6666, 6999):
	try:
		server = TCPServer(('localhost', port), Handler)
		print 'server running at port {0}'.format(port)
		break
	except:
		continue
server.serve_forever()