tlspretense 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/.document +6 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +41 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.rdoc +231 -0
  8. data/Rakefile +44 -0
  9. data/bin/makeder.sh +6 -0
  10. data/bin/tlspretense +7 -0
  11. data/bin/view.sh +3 -0
  12. data/doc/general_setup.rdoc +288 -0
  13. data/doc/linux_setup.rdoc +64 -0
  14. data/lib/certmaker.rb +61 -0
  15. data/lib/certmaker/certificate_factory.rb +106 -0
  16. data/lib/certmaker/certificate_suite_generator.rb +120 -0
  17. data/lib/certmaker/ext_core/hash_indifferent_fetch.rb +12 -0
  18. data/lib/certmaker/runner.rb +27 -0
  19. data/lib/certmaker/tasks.rb +20 -0
  20. data/lib/packetthief.rb +167 -0
  21. data/lib/packetthief/handlers.rb +14 -0
  22. data/lib/packetthief/handlers/abstract_ssl_handler.rb +249 -0
  23. data/lib/packetthief/handlers/proxy_redirector.rb +26 -0
  24. data/lib/packetthief/handlers/ssl_client.rb +87 -0
  25. data/lib/packetthief/handlers/ssl_server.rb +174 -0
  26. data/lib/packetthief/handlers/ssl_smart_proxy.rb +143 -0
  27. data/lib/packetthief/handlers/ssl_transparent_proxy.rb +225 -0
  28. data/lib/packetthief/handlers/transparent_proxy.rb +183 -0
  29. data/lib/packetthief/impl.rb +11 -0
  30. data/lib/packetthief/impl/ipfw.rb +140 -0
  31. data/lib/packetthief/impl/manual.rb +54 -0
  32. data/lib/packetthief/impl/netfilter.rb +109 -0
  33. data/lib/packetthief/impl/pf_divert.rb +168 -0
  34. data/lib/packetthief/impl/pf_rdr.rb +192 -0
  35. data/lib/packetthief/logging.rb +49 -0
  36. data/lib/packetthief/redirect_rule.rb +29 -0
  37. data/lib/packetthief/util.rb +36 -0
  38. data/lib/ssl_test.rb +21 -0
  39. data/lib/ssl_test/app_context.rb +17 -0
  40. data/lib/ssl_test/certificate_manager.rb +33 -0
  41. data/lib/ssl_test/config.rb +79 -0
  42. data/lib/ssl_test/ext_core/io_raw_input.rb +31 -0
  43. data/lib/ssl_test/input_handler.rb +35 -0
  44. data/lib/ssl_test/runner.rb +110 -0
  45. data/lib/ssl_test/runner_options.rb +68 -0
  46. data/lib/ssl_test/ssl_test_case.rb +46 -0
  47. data/lib/ssl_test/ssl_test_report.rb +24 -0
  48. data/lib/ssl_test/ssl_test_result.rb +30 -0
  49. data/lib/ssl_test/test_listener.rb +140 -0
  50. data/lib/ssl_test/test_manager.rb +116 -0
  51. data/lib/tlspretense.rb +13 -0
  52. data/lib/tlspretense/app.rb +52 -0
  53. data/lib/tlspretense/init_runner.rb +115 -0
  54. data/lib/tlspretense/skel/ca/goodcacert.pem +19 -0
  55. data/lib/tlspretense/skel/ca/goodcakey.pem +27 -0
  56. data/lib/tlspretense/skel/config.yml +523 -0
  57. data/lib/tlspretense/version.rb +3 -0
  58. data/packetthief_examples/em_ssl_test.rb +73 -0
  59. data/packetthief_examples/redirector.rb +29 -0
  60. data/packetthief_examples/setup_iptables.sh +24 -0
  61. data/packetthief_examples/ssl_client_simple.rb +27 -0
  62. data/packetthief_examples/ssl_server_simple.rb +44 -0
  63. data/packetthief_examples/ssl_smart_proxy.rb +115 -0
  64. data/packetthief_examples/ssl_transparent_proxy.rb +97 -0
  65. data/packetthief_examples/transparent_proxy.rb +56 -0
  66. data/spec/packetthief/impl/ipfw_spec.rb +98 -0
  67. data/spec/packetthief/impl/manual_spec.rb +65 -0
  68. data/spec/packetthief/impl/netfilter_spec.rb +66 -0
  69. data/spec/packetthief/impl/pf_divert_spec.rb +82 -0
  70. data/spec/packetthief/impl/pf_rdr_spec.rb +133 -0
  71. data/spec/packetthief/logging_spec.rb +78 -0
  72. data/spec/packetthief_spec.rb +47 -0
  73. data/spec/spec_helper.rb +53 -0
  74. data/spec/ssl_test/certificate_manager_spec.rb +222 -0
  75. data/spec/ssl_test/config_spec.rb +76 -0
  76. data/spec/ssl_test/runner_spec.rb +360 -0
  77. data/spec/ssl_test/ssl_test_case_spec.rb +113 -0
  78. data/spec/ssl_test/test_listener_spec.rb +199 -0
  79. data/spec/ssl_test/test_manager_spec.rb +324 -0
  80. data/tlspretense.gemspec +35 -0
  81. metadata +262 -0
@@ -0,0 +1,3 @@
1
+ module TLSPretense
2
+ VERSION = '0.6.1'
3
+ end
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << 'lib'
4
+
5
+ require 'rubygems'
6
+ require 'eventmachine'
7
+ require 'packetthief' # needs root
8
+
9
+
10
+ # Note that this does not forward the encrypted traffic at all, so it isn't a
11
+ # full proxy. It just demonstrates that we can terminate the SSL connection
12
+ # that we have redirected.
13
+ #
14
+ # Also, you will need to supply your own certificate chain and private key file.
15
+ #
16
+ # A single connection:
17
+ # Connected
18
+ # starting TLS
19
+ # Connection closed
20
+ #
21
+ # A second connection, where the client accepts the certificate:
22
+ # Connected
23
+ # starting TLS
24
+ # SSL handshake completed
25
+ # Received data
26
+ module SSLTester
27
+ def initialize(chainfile, keyfile)
28
+ puts "Connected"
29
+ @chainfile = chainfile
30
+ @keyfile = keyfile
31
+ end
32
+
33
+ def connection_completed
34
+ puts "Connection completed."
35
+ end
36
+
37
+ def post_init
38
+ puts "starting TLS"
39
+ start_tls(:private_key_file => @keyfile, :cert_chain_file => @chainfile, :verify_peer => false)
40
+ end
41
+
42
+ def ssl_handshake_completed
43
+ puts "SSL handshake completed"
44
+ end
45
+
46
+ def receive_data(data)
47
+ puts "Received data"
48
+ end
49
+
50
+ def unbind
51
+ puts "Connection closed"
52
+ end
53
+ end
54
+
55
+
56
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443).run
57
+ EM.run {
58
+ EM.start_server('', 54321, SSLTester, 'chain.pem', 'key.pem')
59
+
60
+ Signal.trap("TERM") do
61
+ puts "Received SIGTERM"
62
+ PacketThief.revert
63
+ exit
64
+ end
65
+
66
+ Signal.trap("INT") do
67
+ puts "Received SIGINT"
68
+ PacketThief.revert
69
+ exit
70
+ end
71
+
72
+ }
73
+ PacketThief.revert
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << 'lib'
4
+
5
+ require 'rubygems'
6
+ require 'eventmachine'
7
+ require 'packetthief' # needs root
8
+
9
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 80, :in_interface => 'en1').run
10
+
11
+ at_exit { puts "Exiting"; PacketThief.revert }
12
+
13
+ Signal.trap("TERM") do
14
+ puts "Received SIGTERM"
15
+ exit
16
+ end
17
+
18
+ Signal.trap("INT") do
19
+ puts "Received SIGINT"
20
+ exit
21
+ end
22
+
23
+
24
+ EM.run do
25
+
26
+ EM.start_server('', 54321, PacketThief::Handlers::ProxyRedirector, 'localhost', 8080)
27
+
28
+ end
29
+ PacketThief.revert
@@ -0,0 +1,24 @@
1
+ #!/bin/sh
2
+ # Sample script for setting up iptables/netfilter for use with PacketThief. It
3
+ # creates a NAT on the external interface, and it manually configures the
4
+ # internal interface. A more advanced setup with a DHCP server could make it
5
+ # easier by auto-configuring clients.
6
+ external=eth0
7
+ internal=eth1
8
+
9
+ iptables --flush
10
+ iptables --table nat --flush
11
+ iptables --delete-chain
12
+ iptables --table nat --delete-chain
13
+
14
+
15
+ echo "Manually setup the internal network's nic"
16
+ ifconfig $internal 192.168.0.1 netmask 255.255.255.0
17
+
18
+ echo "enabling packet forwarding"
19
+ echo 1 > /proc/sys/net/ipv4/ip_forward
20
+
21
+ echo "applying basic iptables rules for NATing"
22
+ iptables -t nat -A POSTROUTING -o $external -j MASQUERADE
23
+
24
+ echo "Done! PacketThief will create and destroy the rules for redirecting traffic."
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # This example just shows how to call the SSLServer class with PacketThief. All
3
+ # it does is receive data -- it does not attempt to send data on.
4
+ #
5
+ # TODO: Make the dest configurable
6
+ # TODO: Pull input form stdin
7
+
8
+ $: << 'lib'
9
+
10
+ require 'rubygems'
11
+ require 'eventmachine'
12
+ require 'packetthief' # needs root
13
+
14
+
15
+ EM.run do
16
+
17
+ PacketThief::Handlers::SSLClient.connect('www.isecpartners.com', 443) do |h|
18
+ h.ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
19
+ # h.ctx.ssl_version = :TLSv1_client
20
+
21
+ def h.tls_successful_handshake
22
+ puts @sslsocket.peer_cert_chain.inspect
23
+ close_connection
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # This example just shows how to call the SSLServer class with PacketThief. All
3
+ # it does is receive data -- it does not attempt to send data on.
4
+
5
+ $: << 'lib'
6
+
7
+ require 'rubygems'
8
+ require 'eventmachine'
9
+ require 'packetthief' # needs root
10
+
11
+ if ARGV.length != 2
12
+ puts "script chain.pem key.pem"
13
+ exit 1
14
+ end
15
+
16
+ chain = PacketThief::Util.cert_chain(File.read(ARGV[0]))
17
+ puts "Certificate chain:"
18
+ p chain
19
+ cert = chain.shift
20
+ key = OpenSSL::PKey.read(File.read(ARGV[1]))
21
+
22
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'en1').run
23
+ at_exit { puts "Exiting"; PacketThief.revert }
24
+ Signal.trap("TERM") do
25
+ puts "Received SIGTERM"
26
+ exit
27
+ end
28
+ Signal.trap("INT") do
29
+ puts "Received SIGINT"
30
+ exit
31
+ end
32
+
33
+ EM.run do
34
+
35
+ PacketThief::Handlers::SSLServer.start('', 54321) do |h|
36
+ puts "extra block"
37
+ h.ctx.cert = cert
38
+ h.ctx.extra_chain_cert = chain
39
+ h.ctx.key = key
40
+ end
41
+
42
+
43
+ end
44
+ PacketThief.revert
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << 'lib'
4
+
5
+ require 'rubygems'
6
+ require 'eventmachine'
7
+ require 'packetthief' # needs root
8
+
9
+ class VerboseProxy < PacketThief::Handlers::SSLSmartProxy
10
+
11
+ def client_desc
12
+ "Client #{client_host}:#{client_port}->#{dest_host}:#{dest_port} (#{dest_hostname})"
13
+ end
14
+
15
+ def dest_desc
16
+ "Dest #{dest_host}:#{dest_port}(#{dest_hostname})->#{client_host}:#{client_port}"
17
+ end
18
+
19
+ def servername_cb(sslsock, hostname)
20
+ puts "#{client_desc} request hostname: #{hostname}"
21
+ super(sslsock, hostname)
22
+ end
23
+
24
+ def client_connected
25
+ puts "#{client_desc} connected and TLS handshake succeeded"
26
+ super
27
+ end
28
+
29
+ def client_handshake_failed(e)
30
+ puts "TLS handshake from #{client_desc} failed: #{e}"
31
+ end
32
+
33
+ def client_recv(data)
34
+ puts "#{client_desc} says (#{data.length}): #{data.inspect}"
35
+ # @seenclientdata ||= false
36
+ # unless @seenclientdata
37
+ # puts "#{client_desc} says (#{data.length}): #{data.split("\r\n\r\n",2)[0]}"
38
+ # puts ""
39
+ # @seenclientdata = true
40
+ # else
41
+ # puts "#{client_desc} says (#{data.length}): #{data[0,20].inspect}"
42
+ # end
43
+ super(data)
44
+ end
45
+
46
+ def client_closed
47
+ puts "#{client_desc} closed"
48
+ end
49
+
50
+ def dest_connected
51
+ puts "#{dest_desc} connected"
52
+ puts "Remote certificates: #{dest_cert_chain.inspect}"
53
+ end
54
+
55
+ def dest_handshake_failed(e)
56
+ puts "TLS handshake to #{dest_desc} handshake failed: #{e}"
57
+ end
58
+
59
+ def dest_recv(data)
60
+ puts "#{dest_desc} says (#{data.length}): #{data.inspect}"
61
+ # @seendestdata ||= false
62
+ # unless @seendestdata
63
+ # puts "#{dest_desc} says (#{data.length}): #{data.split("\r\n\r\n",2)[0]}"
64
+ # puts ""
65
+ # @seendestdata = true
66
+ # else
67
+ # puts "#{dest_desc} says (#{data.length}): #{data[0,20].inspect}"
68
+ # end
69
+ super(data)
70
+ end
71
+
72
+ def dest_closed
73
+ puts "#{dest_desc} closed"
74
+ end
75
+
76
+ end
77
+
78
+ if ARGV.length != 2
79
+ puts "script cacert.pem key.pem"
80
+ exit 1
81
+ end
82
+ cacert = OpenSSL::X509::Certificate.new(File.read(ARGV[0]))
83
+ key = OpenSSL::PKey.read(File.read(ARGV[1]))
84
+
85
+
86
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'en1').run
87
+ #PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'vmnet1').run
88
+ #PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'vmnet8').run
89
+ #PacketThief.redirect(:to_ports => 54322).where(:protocol => :tcp, :dest_port => 80, :in_interface => 'en1').run
90
+
91
+ at_exit { puts "Exiting"; PacketThief.revert }
92
+
93
+ Signal.trap("TERM") do
94
+ puts "Received SIGTERM"
95
+ exit
96
+ end
97
+
98
+ Signal.trap("INT") do
99
+ puts "Received SIGINT"
100
+ exit
101
+ end
102
+
103
+ EM.run do
104
+
105
+ VerboseProxy.start('', 54321, cacert, key) do |h|
106
+ # h.ctx.ssl_version = :TLSv1_server
107
+ end
108
+ EM.start_server('', 54322, PacketThief::Handlers::TransparentProxy) do |h|
109
+ def h.client_recv(data)
110
+ puts "HTTP: #{data}"
111
+ end
112
+ end
113
+
114
+ end
115
+ PacketThief.revert
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << 'lib'
4
+
5
+ require 'rubygems'
6
+ require 'eventmachine'
7
+ require 'packetthief' # needs root
8
+
9
+ class VerboseProxy < PacketThief::Handlers::SSLTransparentProxy
10
+
11
+ def client_desc
12
+ "Client #{client_host}:#{client_port}->#{dest_host}:#{dest_port} (#{dest_hostname})"
13
+ end
14
+
15
+ def dest_desc
16
+ "Dest #{dest_host}:#{dest_port}(#{dest_hostname})->#{client_host}:#{client_port}"
17
+ end
18
+
19
+ def servername_cb(sslsock, hostname)
20
+ puts "#{client_desc} request hostname: #{hostname}"
21
+ super(sslsock, hostname)
22
+ end
23
+
24
+ def client_connected
25
+ puts "#{client_desc} connected and TLS handshake succeeded"
26
+ super
27
+ end
28
+
29
+ def client_handshake_failed(e)
30
+ puts "TLS handshake from #{client_desc} failed: #{e}"
31
+ end
32
+
33
+ def client_recv(data)
34
+ puts "#{client_desc} says: #{data[0,20].inspect}"
35
+ super(data)
36
+ end
37
+
38
+ def client_closed
39
+ puts "#{client_desc} closing"
40
+ end
41
+
42
+ def dest_connected
43
+ puts "#{dest_desc} connected"
44
+ puts "Remote certificates: #{dest_cert_chain.inspect}"
45
+ end
46
+
47
+ def dest_handshake_failed(e)
48
+ puts "TLS handshake to #{dest_desc} handshake failed: #{e}"
49
+ end
50
+
51
+ def dest_recv(data)
52
+ puts "#{dest_desc} says: #{data[0,20].inspect}"
53
+ super(data)
54
+ end
55
+
56
+ def dest_closed
57
+ puts "#{dest_desc} closing"
58
+ end
59
+
60
+ end
61
+
62
+
63
+ if ARGV.length != 2
64
+ puts "script chain.pem key.pem"
65
+ exit 1
66
+ end
67
+
68
+ chain = PacketThief::Util.cert_chain(File.read(ARGV[0]))
69
+ puts "Certificate chain:"
70
+ p chain
71
+ cert = chain.shift
72
+ key = OpenSSL::PKey.read(File.read(ARGV[1]))
73
+
74
+
75
+ #PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 80, :in_interface => 'en1').run
76
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'en1').run
77
+ at_exit { puts "Exiting"; PacketThief.revert }
78
+ Signal.trap("TERM") do
79
+ puts "Received SIGTERM"
80
+ exit
81
+ end
82
+ Signal.trap("INT") do
83
+ puts "Received SIGINT"
84
+ exit
85
+ end
86
+
87
+ EM.run do
88
+
89
+ VerboseProxy.start('', 54321) do |h|
90
+ h.ctx.cert = cert
91
+ h.ctx.extra_chain_cert = chain
92
+ h.ctx.key = key
93
+ # h.ctx.ssl_version = :TLSv1_server
94
+ end
95
+
96
+ end
97
+ PacketThief.revert
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << 'lib'
4
+
5
+ require 'rubygems'
6
+ require 'eventmachine'
7
+ require 'packetthief' # needs root
8
+
9
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 80, :in_interface => 'en1').run
10
+ PacketThief.redirect(:to_ports => 54321).where(:protocol => :tcp, :dest_port => 443, :in_interface => 'en1').run
11
+
12
+ at_exit { puts "Exiting"; PacketThief.revert }
13
+
14
+ Signal.trap("TERM") do
15
+ puts "Received SIGTERM"
16
+ exit
17
+ end
18
+
19
+ Signal.trap("INT") do
20
+ puts "Received SIGINT"
21
+ exit
22
+ end
23
+
24
+ class VerboseProxy < PacketThief::Handlers::TransparentProxy
25
+
26
+ def client_connected
27
+ puts "Client #{client_host}:#{client_port}->#{dest_host}:#{dest_port} connected"
28
+ connect_to_dest
29
+ end
30
+
31
+ def client_recv(data)
32
+ puts "Client #{client_host}:#{client_port}->#{dest_host}:#{dest_port} says: #{data[0,20].inspect}"
33
+ send_to_dest data
34
+ end
35
+
36
+ def dest_recv(data)
37
+ puts "Dest #{client_host}:#{client_port}->#{dest_host}:#{dest_port} says: #{data[0,20].inspect}"
38
+ send_to_client data
39
+ end
40
+
41
+ def client_closed
42
+ puts "Client #{client_host}:#{client_port}->#{dest_host}:#{dest_port} closing"
43
+ end
44
+
45
+ def dest_closed
46
+ puts "Dest #{client_host}:#{client_port}->#{dest_host}:#{dest_port} closing"
47
+ end
48
+
49
+ end
50
+
51
+ EM.run do
52
+
53
+ EM.start_server('', 54321, VerboseProxy)
54
+
55
+ end
56
+ PacketThief.revert