packetman 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/NOTES.md +5 -0
- data/README.md +53 -0
- data/Rakefile +6 -0
- data/TODO.md +3 -0
- data/bin/console +10 -0
- data/bin/setup +7 -0
- data/circle.yml +3 -0
- data/config/protocols.yml +35 -0
- data/exe/packetman +6 -0
- data/lib/packetman.rb +24 -0
- data/lib/packetman/compose.rb +97 -0
- data/lib/packetman/config.rb +71 -0
- data/lib/packetman/config_methods.rb +11 -0
- data/lib/packetman/table.rb +58 -0
- data/lib/packetman/version.rb +3 -0
- data/packetman.gemspec +27 -0
- data/packetman_notes +156 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d179b4712440f17879c705887caeec69fd857517
|
4
|
+
data.tar.gz: 7879478eab7e6ecca5d75bff051a5dcad4006465
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 59f189ec8d961cc829938163d21daffea43b4ce14f5b0487d49339ad59abf6cbefabfbb5254e2b949132987ee06df4b584664d9e0d1f7973c33835c1328cd59a
|
7
|
+
data.tar.gz: 4e6b9134085f93800d07dd8a5e218c48d1c25260832b837c4f2e4fc365545234589232e0af344b8e1687eb90f6aa93d91875a341cfcf1165c1bec3d2341fd3a5
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Jason Scholl
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/NOTES.md
ADDED
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Packetman
|
2
|
+
|
3
|
+
Advanced tcpdump and Wireshark capture generator.
|
4
|
+
|
5
|
+
[](https://codeclimate.com/github/jescholl/packetman) [](https://codeclimate.com/github/jescholl/packetman/coverage) [](https://circleci.com/gh/jescholl/packetman)
|
6
|
+
|
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
|
+
|
9
|
+
Features:
|
10
|
+
* String-matching (just like Wireshark's tool)
|
11
|
+
* bit-string matching
|
12
|
+
* hex-string matching
|
13
|
+
* easy masking through `?` wildcard characters
|
14
|
+
* offsets in bits or bytes
|
15
|
+
* use header field name instead of manual offsets
|
16
|
+
* application specific queries
|
17
|
+
* built-in header reference tables
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
Add this line to your application's Gemfile:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
gem 'packetman'
|
25
|
+
```
|
26
|
+
|
27
|
+
And then execute:
|
28
|
+
|
29
|
+
$ bundle
|
30
|
+
|
31
|
+
Or install it yourself as:
|
32
|
+
|
33
|
+
$ gem install packetman
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
TODO: Write usage instructions here
|
38
|
+
|
39
|
+
## Development
|
40
|
+
|
41
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
42
|
+
|
43
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
44
|
+
|
45
|
+
## Contributing
|
46
|
+
|
47
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/jescholl/packetman.
|
48
|
+
|
49
|
+
|
50
|
+
## License
|
51
|
+
|
52
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
53
|
+
|
data/Rakefile
ADDED
data/TODO.md
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
data/circle.yml
ADDED
@@ -0,0 +1,35 @@
|
|
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
|
data/exe/packetman
ADDED
data/lib/packetman.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require "packetman/version"
|
3
|
+
require "packetman/config"
|
4
|
+
require "packetman/config_methods"
|
5
|
+
require "packetman/table"
|
6
|
+
require "packetman/compose"
|
7
|
+
|
8
|
+
module Packetman
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def config
|
12
|
+
@config ||= Config.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def config!
|
16
|
+
@config = Config.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def user_input(prompt)
|
20
|
+
puts prompt
|
21
|
+
gets
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Packetman
|
2
|
+
class Compose
|
3
|
+
include ConfigMethods
|
4
|
+
|
5
|
+
def initialize(input, radix=config.radix)
|
6
|
+
@input = input
|
7
|
+
@radix = radix
|
8
|
+
end
|
9
|
+
|
10
|
+
def desired_length
|
11
|
+
((@input.length + config.offset)/8.to_f).ceil*8 - config.offset
|
12
|
+
end
|
13
|
+
|
14
|
+
def bit_density(radix=@radix)
|
15
|
+
(radix.nil?) ? 8 : Math.log2(radix).to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
def mask
|
19
|
+
shift(@input.scan(/./).map{ |c| mask_chr(c) }.join)
|
20
|
+
end
|
21
|
+
|
22
|
+
def radix_mask
|
23
|
+
("1"*bit_density).to_i(2)
|
24
|
+
end
|
25
|
+
|
26
|
+
def shift(input)
|
27
|
+
input.ljust(desired_length, '0')
|
28
|
+
end
|
29
|
+
|
30
|
+
def search
|
31
|
+
shift(@input.scan(/./).map{ |c| bin_chr(c) }.join)
|
32
|
+
end
|
33
|
+
|
34
|
+
def mask_chr(chr)
|
35
|
+
if chr == '?'
|
36
|
+
raise "wildcards not allowed" unless config.allow_wildcards
|
37
|
+
0
|
38
|
+
else
|
39
|
+
radix_mask
|
40
|
+
end.to_s(2).rjust(bit_density, '0')
|
41
|
+
end
|
42
|
+
|
43
|
+
def bin_chr(chr)
|
44
|
+
if chr == '?'
|
45
|
+
raise "wildcards not allowed" unless config.allow_wildcards
|
46
|
+
chr = '0'
|
47
|
+
end
|
48
|
+
|
49
|
+
if @radix
|
50
|
+
chr.to_i(@radix)
|
51
|
+
else
|
52
|
+
chr.ord
|
53
|
+
end.to_s(2).rjust(bit_density, '0')
|
54
|
+
end
|
55
|
+
|
56
|
+
def mask_hex
|
57
|
+
hex_encode(mask)
|
58
|
+
end
|
59
|
+
|
60
|
+
def search_hex
|
61
|
+
hex_encode(search)
|
62
|
+
end
|
63
|
+
|
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') }
|
66
|
+
end
|
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
|
+
|
71
|
+
case num
|
72
|
+
when /^0x/
|
73
|
+
$'.length * bit_density(16)
|
74
|
+
when /^0b/
|
75
|
+
$'.length * bit_density(2)
|
76
|
+
else
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def start_byte(position)
|
82
|
+
"#{config.payload_query} + #{(config.offset + position)/8}"
|
83
|
+
end
|
84
|
+
|
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
|
93
|
+
|
94
|
+
clauses.join(' && ')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Packetman
|
4
|
+
class Config
|
5
|
+
attr_accessor :transport, :application, :offset_units, :offset_type, :allow_wildcards, :radix
|
6
|
+
attr_writer :offset
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@transport = "tcp"
|
10
|
+
@application = "http"
|
11
|
+
@offset = 0
|
12
|
+
@offset_units = "bits"
|
13
|
+
@offset_type = "application"
|
14
|
+
@allow_wildcards = true
|
15
|
+
end
|
16
|
+
|
17
|
+
def protocols
|
18
|
+
@protocols ||= YAML.load(File.read(File.expand_path('../../../config/protocols.yml', __FILE__)))
|
19
|
+
end
|
20
|
+
|
21
|
+
def payload_query
|
22
|
+
case offset_type
|
23
|
+
when "application"
|
24
|
+
protocols['transport'][transport.to_s]['payload_query']
|
25
|
+
else
|
26
|
+
"0"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def offset
|
31
|
+
case offset_units
|
32
|
+
when "bytes"
|
33
|
+
@offset*8
|
34
|
+
else
|
35
|
+
@offset
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_opts
|
40
|
+
@opts ||= OptionParser.new do |opt|
|
41
|
+
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 }
|
45
|
+
opt.on("-r", "--radix [RADIX]", Integer, "Treat FILTER_STRING as RADIX instead of String") {|v| self.radix = v; }
|
46
|
+
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 }
|
50
|
+
end
|
51
|
+
|
52
|
+
@opts.parse!
|
53
|
+
|
54
|
+
raise "Invalid command line arguments" if ARGV.size != 1
|
55
|
+
|
56
|
+
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
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Packetman
|
2
|
+
class Table
|
3
|
+
include ConfigMethods
|
4
|
+
|
5
|
+
attr_reader :line_h, :line_v
|
6
|
+
attr_accessor :columns
|
7
|
+
|
8
|
+
def initialize(cols = 32)
|
9
|
+
@line_v = '|'
|
10
|
+
@line_h = '-'
|
11
|
+
@columns = cols
|
12
|
+
end
|
13
|
+
|
14
|
+
def line_h=(value)
|
15
|
+
raise "Invalid character" if value.length != 1
|
16
|
+
@line_h = value
|
17
|
+
end
|
18
|
+
|
19
|
+
def line_v=(value)
|
20
|
+
raise "Invalid character" if value.length != 1
|
21
|
+
@line_v = value
|
22
|
+
end
|
23
|
+
|
24
|
+
def column_width
|
25
|
+
(columns-1).to_s.length
|
26
|
+
end
|
27
|
+
|
28
|
+
def horizontal_bar
|
29
|
+
line_v + line_h*(table_width - 2) + line_v + "\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
def table_width
|
33
|
+
columns*(column_width + 1) + 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def cell_size(field_size)
|
37
|
+
field_size*(column_width + 1) - 1
|
38
|
+
end
|
39
|
+
|
40
|
+
def header_row
|
41
|
+
line_v + columns.times.map{ |n| sprintf "%0#{column_width}d", n }.join(line_v) + line_v + "\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
output = horizontal_bar + header_row + horizontal_bar
|
46
|
+
|
47
|
+
config.protocols['transport'][config.transport]['table'].each do |label, size|
|
48
|
+
output += sprintf "%s%.#{cell_size(size)}s", line_v, label.center(cell_size(size))
|
49
|
+
if output.split("\n").last.length == (table_width - 1)
|
50
|
+
output += line_v + "\n"
|
51
|
+
output += horizontal_bar
|
52
|
+
end
|
53
|
+
end
|
54
|
+
output
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
data/packetman.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'packetman/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "packetman"
|
8
|
+
spec.version = Packetman::VERSION
|
9
|
+
spec.authors = ["Jason Scholl"]
|
10
|
+
spec.email = ["jason.e.scholl@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Advanced tcpdump and Wiresharp filter generator.}
|
13
|
+
spec.description = %q{Simple tool for creating advanced tcpdump queries, because manually writing `tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420` is no fun.}
|
14
|
+
spec.homepage = "https://github.com/jescholl/packetman"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.3"
|
25
|
+
spec.add_development_dependency "pry", "~> 0.10"
|
26
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
27
|
+
end
|
data/packetman_notes
ADDED
@@ -0,0 +1,156 @@
|
|
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
|
+
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: packetman
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jason Scholl
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.10'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.10'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: codeclimate-test-reporter
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Simple tool for creating advanced tcpdump queries, because manually writing
|
84
|
+
`tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420` is no fun.
|
85
|
+
email:
|
86
|
+
- jason.e.scholl@gmail.com
|
87
|
+
executables:
|
88
|
+
- packetman
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- ".gitignore"
|
93
|
+
- ".rspec"
|
94
|
+
- ".travis.yml"
|
95
|
+
- Gemfile
|
96
|
+
- LICENSE.txt
|
97
|
+
- NOTES.md
|
98
|
+
- README.md
|
99
|
+
- Rakefile
|
100
|
+
- TODO.md
|
101
|
+
- bin/console
|
102
|
+
- bin/setup
|
103
|
+
- circle.yml
|
104
|
+
- config/protocols.yml
|
105
|
+
- exe/packetman
|
106
|
+
- lib/packetman.rb
|
107
|
+
- lib/packetman/compose.rb
|
108
|
+
- lib/packetman/config.rb
|
109
|
+
- lib/packetman/config_methods.rb
|
110
|
+
- lib/packetman/table.rb
|
111
|
+
- lib/packetman/version.rb
|
112
|
+
- packetman.gemspec
|
113
|
+
- packetman_notes
|
114
|
+
homepage: https://github.com/jescholl/packetman
|
115
|
+
licenses:
|
116
|
+
- MIT
|
117
|
+
metadata: {}
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
requirements: []
|
133
|
+
rubyforge_project:
|
134
|
+
rubygems_version: 2.4.5
|
135
|
+
signing_key:
|
136
|
+
specification_version: 4
|
137
|
+
summary: Advanced tcpdump and Wiresharp filter generator.
|
138
|
+
test_files: []
|