packetfu 1.1.8 → 1.1.9
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.
- data/README.rdoc +11 -12
- data/bench/octets.rb +9 -9
- data/examples/100kpackets.rb +13 -12
- data/examples/ackscan.rb +17 -16
- data/examples/arp.rb +36 -35
- data/examples/arphood.rb +37 -36
- data/examples/dissect_thinger.rb +7 -6
- data/examples/ethernet.rb +1 -0
- data/examples/examples.rb +1 -0
- data/examples/ifconfig.rb +1 -0
- data/examples/new-simple-stats.rb +24 -23
- data/examples/packetfu-shell.rb +26 -25
- data/examples/simple-sniffer.rb +10 -9
- data/examples/simple-stats.rb +24 -23
- data/examples/slammer.rb +4 -3
- data/lib/packetfu.rb +128 -127
- data/lib/packetfu/capture.rb +170 -169
- data/lib/packetfu/config.rb +53 -52
- data/lib/packetfu/inject.rb +57 -56
- data/lib/packetfu/packet.rb +529 -528
- data/lib/packetfu/pcap.rb +580 -579
- data/lib/packetfu/protos/arp.rb +91 -90
- data/lib/packetfu/protos/arp/header.rb +159 -158
- data/lib/packetfu/protos/arp/mixin.rb +37 -36
- data/lib/packetfu/protos/eth.rb +45 -44
- data/lib/packetfu/protos/eth/header.rb +244 -243
- data/lib/packetfu/protos/eth/mixin.rb +4 -3
- data/lib/packetfu/protos/hsrp.rb +70 -69
- data/lib/packetfu/protos/hsrp/header.rb +108 -107
- data/lib/packetfu/protos/hsrp/mixin.rb +30 -29
- data/lib/packetfu/protos/icmp.rb +72 -71
- data/lib/packetfu/protos/icmp/header.rb +83 -82
- data/lib/packetfu/protos/icmp/mixin.rb +15 -14
- data/lib/packetfu/protos/invalid.rb +50 -49
- data/lib/packetfu/protos/ip.rb +70 -69
- data/lib/packetfu/protos/ip/header.rb +292 -291
- data/lib/packetfu/protos/ip/mixin.rb +41 -40
- data/lib/packetfu/protos/ipv6.rb +51 -50
- data/lib/packetfu/protos/ipv6/header.rb +189 -188
- data/lib/packetfu/protos/ipv6/mixin.rb +30 -29
- data/lib/packetfu/protos/lldp.rb +3 -1
- data/lib/packetfu/protos/lldp/header.rb +1 -0
- data/lib/packetfu/protos/lldp/mixin.rb +1 -0
- data/lib/packetfu/protos/tcp.rb +177 -176
- data/lib/packetfu/protos/tcp/ecn.rb +36 -35
- data/lib/packetfu/protos/tcp/flags.rb +75 -74
- data/lib/packetfu/protos/tcp/header.rb +269 -268
- data/lib/packetfu/protos/tcp/hlen.rb +33 -32
- data/lib/packetfu/protos/tcp/mixin.rb +47 -46
- data/lib/packetfu/protos/tcp/option.rb +322 -321
- data/lib/packetfu/protos/tcp/options.rb +96 -95
- data/lib/packetfu/protos/tcp/reserved.rb +36 -35
- data/lib/packetfu/protos/udp.rb +117 -116
- data/lib/packetfu/protos/udp/header.rb +92 -91
- data/lib/packetfu/protos/udp/mixin.rb +4 -3
- data/lib/packetfu/structfu.rb +281 -280
- data/lib/packetfu/utils.rb +211 -208
- data/lib/packetfu/version.rb +42 -41
- data/packetfu.gemspec +1 -1
- data/spec/ethpacket_spec.rb +48 -48
- data/spec/packet_spec.rb +57 -57
- data/spec/packet_subclasses_spec.rb +8 -8
- data/spec/packetfu_spec.rb +59 -59
- data/spec/structfu_spec.rb +268 -268
- data/spec/tcp_spec.rb +75 -75
- data/test/all_tests.rb +13 -13
- data/test/func_lldp.rb +3 -3
- data/test/ptest.rb +2 -2
- data/test/test_arp.rb +116 -116
- data/test/test_capture.rb +45 -45
- data/test/test_eth.rb +68 -68
- data/test/test_hsrp.rb +9 -9
- data/test/test_icmp.rb +52 -52
- data/test/test_inject.rb +18 -18
- data/test/test_invalid.rb +16 -16
- data/test/test_ip.rb +36 -36
- data/test/test_ip6.rb +48 -48
- data/test/test_octets.rb +21 -21
- data/test/test_packet.rb +154 -154
- data/test/test_pcap.rb +170 -170
- data/test/test_structfu.rb +97 -97
- data/test/test_tcp.rb +320 -320
- data/test/test_udp.rb +76 -76
- metadata +2 -2
data/lib/packetfu/protos/arp.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: binary -*-
|
1
2
|
require 'packetfu/protos/eth/header'
|
2
3
|
require 'packetfu/protos/eth/mixin'
|
3
4
|
|
@@ -6,109 +7,109 @@ require 'packetfu/protos/arp/mixin'
|
|
6
7
|
|
7
8
|
module PacketFu
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
# ARPPacket is used to construct ARP packets. They contain an EthHeader and an ARPHeader.
|
11
|
+
# == Example
|
12
|
+
#
|
12
13
|
# require 'packetfu'
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
# arp_pkt = PacketFu::ARPPacket.new(:flavor => "Windows")
|
15
|
+
# arp_pkt.arp_saddr_mac="00:1c:23:44:55:66" # Your hardware address
|
16
|
+
# arp_pkt.arp_saddr_ip="10.10.10.17" # Your IP address
|
17
|
+
# arp_pkt.arp_daddr_ip="10.10.10.1" # Target IP address
|
18
|
+
# arp_pkt.arp_opcode=1 # Request
|
19
|
+
#
|
20
|
+
# arp_pkt.to_w('eth0') # Inject on the wire. (requires root)
|
20
21
|
# arp_pkt.to_f('/tmp/arp.pcap') # Write to a file.
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
22
|
+
#
|
23
|
+
# == Parameters
|
24
|
+
#
|
25
|
+
# :flavor
|
26
|
+
# Sets the "flavor" of the ARP packet. Choices are currently:
|
27
|
+
# :windows, :linux, :hp_deskjet
|
28
|
+
# :eth
|
29
|
+
# A pre-generated EthHeader object. If not specified, a new one will be created.
|
30
|
+
# :arp
|
31
|
+
# A pre-generated ARPHeader object. If not specificed, a new one will be created.
|
32
|
+
# :config
|
33
|
+
# A hash of return address details, often the output of Utils.whoami?
|
34
|
+
class ARPPacket < Packet
|
34
35
|
include ::PacketFu::EthHeaderMixin
|
35
36
|
include ::PacketFu::ARPHeaderMixin
|
36
37
|
|
37
|
-
|
38
|
+
attr_accessor :eth_header, :arp_header
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
def self.can_parse?(str)
|
41
|
+
return false unless EthPacket.can_parse? str
|
42
|
+
return false unless str.size >= 28
|
43
|
+
return false unless str[12,2] == "\x08\x06"
|
44
|
+
true
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
def read(str=nil,args={})
|
48
|
+
raise "Cannot parse `#{str}'" unless self.class.can_parse?(str)
|
49
|
+
@eth_header.read(str)
|
50
|
+
super(args)
|
51
|
+
self
|
52
|
+
end
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
def initialize(args={})
|
55
|
+
@eth_header = EthHeader.new(args).read(args[:eth])
|
56
|
+
@arp_header = ARPHeader.new(args).read(args[:arp])
|
57
|
+
@eth_header.eth_proto = "\x08\x06"
|
58
|
+
@eth_header.body=@arp_header
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
60
|
+
# Please send more flavors to todb+packetfu@planb-security.net.
|
61
|
+
# Most of these initial fingerprints come from one (1) sample.
|
62
|
+
case (args[:flavor].nil?) ? :nil : args[:flavor].to_s.downcase.intern
|
63
|
+
when :windows; @arp_header.body = "\x00" * 64 # 64 bytes of padding
|
64
|
+
when :linux; @arp_header.body = "\x00" * 4 + # 32 bytes of padding
|
65
|
+
"\x00\x07\x5c\x14" + "\x00" * 4 +
|
66
|
+
"\x00\x0f\x83\x34" + "\x00\x0f\x83\x74" +
|
67
|
+
"\x01\x11\x83\x78" + "\x00\x00\x00\x0c" +
|
68
|
+
"\x00\x00\x00\x00"
|
69
|
+
when :hp_deskjet; # Pads up to 60 bytes.
|
70
|
+
@arp_header.body = "\xe0\x90\x0d\x6c" +
|
71
|
+
"\xff\xff\xee\xee" + "\x00" * 4 +
|
72
|
+
"\xe0\x8f\xfa\x18\x00\x20"
|
73
|
+
else; @arp_header.body = "\x00" * 18 # Pads up to 60 bytes.
|
74
|
+
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
76
|
+
@headers = [@eth_header, @arp_header]
|
77
|
+
super
|
78
|
+
end
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
80
|
+
# Generates summary data for ARP packets.
|
81
|
+
def peek_format
|
82
|
+
peek_data = ["A "]
|
83
|
+
peek_data << "%-5d" % self.to_s.size
|
84
|
+
peek_data << arp_saddr_mac
|
85
|
+
peek_data << "(#{arp_saddr_ip})"
|
86
|
+
peek_data << "->"
|
87
|
+
peek_data << case arp_daddr_mac
|
88
|
+
when "00:00:00:00:00:00"; "Bcast00"
|
89
|
+
when "ff:ff:ff:ff:ff:ff"; "BcastFF"
|
90
|
+
else; arp_daddr_mac
|
91
|
+
end
|
92
|
+
peek_data << "(#{arp_daddr_ip})"
|
93
|
+
peek_data << ":"
|
94
|
+
peek_data << case arp_opcode
|
95
|
+
when 1; "Requ"
|
96
|
+
when 2; "Repl"
|
97
|
+
when 3; "RReq"
|
98
|
+
when 4; "RRpl"
|
99
|
+
when 5; "IReq"
|
100
|
+
when 6; "IRpl"
|
101
|
+
else; "0x%02x" % arp_opcode
|
102
|
+
end
|
103
|
+
peek_data.join
|
104
|
+
end
|
104
105
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
106
|
+
# While there are lengths in ARPPackets, there's not
|
107
|
+
# much to do with them.
|
108
|
+
def recalc(args={})
|
109
|
+
@headers[0].inspect
|
110
|
+
end
|
110
111
|
|
111
|
-
|
112
|
+
end
|
112
113
|
|
113
114
|
end
|
114
115
|
|
@@ -1,160 +1,161 @@
|
|
1
|
+
# -*- coding: binary -*-
|
1
2
|
module PacketFu
|
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
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
3
|
+
# ARPHeader is a complete ARP struct, used in ARPPacket.
|
4
|
+
#
|
5
|
+
# ARP is used to discover the machine address of nearby devices.
|
6
|
+
#
|
7
|
+
# See http://www.networksorcery.com/enp/protocol/arp.htm for details.
|
8
|
+
#
|
9
|
+
# ==== Header Definition
|
10
|
+
#
|
11
|
+
# Int16 :arp_hw Default: 1 # Ethernet
|
12
|
+
# Int16 :arp_proto, Default: 0x8000 # IP
|
13
|
+
# Int8 :arp_hw_len, Default: 6
|
14
|
+
# Int8 :arp_proto_len, Default: 4
|
15
|
+
# Int16 :arp_opcode, Default: 1 # 1: Request, 2: Reply, 3: Request-Reverse, 4: Reply-Reverse
|
16
|
+
# EthMac :arp_src_mac # From eth.rb
|
17
|
+
# Octets :arp_src_ip # From ip.rb
|
18
|
+
# EthMac :arp_dst_mac # From eth.rb
|
19
|
+
# Octets :arp_dst_ip # From ip.rb
|
20
|
+
# String :body
|
21
|
+
class ARPHeader < Struct.new(:arp_hw, :arp_proto, :arp_hw_len,
|
22
|
+
:arp_proto_len, :arp_opcode,
|
23
|
+
:arp_src_mac, :arp_src_ip,
|
24
|
+
:arp_dst_mac, :arp_dst_ip,
|
25
|
+
:body)
|
26
|
+
include StructFu
|
27
|
+
|
28
|
+
def initialize(args={})
|
29
|
+
src_mac = args[:arp_src_mac] || (args[:config][:eth_src] if args[:config])
|
30
|
+
src_ip_bin = args[:arp_src_ip] || (args[:config][:ip_src_bin] if args[:config])
|
31
|
+
|
32
|
+
super(
|
33
|
+
Int16.new(args[:arp_hw] || 1),
|
34
|
+
Int16.new(args[:arp_proto] ||0x0800),
|
35
|
+
Int8.new(args[:arp_hw_len] || 6),
|
36
|
+
Int8.new(args[:arp_proto_len] || 4),
|
37
|
+
Int16.new(args[:arp_opcode] || 1),
|
38
|
+
EthMac.new.read(src_mac),
|
39
|
+
Octets.new.read(src_ip_bin),
|
40
|
+
EthMac.new.read(args[:arp_dst_mac]),
|
41
|
+
Octets.new.read(args[:arp_dst_ip]),
|
42
|
+
StructFu::String.new.read(args[:body])
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the object in string form.
|
47
|
+
def to_s
|
48
|
+
self.to_a.map {|x| x.to_s}.join
|
49
|
+
end
|
50
|
+
|
51
|
+
# Reads a string to populate the object.
|
52
|
+
def read(str)
|
53
|
+
force_binary(str)
|
54
|
+
return self if str.nil?
|
55
|
+
self[:arp_hw].read(str[0,2])
|
56
|
+
self[:arp_proto].read(str[2,2])
|
57
|
+
self[:arp_hw_len].read(str[4,1])
|
58
|
+
self[:arp_proto_len].read(str[5,1])
|
59
|
+
self[:arp_opcode].read(str[6,2])
|
60
|
+
self[:arp_src_mac].read(str[8,6])
|
61
|
+
self[:arp_src_ip].read(str[14,4])
|
62
|
+
self[:arp_dst_mac].read(str[18,6])
|
63
|
+
self[:arp_dst_ip].read(str[24,4])
|
64
|
+
self[:body].read(str[28,str.size])
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
# Setter for the ARP hardware type.
|
69
|
+
def arp_hw=(i); typecast i; end
|
70
|
+
# Getter for the ARP hardware type.
|
71
|
+
def arp_hw; self[:arp_hw].to_i; end
|
72
|
+
# Setter for the ARP protocol.
|
73
|
+
def arp_proto=(i); typecast i; end
|
74
|
+
# Getter for the ARP protocol.
|
75
|
+
def arp_proto; self[:arp_proto].to_i; end
|
76
|
+
# Setter for the ARP hardware type length.
|
77
|
+
def arp_hw_len=(i); typecast i; end
|
78
|
+
# Getter for the ARP hardware type length.
|
79
|
+
def arp_hw_len; self[:arp_hw_len].to_i; end
|
80
|
+
# Setter for the ARP protocol length.
|
81
|
+
def arp_proto_len=(i); typecast i; end
|
82
|
+
# Getter for the ARP protocol length.
|
83
|
+
def arp_proto_len; self[:arp_proto_len].to_i; end
|
84
|
+
# Setter for the ARP opcode.
|
85
|
+
def arp_opcode=(i); typecast i; end
|
86
|
+
# Getter for the ARP opcode.
|
87
|
+
def arp_opcode; self[:arp_opcode].to_i; end
|
88
|
+
# Setter for the ARP source MAC address.
|
89
|
+
def arp_src_mac=(i); typecast i; end
|
90
|
+
# Getter for the ARP source MAC address.
|
91
|
+
def arp_src_mac; self[:arp_src_mac].to_s; end
|
92
|
+
# Getter for the ARP source IP address.
|
93
|
+
def arp_src_ip=(i); typecast i; end
|
94
|
+
# Setter for the ARP source IP address.
|
95
|
+
def arp_src_ip; self[:arp_src_ip].to_s; end
|
96
|
+
# Setter for the ARP destination MAC address.
|
97
|
+
def arp_dst_mac=(i); typecast i; end
|
98
|
+
# Setter for the ARP destination MAC address.
|
99
|
+
def arp_dst_mac; self[:arp_dst_mac].to_s; end
|
100
|
+
# Setter for the ARP destination IP address.
|
101
|
+
def arp_dst_ip=(i); typecast i; end
|
102
|
+
# Getter for the ARP destination IP address.
|
103
|
+
def arp_dst_ip; self[:arp_dst_ip].to_s; end
|
104
|
+
|
105
|
+
# Set the source MAC address in a more readable way.
|
106
|
+
def arp_saddr_mac=(mac)
|
107
|
+
mac = EthHeader.mac2str(mac)
|
108
|
+
self[:arp_src_mac].read(mac)
|
109
|
+
self.arp_src_mac
|
110
|
+
end
|
111
|
+
|
112
|
+
# Get a more readable source MAC address.
|
113
|
+
def arp_saddr_mac
|
114
|
+
EthHeader.str2mac(self[:arp_src_mac].to_s)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Set the destination MAC address in a more readable way.
|
118
|
+
def arp_daddr_mac=(mac)
|
119
|
+
mac = EthHeader.mac2str(mac)
|
120
|
+
self[:arp_dst_mac].read(mac)
|
121
|
+
self.arp_dst_mac
|
122
|
+
end
|
123
|
+
|
124
|
+
# Get a more readable source MAC address.
|
125
|
+
def arp_daddr_mac
|
126
|
+
EthHeader.str2mac(self[:arp_dst_mac].to_s)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Set a more readable source IP address.
|
130
|
+
def arp_saddr_ip=(addr)
|
131
|
+
self[:arp_src_ip].read_quad(addr)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Get a more readable source IP address.
|
135
|
+
def arp_saddr_ip
|
136
|
+
self[:arp_src_ip].to_x
|
137
|
+
end
|
138
|
+
|
139
|
+
# Set a more readable destination IP address.
|
140
|
+
def arp_daddr_ip=(addr)
|
141
|
+
self[:arp_dst_ip].read_quad(addr)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Get a more readable destination IP address.
|
145
|
+
def arp_daddr_ip
|
146
|
+
self[:arp_dst_ip].to_x
|
147
|
+
end
|
148
|
+
|
149
|
+
# Readability aliases
|
150
|
+
|
151
|
+
alias :arp_src_mac_readable :arp_saddr_mac
|
152
|
+
alias :arp_dst_mac_readable :arp_daddr_mac
|
153
|
+
alias :arp_src_ip_readable :arp_saddr_ip
|
154
|
+
alias :arp_dst_ip_readable :arp_daddr_ip
|
155
|
+
|
156
|
+
def arp_proto_readable
|
157
|
+
"0x%04x" % arp_proto
|
158
|
+
end
|
159
|
+
|
160
|
+
end # class ARPHeader
|
160
161
|
end
|