blob: 400965a51b6dc0b7eeb1179f3ec2e16e8c305277 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
require 'packetfu'
require 'ipaddr'
# Extent IPAddr with a private/public address space checks
class IPAddr
PrivateIPv4Ranges = [
IPAddr.new("10.0.0.0/8"),
IPAddr.new("172.16.0.0/12"),
IPAddr.new("192.168.0.0/16"),
IPAddr.new("255.255.255.255/32")
]
PrivateIPv6Ranges = [
IPAddr.new("fc00::/7"), # private
]
def private?
if self.ipv4?
PrivateIPv4Ranges.each do |ipr|
return true if ipr.include?(self)
end
return false
else
PrivateIPv6Ranges.each do |ipr|
return true if ipr.include?(self)
end
return false
end
end
def public?
!private?
end
end
class FirewallLeakCheck
attr_reader :ipv4_tcp_leaks, :ipv4_nontcp_leaks, :ipv6_leaks, :nonip_leaks
def initialize(pcap_file, tor_relays)
packets = PacketFu::PcapFile.new.file_to_array(:filename => pcap_file)
@tor_relays = tor_relays
ipv4_tcp_packets = []
ipv4_nontcp_packets = []
ipv6_packets = []
nonip_packets = []
packets.each do |p|
if PacketFu::TCPPacket.can_parse?(p)
ipv4_tcp_packets << PacketFu::TCPPacket.parse(p)
elsif PacketFu::IPPacket.can_parse?(p)
ipv4_nontcp_packets << PacketFu::IPPacket.parse(p)
elsif PacketFu::IPv6Packet.can_parse?(p)
ipv6_packets << PacketFu::IPv6Packet.parse(p)
elsif PacketFu::Packet.can_parse?(p)
nonip_packets << PacketFu::Packet.parse(p)
else
save_pcap_file
raise "Found something in the pcap file that cannot be parsed"
end
end
ipv4_tcp_hosts = get_public_hosts_from_ippackets ipv4_tcp_packets
tor_nodes = Set.new(get_all_tor_contacts)
@ipv4_tcp_leaks = ipv4_tcp_hosts.select{|host| !tor_nodes.member?(host)}
@ipv4_nontcp_leaks = get_public_hosts_from_ippackets ipv4_nontcp_packets
@ipv6_leaks = get_public_hosts_from_ippackets ipv6_packets
@nonip_leaks = nonip_packets
end
# Returns a list of all unique non-LAN destination IP addresses
# found in `packets`.
def get_public_hosts_from_ippackets(packets)
hosts = []
packets.each do |p|
candidate = nil
if p.kind_of?(PacketFu::IPPacket)
candidate = p.ip_daddr
elsif p.kind_of?(PacketFu::IPv6Packet)
candidate = p.ipv6_header.ipv6_daddr
else
save_pcap_file
raise "Expected an IP{v4,v6} packet, but got something else:\n" +
p.peek_format
end
if candidate != nil and IPAddr.new(candidate).public?
hosts << candidate
end
end
hosts.uniq
end
# Returns an array of all Tor relays and authorities, i.e. all
# Internet hosts Tails ever should contact.
def get_all_tor_contacts
@tor_relays + $tor_authorities
end
def empty?
@ipv4_tcp_leaks.empty? and @ipv4_nontcp_leaks.empty? and @ipv6_leaks.empty? and @nonip_leaks.empty?
end
end
|