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
|
import ssl
import socket
import json
import argparse
def enumerate_tls_ciphers(protocol_options, host, port, cert, cafile):
root_context = ssl.SSLContext(ssl.PROTOCOL_TLS)
root_context.options |= protocol_options
root_context.set_ciphers('ALL:COMPLEMENTOFALL:-PSK:-SRP')
ciphers = set([cipher['name'] for cipher in root_context.get_ciphers()])
accepted_ciphers = []
for cipher_name in ciphers:
context = ssl.SSLContext(root_context.protocol)
context.set_ciphers(cipher_name)
context.options = root_context.options
context.load_verify_locations(cafile=cafile)
context.load_cert_chain(certfile=cert)
with socket.socket(socket.AF_INET) as sock:
with context.wrap_socket(sock, server_hostname=host) as conn:
try:
conn.connect((host, port))
except Exception as e:
continue
accepted_ciphers.append(cipher_name)
return sorted(accepted_ciphers)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='MongoDB TLS Cipher Suite Enumerator')
parser.add_argument('--port', type=int, default=27017, help='Port to connect to')
parser.add_argument('-o', '--outfile', type=str, default='ciphers.json', help='file to write the output to')
parser.add_argument('--host', type=str, default='localhost', help='host to connect to')
parser.add_argument('--cafile', type=str, help='Path to CA certificate')
parser.add_argument('--cert', type=str, help='Path to client certificate')
args = parser.parse_args()
exclude_ops = {
ssl.OP_NO_SSLv2,
ssl.OP_NO_SSLv3,
ssl.OP_NO_TLSv1,
ssl.OP_NO_TLSv1_1,
ssl.OP_NO_TLSv1_2,
}
def exclude_except(op):
option = 0
for other_op in exclude_ops - {op}:
option |= other_op
return option
suites = {
'sslv2': exclude_except(ssl.OP_NO_SSLv2),
'sslv3': exclude_except(ssl.OP_NO_SSLv3),
'tls1': exclude_except(ssl.OP_NO_TLSv1),
'tls1_1': exclude_except(ssl.OP_NO_TLSv1_1),
'tls1_2': exclude_except(ssl.OP_NO_TLSv1_2),
}
results = {
key: enumerate_tls_ciphers(protocol_options=proto,
host=args.host,
port=args.port,
cafile=args.cafile,
cert=args.cert)
for key, proto in suites.items()
}
with open(args.outfile, 'w+') as outfile:
json.dump(results, outfile)
|