packetfu 1.0.0

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.
Files changed (52) hide show
  1. data/.document +4 -0
  2. data/CHANGES +36 -0
  3. data/INSTALL +40 -0
  4. data/LICENSE +28 -0
  5. data/README +25 -0
  6. data/TODO +25 -0
  7. data/examples/ackscan.rb +38 -0
  8. data/examples/arp.rb +60 -0
  9. data/examples/arphood.rb +56 -0
  10. data/examples/ethernet.rb +10 -0
  11. data/examples/examples.rb +3 -0
  12. data/examples/ids.rb +4 -0
  13. data/examples/idsv2.rb +6 -0
  14. data/examples/oui.txt +84177 -0
  15. data/examples/packetfu-shell.rb +111 -0
  16. data/examples/simple-stats.rb +42 -0
  17. data/examples/slammer.rb +33 -0
  18. data/examples/uniqpcap.rb +15 -0
  19. data/lib/packetfu.rb +108 -0
  20. data/lib/packetfu/arp.rb +239 -0
  21. data/lib/packetfu/capture.rb +169 -0
  22. data/lib/packetfu/config.rb +55 -0
  23. data/lib/packetfu/eth.rb +264 -0
  24. data/lib/packetfu/icmp.rb +153 -0
  25. data/lib/packetfu/inject.rb +65 -0
  26. data/lib/packetfu/invalid.rb +41 -0
  27. data/lib/packetfu/ip.rb +318 -0
  28. data/lib/packetfu/ipv6.rb +230 -0
  29. data/lib/packetfu/packet.rb +492 -0
  30. data/lib/packetfu/pcap.rb +502 -0
  31. data/lib/packetfu/structfu.rb +274 -0
  32. data/lib/packetfu/tcp.rb +1061 -0
  33. data/lib/packetfu/udp.rb +210 -0
  34. data/lib/packetfu/utils.rb +182 -0
  35. data/test/all_tests.rb +37 -0
  36. data/test/ptest.rb +10 -0
  37. data/test/sample.pcap +0 -0
  38. data/test/sample2.pcap +0 -0
  39. data/test/test_arp.rb +135 -0
  40. data/test/test_eth.rb +90 -0
  41. data/test/test_icmp.rb +54 -0
  42. data/test/test_inject.rb +33 -0
  43. data/test/test_invalid.rb +28 -0
  44. data/test/test_ip.rb +69 -0
  45. data/test/test_ip6.rb +68 -0
  46. data/test/test_octets.rb +37 -0
  47. data/test/test_packet.rb +41 -0
  48. data/test/test_pcap.rb +210 -0
  49. data/test/test_structfu.rb +112 -0
  50. data/test/test_tcp.rb +327 -0
  51. data/test/test_udp.rb +73 -0
  52. metadata +144 -0
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ $: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
4
+ require 'packetfu'
5
+
6
+ # Whee unit testing.
7
+ class IntStringTest < Test::Unit::TestCase
8
+ include StructFu
9
+
10
+ def test_intstring_len
11
+ s = IntString.new("hello!", Int32)
12
+ assert_equal(s.len, s.int.v)
13
+ assert_not_equal(s.len, s.length)
14
+ s.len=10
15
+ assert_equal(s.len, s[:int][:value])
16
+ end
17
+
18
+ def test_intstring_to_s
19
+ s = IntString.new("hello!", Int16)
20
+ assert_equal("\x00\x06hello!",s.to_s)
21
+ s.len=10
22
+ assert_equal("\x00\x0ahello!",s.to_s)
23
+ s = IntString.new("hello!", Int16, :parse)
24
+ s.len=10
25
+ assert_equal("\x00\x0ahello!\x00\x00\x00\x00",s.to_s)
26
+ s = IntString.new("hello!", Int16, :fix)
27
+ s.len=10
28
+ assert_equal("\x00\x06hello!",s.to_s)
29
+ end
30
+
31
+ def test_intstring_new
32
+ assert_equal("\x06Hello!",IntString.new("Hello!").to_s)
33
+ assert_equal("\x00\x06Hello!",IntString.new("Hello!",Int16).to_s)
34
+ assert_equal("\x06\x00\x00\x00Hello!",IntString.new("Hello!",Int32le).to_s)
35
+ end
36
+
37
+ def test_intstring_read
38
+ s = IntString.new
39
+ s.read("\x06Hello!")
40
+ assert_equal("Hello!", s.string)
41
+ assert_equal("Hello!", s[:string])
42
+ assert_equal(6, s.int.value)
43
+ assert_equal(6, s.len)
44
+ end
45
+
46
+ def test_intstring_parse
47
+ s = IntString.new
48
+ s[:mode] = :parse
49
+ s.parse("\x02Hello!")
50
+ assert_equal("He", s.string)
51
+ assert_equal(2, s.int.v)
52
+ s.parse("\x0aHello!")
53
+ assert_equal("Hello!\x00\x00\x00\x00", s.string)
54
+ s[:mode] = :fix
55
+ s.parse("\x0aHello!")
56
+ assert_equal("Hello!", s.string)
57
+ end
58
+
59
+ def test_intstring_nocalc
60
+ s = IntString.new
61
+ s[:string] = "Hello"
62
+ assert_equal(0,s.int.value)
63
+ end
64
+
65
+ end
66
+
67
+ class IntTest < Test::Unit::TestCase
68
+ include StructFu
69
+
70
+ def test_int_to_s
71
+ assert_equal("\x02",Int8.new(2).to_s)
72
+ assert_equal("\x00\x07",Int16.new(7).to_s)
73
+ assert_equal("\x00\x00\x00\x0a",Int32.new(10).to_s)
74
+ end
75
+
76
+ def test_int_big
77
+ assert_equal("\x00\x07",Int16be.new(7).to_s)
78
+ assert_equal("\x00\x00\x00\x0a",Int32be.new(10).to_s)
79
+ end
80
+
81
+ def test_int_little
82
+ assert_equal("\x07\x00",Int16le.new(7).to_s)
83
+ assert_equal("\x01\x04\x00\x00",Int32le.new(1025).to_s)
84
+ end
85
+
86
+ def test_read
87
+ assert_equal(7,Int16.new.read("\x00\x07").to_i)
88
+ assert_equal(Int32.new.read("\x00\x00\x00\x0a").to_i,10)
89
+ i = Int32.new
90
+ i.read("\x00\x00\x00\xff")
91
+ assert_equal(i.v, 255)
92
+ assert_equal(7, Int16le.new.read("\x07\x00").to_i)
93
+ assert_equal(1025,Int32le.new.read("\x01\x04\x00\x00").to_i)
94
+ i = Int32le.new
95
+ i.read("\xff\x00\x00\x00")
96
+ assert_equal(i.v, 255)
97
+ end
98
+
99
+ def test_int_compare
100
+ little = Int32le.new
101
+ big = Int32be.new
102
+ little.v = 128
103
+ big.v = 0x80
104
+ assert_not_equal(little.to_s, big.to_s)
105
+ assert_equal(little.v, big.v)
106
+ assert_equal(little[:value], big[:value])
107
+ assert_equal(little.value, big.value)
108
+ end
109
+
110
+ end
111
+
112
+ # vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
@@ -0,0 +1,327 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ $: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
4
+ require 'packetfu'
5
+
6
+ class String
7
+ def bin
8
+ self.scan(/../).map {|x| x.to_i(16).chr}.join
9
+ end
10
+ end
11
+
12
+ class TcpEcnTest < Test::Unit::TestCase
13
+ include PacketFu
14
+
15
+ def test_ecn_set
16
+ t = TcpEcn.new
17
+ assert_kind_of TcpEcn, t
18
+ assert_equal(0, t.to_i)
19
+ t.n = 1
20
+ assert_equal(4, t.to_i)
21
+ t.c = 1
22
+ assert_equal(6, t.to_i)
23
+ t.e = 1
24
+ assert_equal(7, t.to_i)
25
+ end
26
+
27
+ def test_ecn_read
28
+ t = TcpEcn.new
29
+ assert_kind_of TcpEcn, t
30
+ t.read("\x30\xc0")
31
+ assert_equal(0, t.n)
32
+ assert_equal(1, t.c)
33
+ assert_equal(1, t.e)
34
+ t.read("\xa3\x38")
35
+ assert_equal(1, t.n)
36
+ assert_equal(0, t.c)
37
+ assert_equal(0, t.e)
38
+ end
39
+
40
+ def test_hlen_set
41
+ t = TcpHlen.new
42
+ assert_kind_of TcpHlen, t
43
+ assert_equal(0, t.to_i)
44
+ t.hlen = 10
45
+ assert_equal(10, t.to_i)
46
+ end
47
+
48
+ def test_hlen_read
49
+ t = TcpHlen.new
50
+ t.read("\xa0")
51
+ assert_equal(10, t.to_i)
52
+ end
53
+
54
+ def test_reserved_set
55
+ t = TcpReserved.new
56
+ assert_kind_of TcpReserved, t
57
+ assert_equal(0, t.to_i)
58
+ t.r1 = 1
59
+ assert_equal(4, t.to_i)
60
+ t.r2 = 1
61
+ assert_equal(6, t.to_i)
62
+ t.r3 = 1
63
+ assert_equal(7, t.to_i)
64
+ end
65
+
66
+ def test_reserved_read
67
+ t = TcpReserved.new
68
+ t.read("\xa0")
69
+ assert_equal(0, t.to_i)
70
+ end
71
+
72
+ end
73
+
74
+ class TcpFlagsTest < Test::Unit::TestCase
75
+ include PacketFu
76
+
77
+ def test_tcp_flags_set
78
+ t = TcpFlags.new
79
+ assert_kind_of TcpFlags, t
80
+ t.fin = 1
81
+ t.ack = 1
82
+ assert_equal(0x11, t.to_i)
83
+ t.fin = 0
84
+ t.syn = 1
85
+ assert_equal(0x12, t.to_i)
86
+ end
87
+
88
+ def test_tcp_flags_read
89
+ t = TcpFlags.new
90
+ t.read("\x11")
91
+ assert_equal(1, t.fin)
92
+ assert_equal(1, t.ack)
93
+ t.read("\xa6")
94
+ assert_equal(1, t.urg)
95
+ assert_equal(1, t.rst)
96
+ assert_equal(1, t.syn)
97
+ assert_equal(0, t.psh)
98
+ assert_equal(0, t.ack)
99
+ assert_equal(0, t.fin)
100
+ end
101
+
102
+ end
103
+
104
+ class TcpOptionsTest < Test::Unit::TestCase
105
+ include PacketFu
106
+
107
+ def test_tcp_option
108
+ t = TcpOption.new
109
+ assert_equal("\x00", t.to_s)
110
+ t = TcpOption.new(:kind => 2, :optlen => 4, :value => 1024)
111
+ assert_equal("\x02\x04\x04\x00", t.to_s)
112
+ t = TcpOption.new(:kind => 0xf0, :optlen => 6, :value => 1024)
113
+ assert_equal("\xf0\x06\x00\x00\x04\x00", t.to_s)
114
+ t = TcpOption.new(:kind => 0xf0, :optlen => 6, :value => "1024")
115
+ assert_equal("\xf0\x061024", t.to_s)
116
+ t = TcpOption.new(:kind => 0xf0, :optlen => 6, :value => nil)
117
+ assert_equal("\xf0\x06", t.to_s)
118
+ t = TcpOption.new(:kind => 0xf1, :optlen => 10, :value => "a1b2c3d4e5")
119
+ assert_equal("\xf1\x0aa1b2c3d4e5", t.to_s)
120
+ end
121
+
122
+ def test_eol
123
+ t = TcpOption::EOL.new
124
+ assert_equal("\x00", t.to_s)
125
+ assert_equal(0, t.kind.to_i)
126
+ assert_equal(0, t.kind.value)
127
+ assert_equal(nil, t.optlen.value)
128
+ assert_equal("", t.value)
129
+ assert_equal("EOL",t.decode)
130
+ end
131
+
132
+ def test_nop
133
+ t = TcpOption::NOP.new
134
+ assert_equal("\x01", t.to_s)
135
+ assert_equal("NOP",t.decode)
136
+ end
137
+
138
+ def test_mss
139
+ t = TcpOption::MSS.new
140
+ t.read("\x02\x04\x05\xb4")
141
+ assert_equal("MSS:1460",t.decode)
142
+ t = TcpOption::MSS.new(:value => 1460)
143
+ assert_equal("\x02\x04\x05\xb4", t.to_s)
144
+ assert_equal("MSS:1460",t.decode)
145
+ end
146
+
147
+ def test_sack
148
+ t = TcpOption::SACKOK.new
149
+ assert_equal("\x04\x02", t.to_s)
150
+ assert_equal("SACKOK",t.decode)
151
+ end
152
+
153
+ def test_sackok
154
+ t = TcpOption::SACK.new
155
+ assert_equal("\x05\x02", t.to_s)
156
+ assert_equal("SACK:",t.decode)
157
+ t = TcpOption::SACK.new(:value => "ABCD")
158
+ assert_equal("\x05\x06\x41\x42\x43\x44", t.to_s)
159
+ assert_equal("SACK:ABCD",t.decode)
160
+ t = TcpOptions.new
161
+ t.encode("SACK:ABCD,NOP,NOP") # Testing the variable optlen
162
+ assert_equal("SACK:ABCD,NOP,NOP",t.decode)
163
+ end
164
+
165
+ def test_echo
166
+ t = TcpOption::ECHO.new(:value => "ABCD")
167
+ assert_equal("\x06\x06\x41\x42\x43\x44", t.to_s)
168
+ assert_equal("ECHO:ABCD",t.decode)
169
+ t = TcpOption::ECHO.new
170
+ t.read("\x06\x06\x41\x42\x43\x44")
171
+ assert_equal("ECHO:ABCD",t.decode)
172
+ end
173
+
174
+ def test_echoreply
175
+ t = TcpOption::ECHOREPLY.new(:value => "ABCD")
176
+ assert_equal("\x07\x06\x41\x42\x43\x44", t.to_s)
177
+ assert_equal("ECHOREPLY:ABCD",t.decode)
178
+ t = TcpOption::ECHOREPLY.new
179
+ t.read("\x07\x06\x41\x42\x43\x44")
180
+ assert_equal("ECHOREPLY:ABCD",t.decode)
181
+ end
182
+
183
+ def test_tsopt
184
+ t = TcpOption::TS.new
185
+ assert_equal("\x08\x0a\x00\x00\x00\x00\x00\x00\x00\x00", t.to_s)
186
+ assert_equal("TS:0;0",t.decode)
187
+ end
188
+
189
+ def test_tcpoptions
190
+ opt_string = "0101080a002af12c12ef0d57".bin
191
+ t = TcpOptions.new
192
+ t.read opt_string
193
+ assert_equal("NOP,NOP,TS:2814252;317656407", t.decode)
194
+ assert_equal(opt_string, t.to_s)
195
+ opt_string = "020405b40402080a002af1120000000001030306".bin
196
+ t = TcpOptions.new
197
+ t.read opt_string
198
+ assert_equal("MSS:1460,SACKOK,TS:2814226;0,NOP,WS:6", t.decode)
199
+ end
200
+
201
+ def test_tcpoptions_encode
202
+ opt_string = "mss:1460,sackok,ts:2814226;0,nop,ws:6"
203
+ t = TcpOptions.new
204
+ t.encode opt_string
205
+ assert_equal(opt_string.upcase, t.decode)
206
+ assert_kind_of(StructFu::Int8,t[0].kind)
207
+ assert_kind_of(StructFu::Int8,t[0].optlen)
208
+ assert_kind_of(StructFu::Int16,t[0].value)
209
+ assert_equal("\x02\x04\x05\xb4", t[0].to_s)
210
+ assert_equal("\x08\x0a\x00\x2a\xf1\x12\x00\x00\x00\x00", t[2].to_s)
211
+ end
212
+
213
+ end
214
+
215
+ class TcpHeaderTest < Test::Unit::TestCase
216
+ include PacketFu
217
+
218
+ def test_header_new
219
+ t = TCPHeader.new
220
+ assert_kind_of TCPHeader, t
221
+ assert_equal 20, t.sz
222
+ assert_equal 13, t.size
223
+ end
224
+
225
+ def test_header_read
226
+ t = TCPHeader.new
227
+ str = "da920050c9fd6d2b2f54cc2f8018005c74de00000101080a002af11e12ef0d4a".bin
228
+ str << "474554202f20485454502f312e310d0a557365722d4167656e743a206375726c2f372e31382e322028693438362d70632d6c696e75782d676e7529206c69626375726c2f372e31382e32204f70656e53534c2f302e392e3867207a6c69622f312e322e332e33206c696269646e2f312e31300d0a486f73743a207777772e706c616e622d73656375726974792e6e65740d0a4163636570743a202a2f2a0d0a0d0a".bin
229
+ t.read str
230
+ assert_equal 55954, t.tcp_sport
231
+ assert_equal 80, t.tcp_dport
232
+ assert_equal 3388828971, t.tcp_seq
233
+ assert_equal 794086447, t.tcp_ack
234
+ assert_equal 8, t.tcp_hlen
235
+ assert_equal 0, t.tcp_reserved
236
+ assert_equal 0, t.tcp_ecn
237
+ assert_equal 1, t.tcp_flags.psh
238
+ assert_equal 1, t.tcp_flags.ack
239
+ assert_equal 0, t.tcp_flags.syn
240
+ assert_equal 92, t.tcp_win
241
+ assert_equal 0x74de, t.tcp_sum
242
+ assert_equal "NOP,NOP,TS:2814238;317656394", t.tcp_options
243
+ assert_equal "GET /", t.body[0,5]
244
+ assert_equal "*\x0d\x0a\x0d\x0a", t.body[-5,5]
245
+ end
246
+
247
+ end
248
+
249
+ class TCPPacketTest < Test::Unit::TestCase
250
+ include PacketFu
251
+
252
+ def test_tcp_peek
253
+ t = TCPPacket.new
254
+ t.ip_saddr = "10.20.30.40"
255
+ t.ip_daddr = "50.60.70.80"
256
+ t.tcp_src = 55954
257
+ t.tcp_dport = 80
258
+ t.tcp_flags.syn = 1
259
+ t.tcp_flags.ack = true
260
+ t.payload = "GET / HTTP/1.1\x0d\x0aHost: 50.60.70.80\x0d\x0a\x0d\x0a"
261
+ t.recalc
262
+ puts "\n"
263
+ puts "TCP Peek format: "
264
+ puts t.peek
265
+ assert_equal 78,t.peek.size
266
+ end
267
+
268
+ def test_tcp_pcap
269
+ t = TCPPacket.new
270
+ assert_kind_of TCPPacket, t
271
+ t.recalc
272
+ t.to_f('tcp_test.pcap','a')
273
+ t.recalc
274
+ #t.to_f('tcp_test.pcap','a')
275
+ t.ip_saddr = "10.20.30.40"
276
+ t.ip_daddr = "50.60.70.80"
277
+ t.payload = "+some fakey-fake tcp packet"
278
+ t.tcp_sport = 1206
279
+ t.tcp_dst = 13013
280
+ t.tcp_flags.syn = 1
281
+ t.tcp_flags.ack = true
282
+ t.tcp_flags.psh = false
283
+ t.recalc
284
+ #t.to_f('tcp_test.pcap','a')
285
+ end
286
+
287
+ def test_tcp_read
288
+ sample_packet = PcapFile.new.file_to_array(:f => 'sample.pcap')[7]
289
+ pkt = Packet.parse(sample_packet)
290
+ assert_kind_of TCPPacket, pkt
291
+ assert_equal(0x5a73, pkt.tcp_sum)
292
+ pkt.to_f('tcp_test.pcap','a')
293
+ end
294
+
295
+ def test_tcp_alter
296
+ sample_packet = PcapFile.new.file_to_array(:f => 'sample2.pcap')[3]
297
+ pkt = Packet.parse(sample_packet)
298
+ assert_kind_of TCPPacket, pkt
299
+ pkt.tcp_sport = 13013
300
+ pkt.payload = pkt.payload.gsub(/planb/,"brandx")
301
+ pkt.recalc
302
+ pkt.to_f('tcp_test.pcap','a')
303
+ end
304
+
305
+ end
306
+
307
+ class TCPPacketTest < Test::Unit::TestCase
308
+ include PacketFu
309
+
310
+ def test_tcp_edit_opts
311
+ t = TCPPacket.new
312
+ assert_equal(0, t.tcp_options.size)
313
+ assert_equal(0, t.tcp_opts_len)
314
+ assert_equal(5, t.tcp_hlen)
315
+ t.tcp_options = "NOP,NOP,NOP,NOP"
316
+ assert_equal(4, t.tcp_opts_len)
317
+ t.recalc
318
+ assert_equal(6, t.tcp_hlen)
319
+ end
320
+
321
+ end
322
+
323
+
324
+
325
+
326
+
327
+ # vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ $: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
4
+ require 'packetfu'
5
+
6
+ class UDPTest < Test::Unit::TestCase
7
+ include PacketFu
8
+
9
+ def test_udp_header_new
10
+ u = UDPHeader.new
11
+ assert_kind_of UDPHeader, u
12
+ assert_equal(8, u.to_s.size)
13
+ assert_equal("\x00\x00\x00\x00\x00\x08\x00\x00", u.to_s)
14
+ end
15
+
16
+ def test_udp_peek
17
+ u = UDPPacket.new
18
+ u.ip_saddr = "10.20.30.40"
19
+ u.ip_daddr = "50.60.70.80"
20
+ u.udp_src = 53
21
+ u.udp_dport = 1305
22
+ u.payload = "abcdefghijklmnopqrstuvwxyz"
23
+ u.recalc
24
+ puts "\n"
25
+ puts "UDP Peek format: "
26
+ puts u.peek
27
+ assert_equal 78,u.peek.size
28
+ end
29
+
30
+ def test_udp_pcap
31
+ u = UDPPacket.new
32
+ assert_kind_of UDPPacket, u
33
+ u.recalc
34
+ u.to_f('udp_test.pcap','a')
35
+ u.ip_saddr = "10.20.30.40"
36
+ u.ip_daddr = "50.60.70.80"
37
+ u.payload = "+some fakey-fake udp packet"
38
+ u.udp_src = 1205
39
+ u.udp_dst = 13013
40
+ u.recalc
41
+ u.to_f('udp_test.pcap','a')
42
+ end
43
+
44
+ def test_udp_read
45
+ sample_packet = PcapFile.new.file_to_array(:f => 'sample.pcap')[0]
46
+ pkt = Packet.parse(sample_packet)
47
+ assert_kind_of UDPPacket, pkt
48
+ assert_equal(0x8bf8, pkt.udp_sum.to_i)
49
+ pkt.to_f('udp_test.pcap','a')
50
+ end
51
+
52
+ def test_udp_checksum
53
+ sample_packet = PcapFile.new.file_to_array(:f => 'sample.pcap')[0]
54
+ pkt = Packet.parse(sample_packet)
55
+ assert_kind_of UDPPacket, pkt
56
+ pkt.recalc
57
+ assert_equal(0x8bf8, pkt.udp_sum.to_i)
58
+ pkt.to_f('udp_test.pcap','a')
59
+ end
60
+
61
+ def test_udp_alter
62
+ sample_packet = PcapFile.new.file_to_array(:f => 'sample.pcap')[0]
63
+ pkt = Packet.parse(sample_packet)
64
+ assert_kind_of UDPPacket, pkt
65
+ pkt.payload = pkt.payload.gsub(/metasploit/,"MeatPistol")
66
+ pkt.recalc
67
+ assert_equal(0x8341, pkt.udp_sum)
68
+ pkt.to_f('udp_test.pcap','a')
69
+ end
70
+
71
+ end
72
+
73
+ # vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby