bettercap 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,35 @@
1
+ module BetterCap
2
+ module Network
3
+ # This class is responsible for reading the computer ARP table.
4
+ class NdpReader
5
+ # Parse the Ndp cache searching for the given IP +address+ and return its
6
+ # MAC if found, otherwise nil.
7
+ def self.find_address( address )
8
+ self.parse_cache(address) do |ip,mac|
9
+ if ip == address
10
+ return mac
11
+ end
12
+ end
13
+ nil
14
+ end
15
+
16
+ private
17
+
18
+ # Read the computer NDP cache and parse each line, it will yield each
19
+ # ip and mac address it will be able to extract.
20
+ def self.parse_cache(address)
21
+ iface = Context.get.iface.name
22
+ Shell.ndp.split("\n").each do |line|
23
+ if line.include?(address) && line.include?(iface)
24
+ m = line.split
25
+ ip = m[0]
26
+ hw = Target.normalized_mac( m[4] )
27
+ if hw != 'FF:FF:FF:FF:FF:FF'
28
+ yield( ip, hw )
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -30,6 +30,21 @@ class << self
30
30
  nil
31
31
  end
32
32
 
33
+ # Return the current network's IPv6 gateway or nil.
34
+ def get_ipv6_gateway
35
+ route6 = Shell.execute('route -A inet6')
36
+ iface = Context.get.options.core.iface
37
+
38
+ Logger.debug "ROUTE6:\n#{route6}"
39
+
40
+ route6.split(/\n/).select {|n| n =~ /UG/ }.each do |line|
41
+ Network::Validator.each_ipv6_gateway(line) do |address|
42
+ return address
43
+ end
44
+ end
45
+ nil
46
+ end
47
+
33
48
  # Return a list of IP addresses associated to this device network interfaces.
34
49
  def get_local_ips
35
50
  ips = []
@@ -77,10 +92,19 @@ class << self
77
92
  # Return the hardware address associated with the specified +ip_address+ using
78
93
  # the +iface+ network interface.
79
94
  def get_hw_address( ctx, ip )
80
- hw = ArpReader.find_address( ip )
95
+ hw = nil
96
+ if ctx.options.core.use_ipv6
97
+ hw = NdpReader.find_address( ip )
98
+ else
99
+ hw = ArpReader.find_address( ip )
100
+ end
81
101
  if hw.nil?
82
102
  start_agents( ctx, ip )
83
- hw = ArpReader.find_address( ip )
103
+ if ctx.options.core.use_ipv6
104
+ hw = NdpReader.find_address( ip )
105
+ else
106
+ hw = ArpReader.find_address( ip )
107
+ end
84
108
  end
85
109
  hw
86
110
  end
@@ -115,8 +139,12 @@ class << self
115
139
  # complete their job.
116
140
  # If +address+ is not nil only that ip will be probed.
117
141
  def start_agents( ctx, address = nil )
118
- [ 'Icmp', 'Udp', 'Arp' ].each do |name|
119
- BetterCap::Loader.load("BetterCap::Discovery::Agents::#{name}").new(ctx, address)
142
+ if ctx.options.core.use_ipv6
143
+ BetterCap::Loader.load("BetterCap::Discovery::Agents::Ndp").new(ctx, address)
144
+ else
145
+ [ 'Icmp', 'Udp', 'Arp' ].each do |name|
146
+ BetterCap::Loader.load("BetterCap::Discovery::Agents::#{name}").new(ctx, address)
147
+ end
120
148
  end
121
149
  ctx.packets.wait_empty( ctx.timeout )
122
150
  end
@@ -47,7 +47,7 @@ class Target
47
47
  # ip address will be parsed from the computer ARP cache and updated
48
48
  # accordingly.
49
49
  def initialize( ip, mac=nil, network=nil, name=nil )
50
- if Network::Validator.is_ip?(ip)
50
+ if Network::Validator.is_ip?(ip) or Network::Validator.is_ipv6?(ip)
51
51
  @ip = ip
52
52
  @ip_refresh = false
53
53
  elsif Network::Validator.is_mac?(ip)
@@ -16,8 +16,28 @@ module Network
16
16
  class Validator
17
17
  # Basic expression to validate an IP address.
18
18
  IP_ADDRESS_REGEX = '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})'
