-
Notifications
You must be signed in to change notification settings - Fork 111
/
test-cve-2016-2107.py
106 lines (90 loc) · 4.05 KB
/
test-cve-2016-2107.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# Author: Hubert Kario, (c) 2016
# Released under Gnu GPL v2.0, see LICENSE file for details
"""Check for CVE-2016-2107"""
from __future__ import print_function
import traceback
import sys
from tlsfuzzer.runner import Runner
from tlsfuzzer.messages import Connect, ClientHelloGenerator, \
ClientKeyExchangeGenerator, ChangeCipherSpecGenerator, \
FinishedGenerator, ApplicationDataGenerator, AlertGenerator, \
fuzz_plaintext
from tlsfuzzer.expect import ExpectServerHello, ExpectCertificate, \
ExpectServerHelloDone, ExpectChangeCipherSpec, ExpectFinished, \
ExpectAlert, ExpectClose, ExpectApplicationData
from tlslite.constants import CipherSuite, AlertLevel, AlertDescription, \
ExtensionType
def main():
conversations = {}
conversation = Connect("localhost", 4433)
node = conversation
# any CBC will do, but the rest of code expects a 128 block cipher
ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA]
node = node.add_child(ClientHelloGenerator(ciphers,
extensions={ExtensionType.renegotiation_info:None}))
node = node.add_child(ExpectServerHello(extensions={ExtensionType.renegotiation_info:None}))
node = node.add_child(ExpectCertificate())
node = node.add_child(ExpectServerHelloDone())
node = node.add_child(ClientKeyExchangeGenerator())
node = node.add_child(ChangeCipherSpecGenerator())
node = node.add_child(FinishedGenerator())
node = node.add_child(ExpectChangeCipherSpec())
node = node.add_child(ExpectFinished())
node = node.add_child(ApplicationDataGenerator(bytearray(b"GET / HTTP/1.0\n\n")))
node = node.add_child(ExpectApplicationData())
node = node.add_child(AlertGenerator(AlertLevel.warning,
AlertDescription.close_notify))
node = node.add_child(ExpectAlert())
node.next_sibling = ExpectClose()
conversations["sanity check"] = conversation
# CVE-2016-2107 reproducer
# to reproduce the vulnerability we need to send a packet that decrypts
# to 32 ASCII "A" bytes
conversation = Connect("localhost", 4433)
node = conversation
# any CBC will do, but the rest of code expects a 128 bit block cipher and
# 160 bit HMAC
ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA]
node = node.add_child(ClientHelloGenerator(ciphers,
extensions={ExtensionType.renegotiation_info:None}))
node = node.add_child(ExpectServerHello(extensions={ExtensionType.renegotiation_info:None}))
node = node.add_child(ExpectCertificate())
node = node.add_child(ExpectServerHelloDone())
node = node.add_child(ClientKeyExchangeGenerator())
node = node.add_child(ChangeCipherSpecGenerator())
node = node.add_child(FinishedGenerator())
node = node.add_child(ExpectChangeCipherSpec())
node = node.add_child(ExpectFinished())
# we are encrypting 4 blocks, with 3 blocks (48 bytes) being data, MAC and padding
node = node.add_child(
fuzz_plaintext(ApplicationDataGenerator(bytearray(b"GET / HTTP/1.0\n\n"))
,
substitutions=dict((i, 0x31) for i in range(-1, -49, -1))))
node = node.add_child(ExpectAlert(AlertLevel.fatal, AlertDescription.bad_record_mac))
node = node.add_child(ExpectClose())
conversations["CVE-2016-2107"] = conversation
good = 0
bad = 0
for conversation_name, conversation in conversations.items():
print("{0} ...".format(conversation_name))
runner = Runner(conversation)
res = True
try:
runner.run()
except:
print("Error while processing")
print(traceback.format_exc())
print("")
res = False
if res:
good+=1
print("OK\n")
else:
bad+=1
print("Test end")
print("successful: {0}".format(good))
print("failed: {0}".format(bad))
if bad > 0:
sys.exit(1)
if __name__ == "__main__":
main()