packetman 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d179b4712440f17879c705887caeec69fd857517
4
- data.tar.gz: 7879478eab7e6ecca5d75bff051a5dcad4006465
3
+ metadata.gz: d3819b6864ab2d131bcd29e65c79a02123a1d4b4
4
+ data.tar.gz: 7de18ca9f2f368755393dbc6c0d3b4edfb34a019
5
5
  SHA512:
6
- metadata.gz: 59f189ec8d961cc829938163d21daffea43b4ce14f5b0487d49339ad59abf6cbefabfbb5254e2b949132987ee06df4b584664d9e0d1f7973c33835c1328cd59a
7
- data.tar.gz: 4e6b9134085f93800d07dd8a5e218c48d1c25260832b837c4f2e4fc365545234589232e0af344b8e1687eb90f6aa93d91875a341cfcf1165c1bec3d2341fd3a5
6
+ metadata.gz: f70eb13025b20f23690c6d0b169bb165a7ea035597bd863a5bb1279711eb1f40f54fe393e0611715b980f460e5d899f2ddf92a8ce2806544d70f26d3cf0599e8
7
+ data.tar.gz: 3f2df4b4ee6be9f721195aa661b8ae91bf7aeccd77c8935fa6b51464c872e345206c103af7898342f102ddc55859ddb300642a5420b1e7831b24585f3b378dcb
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Advanced tcpdump and Wireshark capture generator.
4
4
 