19
+ # Basic expression to validate an IPv6 address.
20
+ IPV6_REGEX = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|
21
+ (([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|
22
+ [1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]
23
+ {1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]
24
+ ?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:)
25
+ {4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]
26
+ \d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))
27
+ |(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]
28
+ {1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|
29
+ 1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4})
30
+ {1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)
31
+ (\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:)
32
+ {1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|
33
+ 2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))
34
+ |(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|
35
+ 2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))
36
+ (%.+)?\s*$/x
19
37
  # Quite self explainatory :)
20
38
  IP_OCTECT_MAX = 255
39
+ # Basic expression for default IPv6 gateway.
40
+ IPV6_GATEWAY_REGEX = /fe80[^\s]*/
21
41
 
22
42
  # Return true if +ip+ is a valid IP address, otherwise false.
23
43
  def self.is_ip?(ip)
@@ -27,6 +47,12 @@ class Validator
27
47
  false
28
48
  end
29
49
 
50
+ # Return true if +ip+ is a valid IPv6 address, otherwise false.
51
+ def self.is_ipv6?(ip)
52
+ result = ip =~ IPV6_REGEX
53
+ return result ? true : false
54
+ end
55
+
30
56
  # Return true if +port+ is a valid port, otherwise false.
31
57
  def self.is_valid_port?(port)
32
58
  port ||= ""
@@ -43,6 +69,13 @@ class Validator
43
69
  end
44
70
  end
45
71
 
72
+ # Extract default IPv6 gateway address from +data+.
73
+ def self.each_ipv6_gateway(data)
74
+ data.scan(/(#{IPV6_GATEWAY_REGEX})/).each do |m|
75
+ yield ( m[0] )
76
+ end
77
+ end
78
+
46
79
  # Return true if +r+ is a valid IP address range ( 192.168.1.1-93 ), otherwise false.
47
80
  def self.is_range?(r)
48
81
  if /\A#{IP_ADDRESS_REGEX}\-(\d{1,3})\Z/ =~ r.to_s
@@ -41,6 +41,8 @@ class CoreOptions
41
41
  attr_accessor :check_updates
42
42
  # If not nil, the interface MAC address will be changed to this value.
43
43
  attr_accessor :use_mac
44
+ # If true, IPv6 target endpoints are enabled.
45
+ attr_accessor :use_ipv6
44
46
 
45
47
  def initialize( iface )
46
48
  @iface = iface
@@ -56,6 +58,7 @@ class CoreOptions
56
58
  @packet_throttle = 0.0
57
59
  @check_updates = false
58
60
  @use_mac = nil
61
+ @use_ipv6 = false
59
62
  end
60
63
 
61
64
  def parse!( ctx, opts )
@@ -78,7 +81,7 @@ class CoreOptions
78
81
 
79
82
  opts.on( '-G', '--gateway ADDRESS', 'Manually specify the gateway address, if not specified the current gateway will be retrieved and used. ' ) do |v|
80
83
  @gateway = v
81
- raise BetterCap::Error, "The specified gateway '#{v}' is not a valid IPv4 address." unless Network::Validator.is_ip?(v)
84
+ check_ip!( v, "The specified gateway '#{v}' is not a valid IPv4 or IPv6 address." )
82
85
  end
83
86
 
84
87
  opts.on( '-T', '--target ADDRESS1,ADDRESS2', 'Target IP addresses, if not specified the whole subnet will be targeted.' ) do |v|
@@ -147,6 +150,16 @@ class CoreOptions
147
150
  raise BetterCap::Error, 'No default interface found, please specify one with the -I argument.' if @iface.nil?
148
151
  end
149
152
 
153
+ def check_ip!(v,error)
154
+ if Network::Validator.is_ip?(v)
155
+ @use_ipv6 = false
156
+ elsif Network::Validator.is_ipv6?(v)
157
+ @use_ipv6 = true
158
+ else
159
+ raise BetterCap::Error, error
160
+ end
161
+ end
162
+
150
163
  # Return true if active host discovery is enabled, otherwise false.
151
164
  def discovery?
152
165
  ( @discovery and @targets.nil? )
@@ -161,6 +174,10 @@ class CoreOptions
161
174
  if Network::Validator.is_ip?(t) or Network::Validator.is_mac?(t)
162
175
  @targets << Network::Target.new(t)
163
176
 
177
+ elsif Network::Validator.is_ipv6?(t)
178
+ @targets << Network::Target.new(t)
179
+ @use_ipv6 = true
180
+
164
181
  elsif Network::Validator.is_range?(t)
165
182
  Network::Validator.each_in_range( t ) do |address|
166
183
  @targets << Network::Target.new(address)
@@ -172,7 +189,7 @@ class CoreOptions
172
189
  end
173
190
 
174
191
  else
175
- raise BetterCap::Error, "Invalid target specified '#{t}', valid formats are IP addresses, "\
192
+ raise BetterCap::Error, "Invalid target specified '#{t}', valid formats are IP/IPv6 addresses, "\
176
193
  "MAC addresses, IP ranges ( 192.168.1.1-30 ) or netmasks ( 192.168.1.1/24 ) ."
177
194
  end
178
195
  end
@@ -182,7 +199,7 @@ class CoreOptions
182
199
  # or more invalid IP addresses are specified.
183
200
  def ignore=(value)
184
201
  @ignore = value.split(",")
185
- valid = @ignore.select { |target| Network::Validator.is_ip?(target) }
202
+ valid = @ignore.select { |target| ( Network::Validator.is_ip?(target) or Network::Validator.is_ipv6?(target) ) }
186
203
 
187
204
  raise BetterCap::Error, "Invalid ignore addresses specified." if valid.empty?
188
205
 
@@ -191,6 +208,12 @@ class CoreOptions
191
208
  Logger.warn "Not a valid address: #{target}"
192
209
  end
193
210
 
211
+ valid.each do |target|
212
+ if Network::Validator.is_ipv6?(target)
213
+ @use_ipv6 = true
214
+ end
215
+ end
216
+
194
217
  @ignore = valid
195
218
 
196
219
  Logger.warn "Ignoring #{valid.join(", ")} ."
@@ -125,6 +125,10 @@ class Options
125
125
  redirections << redir_single( @proxies.tcp_proxy_upstream_address, iface.ip, @proxies.tcp_proxy_upstream_port, @proxies.tcp_proxy_port )
126
126
  end
127
127
 
128
+ if @proxies.udp_proxy
129
+ redirections << redir_single( @proxies.udp_proxy_upstream_address, iface.ip, @proxies.udp_proxy_upstream_port, @proxies.udp_proxy_port, 'UDP' )
130
+ end
131
+
128
132
  if @proxies.custom_proxy
129
133
  @proxies.http_ports.each do |port|
130
134
  redirections << redir( @proxies.custom_proxy, port, @proxies.custom_proxy_port )
@@ -153,6 +157,7 @@ class Options
153
157
  'discovery' => ( @core.discovery? ? on : off ),
154
158
  'sniffer' => ( @sniff.enabled? ? on : off ),
155
159
  'tcp-proxy' => ( @proxies.tcp_proxy ? on : off ),
160
+ 'udp-proxy' => ( @proxies.udp_proxy ? on : off ),
156
161
  'http-proxy' => ( @proxies.proxy ? on : off ),
157
162
  'https-proxy' => ( @proxies.proxy_https ? on : off ),
158
163
  'sslstrip' => ( @proxies.sslstrip? ? on : off ),
@@ -40,6 +40,7 @@ class ProxyOptions
40
40
  attr_accessor :log_response
41
41
  # If true, suppress HTTP requests logs.
42
42
  attr_accessor :no_http_logs
43
+
43
44
  # If true, TCP proxy will be enabled.
44
45
  attr_accessor :tcp_proxy
45
46
  # TCP proxy local port.
@@ -50,6 +51,18 @@ class ProxyOptions
50
51
  attr_accessor :tcp_proxy_upstream_port
51
52
  # TCP proxy module to load.
52
53
  attr_accessor :tcp_proxy_module
54
+
55
+ # If true, UDP proxy will be enabled.
56
+ attr_accessor :udp_proxy
57
+ # UDP proxy local port.
58
+ attr_accessor :udp_proxy_port
59
+ # UDP proxy upstream server address.
60
+ attr_accessor :udp_proxy_upstream_address
61
+ # UDP proxy upstream server port.
62
+ attr_accessor :udp_proxy_upstream_port
63
+ # UDP proxy module to load.
64
+ attr_accessor :udp_proxy_module
65
+
53
66
  # Custom HTTP transparent proxy address.
54
67
  attr_accessor :custom_proxy
55
68
  # Custom HTTP transparent proxy port.
@@ -82,6 +95,12 @@ class ProxyOptions
82
95
  @tcp_proxy_upstream_port = nil
83
96
  @tcp_proxy_module = nil
84
97
 
98
+ @udp_proxy = false
99
+ @udp_proxy_port = 3333
100
+ @udp_proxy_upstream_address = nil
101
+ @udp_proxy_upstream_port = nil
102
+ @udp_proxy_module = nil
103
+
85
104
  @custom_proxy = nil
86
105
  @custom_proxy_port = 8080
87
106
 
@@ -143,6 +162,53 @@ class ProxyOptions
143
162
  @tcp_proxy_upstream_port = v.to_i
144
163
  end
145
164
 
165
+ opts.separator ""
166
+ opts.separator " UDP:"
167
+ opts.separator ""
168
+
169
+ opts.on( '--udp-proxy', 'Enable UDP proxy ( requires other --udp-proxy-* options to be specified ).' ) do
170
+ @udp_proxy = true
171
+ end
172
+
173
+ opts.on( '--udp-proxy-module MODULE', "Ruby UDP proxy module to load." ) do |v|
174
+ @udp_proxy_module = File.expand_path(v)
175
+ Proxy::UDP::Module.load( @udp_proxy_module, opts )
176
+ end
177
+
178
+ opts.on( '--udp-proxy-port PORT', "Set local UDP proxy port, default to #{@udp_proxy_port.to_s.yellow} ." ) do |v|
179
+ raise BetterCap::Error, "Invalid port '#{v}' specified." unless Network::Validator.is_valid_port?(v)
180
+ @udp_proxy = true
181
+ @udp_proxy_port = v.to_i
182
+ end
183
+
184
+ opts.on( '--udp-proxy-upstream ADDRESS:PORT', 'Set UDP proxy upstream server address and port.' ) do |v|
185
+ if v =~ /^(.+):(\d+)$/
186
+ address = $1
187
+ port = $2
188
+ else
189
+ raise BetterCap::Error, "Invalid address and port specified, the correct syntax is ADDRESS:PORT ( i.e. 192.168.1.2:69 )."
190
+ end
191
+
192
+ address, port = validate_address address, port
193
+
194
+ @udp_proxy = true
195
+ @udp_proxy_upstream_address = address
196
+ @udp_proxy_upstream_port = port.to_i
197
+ end
198
+
199
+ opts.on( '--udp-proxy-upstream-address ADDRESS', 'Set UDP proxy upstream server address.' ) do |v|
200
+ v, _ = validate_address v
201
+
202
+ @udp_proxy = true
203
+ @udp_proxy_upstream_address = v
204
+ end
205
+
206
+ opts.on( '--udp-proxy-upstream-port PORT', 'Set UDP proxy upstream server port.' ) do |v|
207
+ raise BetterCap::Error, "Invalid port '#{v}' specified." unless Network::Validator.is_valid_port?(v)
208
+ @udp_proxy = true
209
+ @udp_proxy_upstream_port = v.to_i
210
+ end
211
+
146
212
  opts.separator " HTTP:"
147
213
  opts.separator ""
148
214
 
@@ -245,6 +311,12 @@ class ProxyOptions
245
311
  raise BetterCap::Error, "No TCP proxy upstream server port specified ( --tcp-proxy-upstream-port PORT )." if @tcp_proxy_upstream_port.nil?
246
312
  end
247
313
 
314
+ if @udp_proxy
315
+ raise BetterCap::Error, "No UDP proxy port specified ( --udp-proxy-port PORT )." if @udp_proxy_port.nil?
316
+ raise BetterCap::Error, "No UDP proxy upstream server address specified ( --udp-proxy-upstream-address ADDRESS )." if @udp_proxy_upstream_address.nil?
317
+ raise BetterCap::Error, "No UDP proxy upstream server port specified ( --udp-proxy-upstream-port PORT )." if @udp_proxy_upstream_port.nil?
318
+ end
319
+
248
320
  if @proxy and @sslstrip and ctx.options.servers.dnsd
249
321
  raise BetterCap::Error, "SSL Stripping and builtin DNS server are mutually exclusive features, " \
250
322
  "either use the --no-sslstrip option or remove the --dns option."
@@ -305,7 +377,7 @@ class ProxyOptions
305
377
  end
306
378
 
307
379
  def any?
308
- @proxy or @proxy_https or @tcp_proxy or @custom_proxy
380
+ @proxy or @proxy_https or @tcp_proxy or @udp_proxy or @custom_proxy
309
381
  end
310
382
 
311
383
  def validate_address( address, port = nil )
@@ -33,7 +33,7 @@ class SpoofOptions
33
33
  opts.separator "SPOOFING:".bold
34
34
  opts.separator ""
35
35
 
36
- opts.on( '-S', '--spoofer NAME', "Spoofer module to use, available: #{Spoofers::Base.available.map{|x| x.yellow }.join(', ')} - default: #{@spoofer.yellow}." ) do |v|
36
+ opts.on( '-S', '--spoofer NAME', "Spoofer module to use, available: #{Spoofers::Base.available.map{|x| x.yellow }.join(', ')} - default: #{@spoofer.yellow} for IPv4 and #{'NDP'.yellow} for IPv6." ) do |v|
37
37
  @spoofer = v
38
38
  end
39
39
 
@@ -55,11 +55,19 @@ class SpoofOptions
55
55
  @spoofer.upcase != 'NONE'
56
56
  end
57
57
 
58
+ # Change default ARP with NDP spoofer in case the target endpoint uses IPv6.
59
+ def calibrate_default_spoofer(ctx)
60
+ if ctx.options.core.use_ipv6
61
+ @spoofer = 'NDP'
62
+ end
63
+ end
64
+
58
65
 
59
66
  # Parse spoofers and return a list of BetterCap::Spoofers objects. Raise a
60
67
  # BetterCap::Error if an invalid spoofer name was specified.
61
- def parse_spoofers
68
+ def parse_spoofers(ctx)
62
69
  valid = []
70
+ calibrate_default_spoofer(ctx)
63
71
  @spoofer.split(",").each do |module_name|
64
72
  valid << Spoofers::Base.get_by_name( module_name )
65
73
  end
@@ -62,7 +62,12 @@ class Proxy
62
62
  # Start this proxy instance.
63
63
  def start
64
64
  begin
65
- @socket = TCPServer.new( @address, @port )
65
+ # If IPv6 is enabled, we must specify iface for current link local address since it's not unique.
66
+ if Context.get.options.core.use_ipv6
67
+ @socket = TCPServer.new( @address + "%" + Context.get.options.core.iface , @port )
68
+ else
69
+ @socket = TCPServer.new( @address, @port )
70
+ end
66
71
 
67
72
  if @is_https
68
73
  @sslserver = SSL::Server.new( @socket, @upstream_port )
@@ -64,7 +64,7 @@ class Response
64
64
  end
65
65
 
66
66
  r << "Connection: close"
67
- r << "\n\n"
67
+ r << "\r\n\r\n"
68
68
 
69
69
  r
70
70
  end
@@ -225,7 +225,13 @@ class Response
225
225
  s << "#{name}: #{value}\n"
226
226
  end
227
227
  end
228
- s << "\n" + ( @body.nil?? "\n" : @body )
228
+ s << "\r\n"
229
+
230
+ if @body.nil?
231
+ s << "\r\n"
232
+ else
233
+ s << @body
234
+ end
229
235
  s
230
236
  end
231
237
  end
@@ -1,52 +1,56 @@
1
1
  -----BEGIN RSA PRIVATE KEY-----
2
- MIIEogIBAAKCAQEAruvJ65uOclbgx1V+lNS0n1dtRj8V3iK4oYfFm6zk+bYVQgnh
3
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
27
27
  -----END RSA PRIVATE KEY-----
28
28
  -----BEGIN CERTIFICATE-----
29
- MIIEPTCCAyWgAwIBAgIJANs3OdOm704WMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD
30
- VQQGEwJVUzEQMA4GA1UECAwHQXJpem9uYTETMBEGA1UEBwwKU2NvdHRzZGFsZTEa
31
- MBgGA1UECgwRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsMJGh0dHA6Ly9jZXJ0
32
- cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAwwqR28gRGFkZHkgU2Vj
33
- dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTE2MTIyMzE4NDQyNFoX
34
- DTE3MDEyMjE4NDQyNFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6b25h
35
- MRMwEQYDVQQHDApTY290dHNkYWxlMRowGAYDVQQKDBFHb0RhZGR5LmNvbSwgSW5j
36
- LjEtMCsGA1UECwwkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv
37
- MTMwMQYDVQQDDCpHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
38
- IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCu68nrm45yVuDH
39
- VX6U1LSfV21GPxXeIrihh8WbrOT5thVCCeE0vb5Lk/JZ0/Rd2qxAcL9zgMuQwaOQ
40
- si3gpKvvxnmh0CjOD/pCTfEfI1qczgZ8KuREib/aOoRjYuUNVqANUFaanDwoc46X
41
- kWE7HSyAyWvUE1nk4KYPRdTIC8BVz7xfR8NhZkyE9kU0cFAvYfm7V6xEeULvEgHL
42
- QlGIlnDux/ejAEuXPko2k5W3D8tW1lSKLpE4NL6sweWq+aipySpX/te/G9yhMilT
43
- ojtIfvk3GzGiW2Zt+t1MX+I6jGFChAEzUep0RRpeyK4z9xzf5CymdVQMiZEAnWwR
44
- YpVKwG7VAgMBAAGjUDBOMB0GA1UdDgQWBBQc3wugFWxNWEKBJRzprSIA82S6gDAf
45
- BgNVHSMEGDAWgBQc3wugFWxNWEKBJRzprSIA82S6gDAMBgNVHRMEBTADAQH/MA0G
46
- CSqGSIb3DQEBCwUAA4IBAQCDZANKvSa7NX36jDMtQa95aDwTSnEo+AOKQ5lnG5Oa
47
- ztYnfqD49BwJUoZzO8J5nHqpSWjmssTOrQ0jc3KR/UjnJ73Gw+nppqr9UeHWSqvW
48
- kuCPxj5/zo+DB0rrMcIZVBqKgkiM5g4CHC+N743PnocmwZtB+uvGjNfaIFknV4Ee
49
- JKSFGmAtUk1sJn5E3052aDQR7TO7cXPwu8AL9OHYPCd4XmT59cH1pl/ULvJ1Isve
50
- aY/qcWypMMlsh46UoJooepIbrTPXYWKA2cdPQ9N5vNeg6SYbkwSuZdbgB84ibA9r
51
- rtNOmsdL7Dbr0FGINHhzhKlS60bVrmEAbyAMVljCC8s6
29
+ MIIFDDCCA/SgAwIBAgIJAKgmMGmQctr/MA0GCSqGSIb3DQEBBQUAMIG0MQswCQYD
30
+ VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEa
31
+ MBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0
32
+ cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2Vj
33
+ dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTE3MDYyOTE3MTMwNFoX
34
+ DTI3MDYyNzE3MTMwNFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25h
35
+ MRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5j
36
+ LjEtMCsGA1UECxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv
37
+ MTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
38
+ IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDjs3JM3y8xmPK
39
+ EbegtFhOufEkKEVnxM7ic+hha6mjHZNODqwW+8z0oj3aDP9jhZF2TfXuKHa5bHtb
40
+ JTlxD4PdLnEOkwa2ocCICcdCDrobWGYzhrezYQ8MtZ376PxMyv0OAEfCw5dXDvQh
41
+ DTFBP1MdkQwdr3aTFxdDaQVNbkSM+LuHMFZr5XfJe4wKfBU7ML4MUC70sfAcS/gp
42
+ z3q7aPj89A7XzXdAg0KYqoI/+hSHzgPPg+YkhiEK2iV4ph3JdHXL07eGeCOXeYjK
43
+ 7QnwihOiCVPBYysGaorLnsEdkMLVdXEvIdPt/1xkGtYZXicNGbvY8kUvQpXZ7Qz6
44
+ QePbL5XDAgMBAAGjggEdMIIBGTAdBgNVHQ4EFgQUo9Vx+QWZ9ce2K873Xxklfi2J
45
+ Q+owgekGA1UdIwSB4TCB3oAUo9Vx+QWZ9ce2K873Xxklfi2JQ+qhgbqkgbcwgbQx
46
+ CzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNk
47
+ YWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDov
48
+ L2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRk
49
+ eSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzKCCQCoJjBpkHLa/zAM
50
+ BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCKe6sCMJ52wAKrv2uKXuep
51
+ qj+epzXB8zTO4z2QcoreUAITEQSqfGjgtyWHM9jqZ8kq97d9KG9M/dp5YCpoAecj
52
+ kn3uweywUIXvyQqazP14KLJh+1W/DuGkzaEJFWbOMuTzE64QSyZ4NM/DW+hbdAls
53
+ 1k5zBVZH91qGczpsO1b//+pPFdPMtGJCFm+U1Mh7BzS5KZjsEEEDUO3trT1hP2qF
54
+ 9UJr22RZyTI595RW7JTbDaMTT7aTqHD58a6U2Lc2Au6YK0XiajBViqit0XnU2K2K
55
+ 2TXj8TpZ+v6O9X/ryYbr4Et4S6B4ljPuNo3CMyj3YPV29IoxNndg7zTHZCXJ3Lxh
52
56
  -----END CERTIFICATE-----