5
- [![Code Climate](https://codeclimate.com/github/jescholl/packetman/badges/gpa.svg)](https://codeclimate.com/github/jescholl/packetman) [![Test Coverage](https://codeclimate.com/github/jescholl/packetman/badges/coverage.svg)](https://codeclimate.com/github/jescholl/packetman/coverage) [![Circle CI](https://circleci.com/gh/jescholl/packetman.svg?style=svg)](https://circleci.com/gh/jescholl/packetman)
5
+ [![Gem Version](https://badge.fury.io/rb/packetman.svg)](http://badge.fury.io/rb/packetman) [![Code Climate](https://codeclimate.com/github/jescholl/packetman/badges/gpa.svg)](https://codeclimate.com/github/jescholl/packetman) [![Test Coverage](https://codeclimate.com/github/jescholl/packetman/badges/coverage.svg)](https://codeclimate.com/github/jescholl/packetman/coverage) [![Circle CI](https://circleci.com/gh/jescholl/packetman.svg?style=svg)](https://circleci.com/gh/jescholl/packetman)
6
6
 
7
7
  Packetman is a packet capture filter generator modeled after [Wireshark's String-Matching Capture Filter Generator](https://www.wireshark.org/tools/string-cf.html) but with a lot more features allowing much finer control over the packets you see.
8
8
 
@@ -1,35 +1,29 @@
1
1
  ---
2
- transport:
3
- tcp:
4
- table:
5
- Source Port: 16
6
- Destination Port: 16
7
- Sequence Number: 32
8
- Acknowledgement Number: 32
9
- Data Offset: 4
10
- RESERVED: 3
11
- ECN: 3
12
- Control Bits: 6
13
- Window: 16
14
- Checksum: 16
15
- Urgent Pointer: 16
16
- Options and Padding: 32
17
- payload_query: '((tcp[12:1] & 0xf0) >> 2)'
18
- udp:
19
- table:
20
- Source Port: 16
21
- Destination Port: 16
22
- Length: 16
23
- Checksum: 16
24
- payload_query: 8
25
- icmp:
26
- table:
27
- Type: 8
28
- Code: 8
29
- Checksum: 16
30
- Type Specific Options: 32
31
- application:
32
- http:
33
- transport_protocol: tcp
34
- dns:
35
- transport_protocol: tcp
2
+ tcp:
3
+ table:
4
+ Source Port: 16
5
+ Destination Port: 16
6
+ Sequence Number: 32
7
+ Acknowledgement Number: 32
8
+ Data Offset: 4
9
+ RESERVED: 3
10
+ ECN: 3
11
+ Control Bits: 6
12
+ Window: 16
13
+ Checksum: 16
14
+ Urgent Pointer: 16
15
+ Options and Padding: 32
16
+ payload_query: '((tcp[12:1] & 0xf0) >> 2)'
17
+ udp:
18
+ table:
19
+ Source Port: 16
20
+ Destination Port: 16
21
+ Length: 16
22
+ Checksum: 16
23
+ payload_query: 8
24
+ icmp:
25
+ table:
26
+ Type: 8
27
+ Code: 8
28
+ Checksum: 16
29
+ Type Specific Options: 32
@@ -15,10 +15,5 @@ module Packetman
15
15
  def config!
16
16
  @config = Config.new
17
17
  end
18
-
19
- def user_input(prompt)
20
- puts prompt
21
- gets
22
- end
23
18
  end
24
19
  end
@@ -6,7 +6,7 @@ module Packetman
6
6
  @input = input
7
7
  @radix = radix
8
8
  end
9
-
9
+
10
10
  def desired_length
11
11
  ((@input.length + config.offset)/8.to_f).ceil*8 - config.offset
12
12
  end
@@ -15,7 +15,7 @@ module Packetman
15
15
  (radix.nil?) ? 8 : Math.log2(radix).to_i
16
16
  end
17
17
 
18
- def mask
18
+ def mask_bits
19
19
  shift(@input.scan(/./).map{ |c| mask_chr(c) }.join)
20
20
  end
21
21
 
@@ -27,7 +27,7 @@ module Packetman
27
27
  input.ljust(desired_length, '0')
28
28
  end
29
29
 
30
- def search
30
+ def search_bits
31
31
  shift(@input.scan(/./).map{ |c| bin_chr(c) }.join)
32
32
  end
33
33
 
@@ -54,20 +54,18 @@ module Packetman
54
54
  end
55
55
 
56
56
  def mask_hex
57
- hex_encode(mask)
57
+ hex_encode(mask_bits)
58
58
  end
59
59
 
60
60
  def search_hex
61
- hex_encode(search)
61
+ hex_encode(search_bits)
62
62
  end
63
63
 
64
64
  def hex_encode(bin_str)
65
- bin_str.reverse.scan(/.{1,4}/).map{ |chunk| chunk.reverse.to_i(2).to_s(16) }.reverse.join.scan(/.{1,8}/).map{ |hex| hex.prepend('0x') }
65
+ bin_str.reverse.scan(/.{1,4}/).map{ |chunk| chunk.reverse.to_i(2).to_s(16) }.reverse.join.scan(/.{8}|.{4}|.{2}/).map{ |hex| hex.prepend('0x') }
66
66
  end
67
67
 
68
- def full_bit_length(num, radix=nil)
69
- return num.to_i(radix).to_s(radix).length * bit_density(radix) if radix
70
-
68
+ def bit_length(num)
71
69
  case num
72
70
  when /^0x/
73
71
  $'.length * bit_density(16)
@@ -78,20 +76,18 @@ module Packetman
78
76
  end
79
77
  end
80
78
 
81
- def start_byte(position)
82
- "#{config.payload_query} + #{(config.offset + position)/8}"
79
+ def start_byte(bit_position)
80
+ [config.payload_query, (config.offset + bit_position)/8].compact.join(' + ')
83
81
  end
84
82
 
85
- def to_s
86
- clauses = []
87
- position = 0
88
- search_hex.zip(mask_hex).each_with_index do |(hex_search, hex_mask),i|
89
- search_bit_length = full_bit_length(hex_search)
90
- clauses << "#{config.transport}[#{start_byte(position)}:#{search_bit_length/8}] & #{hex_mask} = #{hex_search}"
91
- position += search_bit_length
92
- end
83
+ def data_address(start_bit, bit_length)
84
+ "#{config.transport}[#{start_byte(start_bit)}:#{bit_length/8}]"
85
+ end
93
86
 
94
- clauses.join(' && ')
87
+ def to_s
88
+ search_hex.zip(mask_hex).map.with_index do |(search, mask),i|
89
+ "#{data_address(i*32, bit_length(search))} & #{mask} = #{search}"
90
+ end.join(' && ')
95
91
  end
96
92
  end
97
93
  end
@@ -2,16 +2,12 @@ require 'optparse'
2
2
 
3
3
  module Packetman
4
4
  class Config
5
- attr_accessor :transport, :application, :offset_units, :offset_type, :allow_wildcards, :radix
5
+ attr_accessor :transport, :application, :use_bytes, :allow_wildcards, :radix, :start_with_transport
6
6
  attr_writer :offset
7
7
 
8
8
  def initialize
9
9
  @transport = "tcp"
10
- @application = "http"
11
10
  @offset = 0
12
- @offset_units = "bits"
13
- @offset_type = "application"
14
- @allow_wildcards = true
15
11
  end
16
12
 
17
13
  def protocols
@@ -19,17 +15,11 @@ module Packetman
19
15
  end
20
16
 
21
17
  def payload_query
22
- case offset_type
23
- when "application"
24
- protocols['transport'][transport.to_s]['payload_query']
25
- else
26
- "0"
27
- end
18
+ protocols[transport]['payload_query'] unless start_with_transport
28
19
  end
29
20
 
30
21
  def offset
31
- case offset_units
32
- when "bytes"
22
+ if use_bytes
33
23
  @offset*8
34
24
  else
35
25
  @offset
@@ -39,14 +29,13 @@ module Packetman
39
29
  def parse_opts
40
30
  @opts ||= OptionParser.new do |opt|
41
31
  opt.banner = "Usage: #{File.basename($PROGRAM_NAME)} [OPTIONS] FILTER_STRING"
42
- opt.on("-t", "--transport [PROTO]", protocols['transport'].keys, "Transport Protocol (#{protocols['transport'].keys.join(',')})") {|v| self.transport = v }
43
- opt.on("-a", "--application [PROTO]", protocols['application'].keys, "Application protocol (#{protocols['application'].keys.join(',')})") { |v| self.application = v }
44
- #opt.on("-a", "--application [PROTO]", String, "Application Protocol (http|dns|icmp)") {|v| self.application = v }
32
+ opt.on("-p", "--protocol [PROTO]", protocols.keys, "Transport Protocol (#{protocols.keys.join(',')})") {|v| self.transport = v }
33
+ opt.on("-t", "--transport", "OFFSET starts at transport header instead of data payload") { |v| self.start_with_transport = v }
45
34
  opt.on("-r", "--radix [RADIX]", Integer, "Treat FILTER_STRING as RADIX instead of String") {|v| self.radix = v; }
46
35
  opt.on("-o", "--offset [OFFSET]", Integer, "Offset in bits") {|v| self.offset = v; }
47
- opt.on("-b", "--byte-offset", "Use 8-bit bytes instead of bits for offset") { |v| self.offset_units = "bytes" }
48
- opt.on("-O", "--offset-type [TYPE]", ["application", "transport"], "Begin offset at the application/transport header.") { |v| self.offset_type = v }
49
- opt.on("--[no-]wildcards", "Allow '?' wildcards") { |v| self.allow_wildcards = v }
36
+ opt.on("-b", "--byte-offset", "Use 8-bit bytes instead of bits for offset") { |v| self.use_bytes = v }
37
+ opt.on("-w", "--wildcards", "Allow '?' wildcards") { |v| self.allow_wildcards = v }
38
+ opt.on("-v", "--version", "Show version") { puts Packetman::VERSION; exit }
50
39
  end
51
40
 
52
41
  @opts.parse!
@@ -54,17 +43,6 @@ module Packetman
54
43
  raise "Invalid command line arguments" if ARGV.size != 1
55
44
 
56
45
  ARGV.pop
57
-
58
-
59
- # if transport !~ /tcp|udp/i ||
60
- # application !~ /http|dns|icmp/i
61
- # raise "invalid options"
62
- # end
63
- #
64
- # if offset_units == :bits
65
- # offset /= 8.to_f
66
- # offset_units = :octets
67
- # end
68
46
  end
69
47
 
70
48
  end
@@ -7,5 +7,9 @@ module Packetman
7
7
  def config
8
8
  Packetman.config
9
9
  end
10
+
11
+ def protocols
12
+ config.protocols
13
+ end
10
14
  end
11
15
  end
@@ -44,7 +44,7 @@ module Packetman
44
44
  def to_s
45
45
  output = horizontal_bar + header_row + horizontal_bar
46
46
 
47
- config.protocols['transport'][config.transport]['table'].each do |label, size|
47
+ protocols[config.transport]['table'].each do |label, size|
48
48
  output += sprintf "%s%.#{cell_size(size)}s", line_v, label.center(cell_size(size))
49
49
  if output.split("\n").last.length == (table_width - 1)
50
50
  output += line_v + "\n"
@@ -1,3 +1,3 @@
1
1
  module Packetman
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: packetman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Scholl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-09-20 00:00:00.000000000 Z
11
+ date: 2015-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -110,7 +110,6 @@ files:
110
110
  - lib/packetman/table.rb
111
111
  - lib/packetman/version.rb
112
112
  - packetman.gemspec
113
- - packetman_notes
114
113
  homepage: https://github.com/jescholl/packetman
115
114
  licenses:
116
115
  - MIT
@@ -131,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
130
  version: '0'
132
131
  requirements: []
133
132
  rubyforge_project:
134
- rubygems_version: 2.4.5
133
+ rubygems_version: 2.4.5.1
135
134
  signing_key:
136
135
  specification_version: 4
137
136
  summary: Advanced tcpdump and Wiresharp filter generator.
@@ -1,156 +0,0 @@
1
- 7a
2
- 1111010
3
-
4
- #NOTE: I think this is wrong
5
- # also, maybe I don't need to worry about the bits bing aligned on the byte, just on the bit, as long as it's what the user asked for
6
-
7
- hex and string need to be 0 padded on the left
8
- binary needs to fill to the right to hex encode, starting at the offset bit
9
-
10
- Packetman.compose3("0b1111", 3)
11
- 1111
12
- (fill right to ((4+3)/8.to_f).ceil*8 = 8 )
13
- 11110000
14
- (shift mask and search >> 3)
15
- 00011110
16
- 00011110
17
- (sample byte sequence)
18
- 00011111
19
-
20
- Packetman.compose3("0b1111010", 3)
21
- 1111010
22
- (fill right to ((7+3)/8.to_f).ceil*8 = 16)
23
- 11110100 00000000
24
- (shift mask and search >> 3)
25
- 00011111 11000000
26
- 00011110 10000000
27
- (sample byte sequence)
28
- 00011110 10101010
29
-
30
-
31
- Packetman.compose3("0b1111010????????", 3)
32
- 1111010? ???????
33
- (fill right to ((15+3)/8.to_f).ceil*8 = 24)
34
- 1111010? ???????0 00000000
35
- (shift mask and search >> 3)
36
- 00011111 11000000 00000000
37
- 00011110 10000000 00000000
38
- (sample byte sequence)
39
- 00011110 10101010 10101010
40
-
41
- Packetman.compose3("0x123",3)
42
- 100100011
43
- (left fill to 12 first, or manual right fill with 16-12)
44
- (fill right to ((3*4)+3)/8.to_f).ceil*8 = 16)
45
- 00010010 00110000
46
- (shift mask and search >> 3)
47
- 00000011 11111110
48
- 00000010 01000110
49
- (sample byte sequence)
50
- 00000010 01000111
51
-
52
-
53
-
54
-
55
- Packetman.compose3("0xa",3)
56
- "((tcp[0:1] & 0xa) >> 1) = 0xa"
57
- 1010
58
- (generate shifted mask)
59
- 00011110
60
- (generate shifted search)
61
- 00010100
62
- (sample byte sequence)
63
- 10010101
64
-
65
- 0b00011110 & 0b10010101 == 0x14
66
-
67
-
68
-
69
-
70
-
71
-
72
- Packetman.compose3("0b001010010", 3)
73
- "((tcp[0:2] & 0x1ff0) >> 4 = 0x52"
74
- 001010010
75
- (generate shifted mask)
76
- (turn preceding 0s to 1s)
77
- (left shift (((binlen)+3)/8.to_f).ceil*8 - binlen - 3)
78
- 1111111110000
79
- (generate shifted search - same as above)
80
- 0010100100000
81
- (sample byte sequence)
82
- 0010100101010
83
-
84
- 0b0010100101010 & 1111111110000 == 0b0010100100000
85
-
86
-
87
- Packetman.compose3("0b00??1010?111?00010101??10101010?????1010111110???111110101001111010101??????????10100101010100011???????", 5)
88
- 00??1010?111?00010101??10101010?????1010111110???111110101001111010101??????????10100101010100011???????
89
- (generate search str - replace ?s with 0s)
90
- 00001010011100001010100101010100000010101111100001111101010011110101010000000000101001010101000110000000
91
- (generate shifted mask)
92
- (turn preceding 0s to 1s)
93
- (left shift (((binlen)+5)/8.to_f).ceil*8 - binlen - 5)
94
- 11001111011101111111100111111110000011111111110001111111111111111111110000000000111111111111111110000000000
95
- 11001111011101111111100111111110000011111111110001111111111111111111110000000000111111111111111110000000
96
- (generate shifted search - same as above)
97
- 00001010011100001010100101010100000010101111100001111101010011110101010000000000101001010101000110000000000
98
- (sample byte sequence)
99
- 00011010011100001010111101010101100110101111100101111101010011110101010010101001101001010101000110110100101
100
-
101
- 00011010011100001010111101010101100110101111100101111101010011110101010010101001101001010101000110110100101 &
102
- 11001111011101111111100111111110000011111111110001111111111111111111110000000000111111111111111110000000000 ==
103
- 00001010011100001010100101010100000010101111100001111101010011110101010000000000101001010101000110000000000
104
-
105
-
106
- # NOTE
107
-
108
- instead of shifting the product of (mask & input), shift search
109
- this makes the form
110
- "tcp[0:1] & mask = shifted_search"
111
-
112
-
113
- Packetman.compose3("0xa",1)
114
- "((tcp[0:1] & 0x78) >> 3) = 0xa"
115
- 1010
116
- (generate shifted mask)
117
- (left shift (((hexlen*4)+1)/8.to_f).ceil*8 - hexlen*4 - 1)
118
- (use length of mask to determine how much data to take)
119
- 01111000
120
- (sample byte sequence)
121
- 11010101
122
-
123
- (0b01111000 & 0b11010101) >> 3 == 0xa
124
-
125
-
126
- Packetman.compose3("0x123", 3)
127
- "((tcp[0:2] & 0x1ffe) >> 1) = 0x123"
128
- 100100011
129
- (hex: left fill with 1s to hexlen*4)
130
- 111100100011
131
- (generate shifted mask)
132
- (left shift (((hexlen*4)+3)/8.to_f).ceil*8 - hexlen*4 - 3)
133
- (use length of mask to determine how much data to take)
134
- 0001111111111110
135
- (sample byte sequence)
136
- 1000001001000111
137
-
138
- (0b1000001001000111 & 0b0001111111111110) >> 1 == 0x123
139
-
140
- Packetman.compose3("abc", 3)
141
- "((tcp[0:4] & 0x1fffffe0 >> 5) = 0x616263"
142
- 11000010110001001100011
143
- (str: left fill with 1s to len*8)
144
- 111000010110001001100011
145
- (generate shifted mask)
146
- (left shift (((strlen*8)+3)/8.to_f).ceil*8 - strlen*8 - 3)
147
- (use length of mask to determine how much data to take)
148
- 00011111 11111111 11111111 11100000
149
- (sample byte sequence)
150
- 10101100 00101100 01001100 01110101
151
-
152
- (0b10101100001011000100110001110101 & 0b00011111111111111111111111100000) >> 5 == 0b11000010110001001100011
153
-
154
-
155
-
156
-