packetgen-plugin-smb 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0420b25c4cbb969cd7178373395736f61b5de2ac31710168305f1cb42281cef7
4
+ data.tar.gz: 7a6fc87b651548518e7b3fb9baa4b48619c4666ce9b33705a4990245999ed613
5
+ SHA512:
6
+ metadata.gz: 36efbeb7817f790c660ff0d6ff71c6284ec7ec1235d99f4473ad34993942c0fe2e7c992a448d6e50640b5d009fc84abe4f0e25ed048cb4f202e320c11e936656
7
+ data.tar.gz: dd3f345d46ec5b59b31f72d34c3aa7bce2878211acafb796cf40b7c7e2c24eaff54056ce3c7a1b6bd85a35ff4861f257e7aadfb3dfd0a52e04de4c45d055bb44
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /vendor/
10
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3
4
+ - 2.4
5
+ - 2.5
6
+
7
+ install:
8
+ - sudo apt-get update -qq
9
+ - sudo apt-get install libpcap-dev -qq
10
+ - bundle install --path vendor/bundle --jobs=3 --retry=3
11
+ script:
12
+ - bundle exec rake
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in packetgen-plugin-smb.gemspec
6
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Sylvain Daubert
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ [![Build Status](https://travis-ci.com/sdaubert/packetgen-plugin-smb.svg?branch=master)](https://travis-ci.com/sdaubert/packetgen-plugin-smb)
2
+
3
+ # Packetgen::Plugin::SMB
4
+
5
+ This is a plugin for [PacketGen gem](https://github.com/sdaubert/packetgen). It adds some support for SMB protocol suite.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'packetgen-plugin-smb'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install packetgen-plugin-smb
22
+
23
+ ## Usage
24
+
25
+ TODO
26
+
27
+ ## Contributing
28
+
29
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sdaubert/packetgen-plugin-smb.
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+ require 'yard'
5
+
6
+ task default: :spec
7
+
8
+ RSpec::Core::RakeTask.new
9
+
10
+ YARD::Rake::YardocTask.new do |t|
11
+ t.options = ['--no-private']
12
+ t.files = ['lib/**/*.rb', '-', 'LICENSE']
13
+ end
@@ -0,0 +1,3 @@
1
+ require "packetgen"
2
+ require_relative "packetgen/plugin/smb_version"
3
+ require_relative "packetgen/plugin/smb"
@@ -0,0 +1,185 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen::Plugin
9
+ # Server Message Block (SMB) header.
10
+ # @author Sylvain Daubert
11
+ # @since 0.1.0
12
+ class SMB < PacketGen::Header::Base
13
+ # Known commands
14
+ COMMANDS = {
15
+ 'delete_dir' => 0x01,
16
+ 'close' => 0x04,
17
+ 'delete' => 0x06,
18
+ 'query_info2' => 0x23,
19
+ 'trans' => 0x25,
20
+ 'echo' => 0x2b,
21
+ 'open_and_x' => 0x2d,
22
+ 'read_and_x' => 0x2e,
23
+ 'write_and_x' => 0x2f,
24
+ 'trans2' => 0x32,
25
+ 'tree_disconnect' => 0x71,
26
+ 'negotiate' => 0x72,
27
+ 'session_setup_and_x' => 0x73,
28
+ 'tree_connect_and_x' => 0x75,
29
+ 'nt_trans' => 0xa0,
30
+ 'nt_create_and_x' => 0xa2
31
+ }.freeze
32
+ # SMB marker, on start of header
33
+ MARKER = PacketGen.force_binary("\xffSMB")
34
+
35
+ # @!attribute protocol
36
+ # This field must contain {MARKER SMB marker}
37
+ # @return [String]
38
+ define_field :protocol, PacketGen::Types::String, static_length: 4, default: MARKER
39
+ # @!attribute command
40
+ # 8-bit SMB command
41
+ # @return [Integer]
42
+ define_field :command, PacketGen::Types::Int8Enum, enum: COMMANDS
43
+ # @!attribute status
44
+ # 32-bit status field. Used to communicate errors from server to client.
45
+ # @return [Integer]
46
+ define_field :status, PacketGen::Types::Int32le
47
+ # @!attribute flags
48
+ # 8-bit flags field
49
+ # @return [Integer]
50
+ define_field :flags, PacketGen::Types::Int8
51
+ # @!attribute flags2
52
+ # 16-bit flags field
53
+ # @return [Integer]
54
+ define_field :flags2, PacketGen::Types::Int16le
55
+ # @!attribute pid_high
56
+ # 16 high order bits of a process identifier (PID)
57
+ # @return [Integer]
58
+ define_field :pid_high, PacketGen::Types::Int16le
59
+ # @!attribute sec_features
60
+ # 64-bit field. May be:
61
+ # * a 64-bit cryptographic message signature if signature was negotiated,
62
+ # * a SecurityFeatures structure, only over connectionless transport,
63
+ # composed of:
64
+ # * a 16-bit sequence number,
65
+ # * a 16-bit connection identifier (CID),
66
+ # * a 32-bit key to validate message,
67
+ # * a reserved field in all others cases.
68
+ # @return [Integer]
69
+ define_field :sec_features, PacketGen::Types::Int64le
70
+ # @!attribute reserved
71
+ # 16-bit reserved field
72
+ # @return [Integer]
73
+ define_field :reserved, PacketGen::Types::Int16le
74
+ # @!attribute tid
75
+ # 16-bit tree identifier (TID)
76
+ define_field :tid, PacketGen::Types::Int16le
77
+ # @!attribute pid
78
+ # 16 low order bits of a process identifier (PID)
79
+ # @return [Integer]
80
+ define_field :pid, PacketGen::Types::Int16le
81
+ # @!attribute uid
82
+ # 16-bit user identifier (UID)
83
+ define_field :uid, PacketGen::Types::Int16le
84
+ # @!attribute mid
85
+ # 16-bit multiplex identifier (MID)
86
+ define_field :mid, PacketGen::Types::Int16le
87
+ # @!attribute body
88
+ # @return [String]
89
+ define_field :body, PacketGen::Types::String
90
+ # @!attribute flags_reply
91
+ # When set, the message is a reply from server to client.
92
+ # @return [Boolean]
93
+ # @!attribute flags_opbatch
94
+ # Obsolescent.
95
+ # @return [Boolean]
96
+ # @!attribute flags_oplock
97
+ # Obsolescent.
98
+ # @return [Boolean]
99
+ # @!attribute flags_canon_paths
100
+ # Obsolescent.
101
+ # @return [Boolean]
102
+ # @!attribute flags_case_insensitive
103
+ # Obsolete.
104
+ # @return [Boolean]
105
+ # @!attribute flags_reserved
106
+ # @return [Boolean]
107
+ # @!attribute flags_rbuf_avail
108
+ # Obsolete.
109
+ # @return [Boolean]
110
+ # @!attribute flags_locknread
111
+ # When set in SMB_COM_NEGOTIATE response, the server supports
112
+ # SMB_COM_LOCK_AND_READ and SNB_COM_WRITE_AND_UNLOCK commands.
113
+ # @return [Boolean]
114
+ define_bit_fields_on :flags, :flags_reply, :flags_opbatch, :flags_oplock,
115
+ :flags_canon_paths, :flags_case_insensitive,
116
+ :flags_reserved, :flags_buf_avail, :flags_locknread
117
+ # @!attribute flags2_unicode
118
+ # If set, each field that contains a string in this message is encoded
119
+ # as UTF-16.
120
+ # @return [Boolean]
121
+ # @!attribute flags2_ntstatus
122
+ # If set in a client request, server must return errors as NTSTATUS, else
123
+ # as SMBSTATUS.
124
+ # @return [Boolean]
125
+ # @!attribute flags2_paging_io
126
+ # Client may read a file if it does not have read permission but have
127
+ # execute one.
128
+ # @return [Boolean]
129
+ # @!attribute flags2_dfs
130
+ # If set, any pathnames should be resolved in the Distributed File System
131
+ # (DFS).
132
+ # @return [Boolean]
133
+ # @!attribute flags2_extended_security
134
+ # @return [Boolean]
135
+ # @!attribute flags2_reparse_path
136
+ # @return [Boolean]
137
+ # @!attribute flags2_reserved
138
+ # 3-bit reserved field
139
+ # @return [Integer]
140
+ # @!attribute flags2_is_long_name
141
+ # @return [Boolean]
142
+ # @!attribute flags2_rsv
143
+ # @return [Boolean]
144
+ # @!attribute flags2_security_signature_required
145
+ # @return [Boolean]
146
+ # @!attribute flags2_compressed
147
+ # @return [Boolean]
148
+ # @!attribute flags2_signature
149
+ # @return [Boolean]
150
+ # @!attribute flags2_eas
151
+ # @return [Boolean]
152
+ # @!attribute flags2_long_names
153
+ # If unset, file names must adhere to the 8.3 naming convention.
154
+ # @return [Boolean]
155
+ define_bit_fields_on :flags2, :flags2_unicode, :flags2_ntstatus,
156
+ :flags2_paging_io, :flags2_dfs, :flags2_extended_security,
157
+ :flags2_reparse_path, :flags2_reserved, 3,
158
+ :flags2_is_long_name, :flags2_rsv,
159
+ :flags2_security_signature_required, :flags2_compresses,
160
+ :flags2_signature, :flags2_eas, :flags2_long_names
161
+
162
+ # Helper to bind a SMB command to {SMB} header.
163
+ # @param [String] command name
164
+ # @return [void]
165
+ def self.bind_command(command)
166
+ contantized = command.capitalize.gsub(/_(\w)/) { $1.upcase }
167
+ krequest = self.const_get("#{contantized}Request")
168
+ kresponse = self.const_get("#{contantized}Response")
169
+ PacketGen::Header.add_class krequest
170
+ self.bind krequest, command: SMB::COMMANDS[command], flags: ->(v) { v.nil? ? 0 : (v & 0x80).zero? }
171
+ PacketGen::Header.add_class kresponse
172
+ self.bind kresponse, command: SMB::COMMANDS[command], flags: ->(v) { v.nil? ? 0 : (v & 0x80 == 0x80) }
173
+ end
174
+ end
175
+ PacketGen::Header.add_class SMB
176
+ PacketGen::Header::NetBIOS::Session.bind SMB, body: ->(val) { val.nil? ? SMB::MARKER : val[0..3] == SMB::MARKER }
177
+ PacketGen::Header::NetBIOS::Datagram.bind SMB, body: ->(val) { val.nil? ? SMB::MARKER : val[0..3] == SMB::MARKER }
178
+ end
179
+
180
+ require_relative 'smb/string'
181
+ require_relative 'smb/filetime'
182
+ require_relative 'smb/close'
183
+ require_relative 'smb/trans'
184
+ require_relative 'smb/nt_create_and_x'
185
+ require_relative 'smb/blocks'
@@ -0,0 +1,48 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen::Plugin
9
+ class SMB
10
+ # Common blocks used for unsupported SMB messages.
11
+ #
12
+ # {Blocks} handles parameter block and data block. Parameter block is
13
+ # composed of:
14
+ # * a 8-bit {#word_count} field,
15
+ # * a {#words} field, an array of +PacketGen::Types::Int16le+.
16
+ # Data block is composed of:
17
+ # * a little endian 16-bit {#byte_count} field,
18
+ # * a {#bytes} field, an array of +PacketGen::Types::Int8+.
19
+ # @author Sylvain Daubert
20
+ # @since 0.1.0
21
+ class Blocks < PacketGen::Header::Base
22
+ # @!attribute word_count
23
+ # The size, in 2-byte words, of the {#words} field.
24
+ # @return [Integer]
25
+ define_field :word_count, PacketGen::Types::Int8
26
+ # @!attribute words
27
+ # The message-specific parameters structure.
28
+ # @return [PacketGen::Types::ArrayOfInt16le]
29
+ define_field :words, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:word_count]) }
30
+ # @!attribute byte_count
31
+ # The size, in bytes, of the {#bytes} field.
32
+ # @return [Integer]
33
+ define_field :byte_count, PacketGen::Types::Int16le
34
+ # @!attribute bytes
35
+ # The message-specific data structure.
36
+ # @return [PacketGen::Types::ArrayOfInt8]
37
+ define_field :bytes, PacketGen::Types::ArrayOfInt8, builder: ->(h, t) { t.new(counter: h[:byte_count]) }
38
+
39
+ # Give protocol name for this class
40
+ # @return [String]
41
+ def protocol_name
42
+ 'SMB::Blocks'
43
+ end
44
+ end
45
+ end
46
+ PacketGen::Header.add_class SMB::Blocks
47
+ SMB.bind SMB::Blocks
48
+ end
@@ -0,0 +1,57 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen::Plugin
9
+ class SMB
10
+ # Close Request.
11
+ # @author Sylvain Daubert
12
+ # @since 0.1.0
13
+ class CloseRequest < PacketGen::Header::Base
14
+ # @!attribute word_count
15
+ # The size, in 2-byte words, of the SMB command parameters. It should
16
+ # be +3+.
17
+ # @return [Integer]
18
+ define_field :word_count, PacketGen::Types::Int8, default: 3
19
+ # @!attribute fid
20
+ # 16-bit FID of the object to close
21
+ # @return [Integer]
22
+ define_field :fid, PacketGen::Types::Int16le, default: 3
23
+ # @!attribute last_modified
24
+ # 32-bit time value encoded as the number of seconds since January
25
+ # 1, 1970 00:00:00.0. The client can request that the last modification
26
+ # time for the file be updated to this time value. A value of +0x00000000+
27
+ # or +0xFFFFFFFF+ results in the server not updating the last modification
28
+ # time.
29
+ # @return [Integer]
30
+ define_field :last_modified, PacketGen::Types::Int32le
31
+ # @!attribute byte_count
32
+ # Should be 0.
33
+ # @return [Integer]
34
+ define_field :byte_count, PacketGen::Types::Int16le, default: 0
35
+ end
36
+
37
+ # Close Response.
38
+ #
39
+ # This is a void container. {#word_count} and {#byte_count} should be 0.
40
+ # @author Sylvain Daubert
41
+ # @since 0.1.0
42
+ class CloseResponse < PacketGen::Header::Base
43
+ # @!attribute word_count
44
+ # The size, in 2-byte words, of the SMB command parameters. It should
45
+ # be +0+.
46
+ # @return [Integer]
47
+ define_field :word_count, PacketGen::Types::Int8, default: 3
48
+ define_field :last_modified, PacketGen::Types::Int32le
49
+ # @!attribute byte_count
50
+ # Should be 0.
51
+ # @return [Integer]
52
+ define_field :byte_count, PacketGen::Types::Int16le, default: 0
53
+ end
54
+
55
+ self.bind_command 'close'
56
+ end
57
+ end
@@ -0,0 +1,114 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen::Plugin
9
+ class SMB
10
+ # 64-bit signed integer, little endian representation
11
+ # @author Sylvain Daubert
12
+ # @private
13
+ # @since 0.1.0
14
+ class SInt64le < PacketGen::Types::Int64le
15
+ def initialize(value=nil)
16
+ super
17
+ @packstr[:little] = 'q<'
18
+ end
19
+ end
20
+
21
+ # SMB FILETIME.
22
+ # @author Sylvain Daubert
23
+ # @since 0.1.0
24
+ class Filetime
25
+ # Base time for SMB FILETIME.
26
+ # This value also indicate no time.
27
+ NO_TIME = Time.utc(1601).freeze
28
+
29
+ # @param [Hash] options
30
+ # @option options [Integer] :filetime
31
+ # @option options [Time] :time
32
+ # @raise [ArgumentError] if +:time+ and +:filetime+ are both given.
33
+ def initialize(options={})
34
+ if (options.keys & %i[time filetime]).size == 2
35
+ raise ArgumentError, ':time and :filetime options are both given'
36
+ end
37
+
38
+ @int = SInt64le.new(options[:filetime])
39
+ if options[:time]
40
+ @time = options[:time]
41
+ @int.value = time2filetime
42
+ else
43
+ @time = filetime2time
44
+ end
45
+ end
46
+
47
+ # @param [::String] str
48
+ # @return [String] self
49
+ def read(str)
50
+ @int.read(str[0, 8])
51
+ @time = filetime2time
52
+ self
53
+ end
54
+
55
+ # Human readable filetime
56
+ # @return [String]
57
+ def to_human
58
+ if no_time?
59
+ 'no time'
60
+ else
61
+ @time.to_s
62
+ end
63
+ end
64
+
65
+ # Get filetime integer value
66
+ # @return [Integer]
67
+ def to_i
68
+ @int.to_i
69
+ end
70
+
71
+ # Check if there is no time specified
72
+ # @return [Boolean]
73
+ def no_time?
74
+ to_i.zero?
75
+ end
76
+
77
+ # @return [Integer]
78
+ def sz
79
+ @int.sz
80
+ end
81
+
82
+ # @return [String]
83
+ def to_s
84
+ @int.to_s
85
+ end
86
+
87
+ # @return [Time]
88
+ def to_time
89
+ @time
90
+ end
91
+
92
+ private
93
+
94
+ def filetime2time
95
+ filetime = @int.to_i
96
+ secs = filetime / 10_000
97
+ nsecs = (filetime % 10_000) * 100
98
+ if filetime.zero?
99
+ NO_TIME
100
+ elsif filetime.positive?
101
+ Time.at(NO_TIME) + Rational("#{secs}.%09d" % nsecs)
102
+ else
103
+ Time.at(Time.now.utc) + Rational("#{secs}.%09d" % nsecs)
104
+ end
105
+ end
106
+
107
+ def time2filetime
108
+ # Time#to_f then #to_r is more precise than Time#to_r
109
+ # (ie Time#to_r sometimes does a rounding error).
110
+ (@time.to_i - NO_TIME.to_i) * 10_000 + ((@time.to_f.to_r * 10_000) % 10_000).to_i
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,273 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen::Plugin
9
+ class SMB
10
+ # SMB Command NtCreateAndX request.
11
+
12
+ # A NtCreateAndXRequest contains:
13
+ # * a {#word_count} field (+Int8+), size, in 2-byte words of SMB
14
+ # parameters:
15
+ # * {#and_xcommand} (+Int8+), next command in packet,
16
+ # * {#rsv1} (+Int8+),
17
+ # * {#and_xoffset} (+Int16le+), offset of the next command from the
18
+ # start of SMB header,
19
+ # * {#rsv2} (+Int8+),
20
+ # * {#filename_len} (+Int16le+), size of {#filename} in SMB data,
21
+ # * {#flags} (+Int32le+),
22
+ # * {#root_dir_fid} (+Int32le+),
23
+ # * {#access_mask} (+Int32le+),
24
+ # * {#alloc_size} (+Int64le+),
25
+ # * {#attributes} (+Int32le+),
26
+ # * {#share_access} (+Int32le+),
27
+ # * {#disposition} (+Int32le+),
28
+ # * {#options} (+Int32le+),
29
+ # * {#impersonation} (+Int32le+),
30
+ # * {#sec_flags} (+Int38+),
31
+ # * #{byte_count} (+Int16le+), size in bytes of SMB data:
32
+ # * {#pad1} (+Int8),
33
+ # * {#filename} ({SMB::String}),
34
+ # * {#extra_bytes} (+String+).
35
+ #
36
+ # == Known limitations
37
+ # 1. Only the first command is properly handled. Chained commands are not.
38
+ # 2. {#filename} is mandatory handled as Windows Unicode string.
39
+ # @author Sylvain Daubert
40
+ # @since 0.1.0
41
+ class NtCreateAndXRequest < PacketGen::Header::Base
42
+ # Commands that may follow this one in a SMB packet
43
+ COMMANDS = {
44
+ 'read' => 0x0a,
45
+ 'read_andx' => 0x2e,
46
+ 'ioctl' => 0x27,
47
+ 'no further commands' => 0xff
48
+ }.freeze
49
+
50
+ # @!attribute word_count
51
+ # The size, in 2-byte words, of the SMB parameters.
52
+ # @return [Integer]
53
+ define_field :word_count, PacketGen::Types::Int8, default: 24
54
+ # @!attribute and_xcommand
55
+ # 8-bit command code for the next SMB command in the
56
+ # packet.
57
+ # @return [Integer]
58
+ define_field :and_xcommand, PacketGen::Types::Int8Enum, enum: COMMANDS
59
+ # @!attribute rsv1
60
+ # 8-bit reserved field.
61
+ # @return [Integer]
62
+ define_field :rsv1, PacketGen::Types::Int8, default: 0
63
+ # @!attribute and_xoffset
64
+ # 16-bit offset from the start of SMB header to the start of
65
+ # the {#word_count} field in the next SMB command in this
66
+ # packet.
67
+ # @return [Integer]
68
+ define_field :and_xoffset, PacketGen::Types::Int16le, default: 0
69
+ # @!attribute rsv2
70
+ # 8-bit reserved field.
71
+ # @return [Integer]
72
+ define_field :rsv2, PacketGen::Types::Int8, default: 0
73
+ # @!attribute filename_len
74
+ # 16-bit length of the {#filename} field.
75
+ # @return [Integer]
76
+ define_field :filename_len, PacketGen::Types::Int16le
77
+ alias filename_length filename_len
78
+ alias filename_length= filename_len=
79
+ # @!attribute flags
80
+ # 32-bit flags word
81
+ # @return [Integer]
82
+ define_field :flags, PacketGen::Types::Int32le
83
+ # @!attribute root_dir_fid
84
+ # 32-bit file ID of an opened root directory.
85
+ # @return [Integer]
86
+ define_field :root_dir_fid, PacketGen::Types::Int32le
87
+ # @!attribute access_mask
88
+ # 32-bit flags that indicate access rights.
89
+ # @return [Integer]
90
+ define_field :access_mask, PacketGen::Types::Int32le
91
+ # @!attribute alloc_size
92
+ # 64-bit initial allocation size.
93
+ # @return [Integer]
94
+ define_field :alloc_size, PacketGen::Types::Int64le
95
+ # @!attribute attributes
96
+ # 32-bit extended file attributes.
97
+ # @return [Integer]
98
+ define_field :attributes, PacketGen::Types::Int32le
99
+ # @!attribute share_access
100
+ # 32-bit field that specifies how the file should be shared.
101
+ # @return [Integer]
102
+ define_field :share_access, PacketGen::Types::Int32le
103
+ # @!attribute disposition
104
+ # 32-bit value that represents the action to take if the file
105
+ # already exists or if the file is a new file and does not already
106
+ # exist.
107
+ # @return [Integer]
108
+ define_field :disposition, PacketGen::Types::Int32le
109
+ # @!attribute options
110
+ # 32-bit field containing flag options to use if creating the file
111
+ # or the directory.
112
+ # @return [Integer]
113
+ define_field :options, PacketGen::Types::Int32le
114
+ # @!attribute impersonation
115
+ # 32-bit field specifying the impersonation level requested by
116
+ # the application.
117
+ # @return [Integer]
118
+ define_field :impersonation, PacketGen::Types::Int32le
119
+ # @!attribute sec_flags
120
+ # 8-bit security flags.
121
+ define_field :sec_flags, PacketGen::Types::Int8
122
+ # @!attribute byte_count
123
+ # The size, in bytes, of the SMB data.
124
+ # @return [Integer]
125
+ define_field :byte_count, PacketGen::Types::Int16le
126
+ # @!attribute pad1
127
+ # Padding before {#filename} to align it on 16-bit boundary
128
+ # @return [Integer]
129
+ define_field :pad1, PacketGen::Types::Int8
130
+ # @!attribute filename
131
+ # A string that represents the fully qualified name of the file
132
+ # relative to the supplied TID
133
+ # @return [String]
134
+ define_field :filename, SMB::String
135
+ # @!attribute extra_bytes
136
+ # @return [Integer]
137
+ define_field :extra_bytes, PacketGen::Types::String,
138
+ builder: ->(h, t) { t.new(length_from: -> { h.byte_count - 1 - h[:filename].sz }) }
139
+
140
+ # Give protocol name for this class
141
+ # @return [String]
142
+ def protocol_name
143
+ 'SMB::NtCreateAndXRequest'
144
+ end
145
+
146
+ # Compute {#filename_len} and {#byte_count}
147
+ # @return [void]
148
+ def calc_length
149
+ self.filename_len = self[:filename].sz
150
+ bcount = 1 + filename_len + self[:extra_bytes].sz
151
+ self.byte_count = bcount
152
+ end
153
+ end
154
+
155
+ # SMB Command NtCreateAndX response
156
+ # @author Sylvain Daubert
157
+ # @since 0.1.0
158
+ class NtCreateAndXResponse < PacketGen::Header::Base
159
+ # OpLock levels
160
+ OP_LOCK_LEVELS = {
161
+ 'none' => 0,
162
+ 'exclusive' => 1,
163
+ 'batch' => 2,
164
+ 'level II' => 3,
165
+ }.freeze
166
+
167
+ # @!attribute word_count
168
+ # The size, in 2-byte words, of the SMB parameters.
169
+ # @return [Integer]
170
+ define_field :word_count, PacketGen::Types::Int8, default: 34
171
+ # @!attribute and_xcommand
172
+ # 8-bit command code for the next SMB command in the
173
+ # packet.
174
+ # @return [Integer]
175
+ define_field :and_xcommand, PacketGen::Types::Int8Enum, enum: NtCreateAndXRequest::COMMANDS
176
+ # @!attribute rsv1
177
+ # 8-bit reserved field.
178
+ # @return [Integer]
179
+ define_field :rsv1, PacketGen::Types::Int8, default: 0
180
+ # @!attribute and_xoffset
181
+ # 16-bit offset from the start of SMB header to the start of
182
+ # the {#word_count} field in the next SMB command in this
183
+ # packet.
184
+ # @return [Integer]
185
+ define_field :and_xoffset, PacketGen::Types::Int16le, default: 0
186
+ # @!attribute oplock_level
187
+ # 8-bit OpLock level.
188
+ # @return [Integer]
189
+ define_field :oplock_level, PacketGen::Types::Int8Enum, enum: OP_LOCK_LEVELS
190
+ # @!attribute fid
191
+ # 16-bit FID.
192
+ # @return [Integer]
193
+ define_field :fid, PacketGen::Types::Int16le
194
+ # @!attribute disposition
195
+ # 32-bit value that represents the action to take if the file
196
+ # already exists or if the file is a new file and does not already
197
+ # exist.
198
+ # @return [Integer]
199
+ define_field :disposition, PacketGen::Types::Int32le
200
+ # @!attribute create_time
201
+ # 64-bit integer representing the time that the file was created.
202
+ # @return [Integer]
203
+ define_field :create_time, SMB::Filetime
204
+ # @!attribute access_time
205
+ # 64-bit integer representing the time that the file was last accessed.
206
+ # @return [Integer]
207
+ define_field :access_time, SMB::Filetime
208
+ # @!attribute write_time
209
+ # 64-bit integer representing the time that the file was last writen.
210
+ # @return [Integer]
211
+ define_field :write_time, SMB::Filetime
212
+ # @!attribute change_time
213
+ # 64-bit integer representing the time that the file was last changed.
214
+ # @return [Integer]
215
+ define_field :change_time, SMB::Filetime
216
+ # @!attribute attributes
217
+ # 32-bit extended file attributes.
218
+ # @return [Integer]
219
+ define_field :attributes, PacketGen::Types::Int32le
220
+ # @!attribute alloc_size
221
+ # 64-bit integer representing the number of bytes allocated to the file.
222
+ # @return [Integer]
223
+ define_field :alloc_size, PacketGen::Types::Int64le
224
+ # @!attribute end_of_file
225
+ # 64-bit integer representing the end of file offset.
226
+ # @return [Integer]
227
+ define_field :end_of_file, PacketGen::Types::Int64le
228
+ # @!attribute res_type
229
+ # 16-bit file type.
230
+ # @return [Integer]
231
+ define_field :res_type, PacketGen::Types::Int16le
232
+ # @!attribute pipe_status
233
+ # 16-bit field that shows the status of the named pipe (if opened resource
234
+ # is a named pipe).
235
+ # @return [Integer]
236
+ define_field :pipe_status, PacketGen::Types::Int16le
237
+ # @!attribute directory
238
+ # 8-bit field indicating is the FID represents a directory.
239
+ # @return [Integer]
240
+ define_field :directory, PacketGen::Types::Int8
241
+ # @!attribute byte_count
242
+ # The size, in bytes, of the SMB data. Should be zero.
243
+ # @return [Integer]
244
+ define_field :byte_count, PacketGen::Types::Int16le, default: 0
245
+
246
+ # Give protocol name for this class
247
+ # @return [String]
248
+ def protocol_name
249
+ 'SMB::NtCreateAndXResponse'
250
+ end
251
+
252
+ # Say if FID is a directory
253
+ # @return [Boolean]
254
+ def directory?
255
+ self.directory > 0
256
+ end
257
+
258
+ # @!method human_create_time
259
+ # @return [String]
260
+ # @!method human_access_time
261
+ # @return [String]
262
+ # @!method human_write_time
263
+ # @return [String]
264
+ # @!method human_change_time
265
+ # @return [String]
266
+ %i[create access write change].each do |type|
267
+ class_eval "def human_#{type}_time; self[:#{type}_time].to_human; end"
268
+ end
269
+ end
270
+
271
+ self.bind_command 'nt_create_and_x'
272
+ end
273
+ end
@@ -0,0 +1,52 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen::Plugin
9
+ class SMB
10
+ # SMB strings (UTF-16 little-endian).
11
+ # @author Sylvain Daubert
12
+ # @since 0.1.0
13
+ class String < PacketGen::Types::CString
14
+ # @param [Boolean, Proc] is string UTF-16 encoded?
15
+ # @param [Hash] options
16
+ # @option options [Integer] :static_length set a static length for this string
17
+ def initialize(options={})
18
+ super
19
+ self.encode!('UTF-16LE')
20
+ end
21
+
22
+ # @param [::String] str
23
+ # @return [String] self
24
+ def read(str)
25
+ return self if str.nil?
26
+
27
+ str2 = case str.encoding
28
+ when Encoding::BINARY
29
+ binidx = nil
30
+ 0.step(to: str.size, by: 2) do |i|
31
+ binidx = i if str[i, 2] == "\x00\x00"
32
+ end
33
+ s = if binidx.nil?
34
+ str
35
+ else
36
+ str[0, binidx]
37
+ end
38
+ s.force_encoding('UTF-16LE')
39
+ when Encoding::UTF_16LE
40
+ str
41
+ else
42
+ str.encode('UTF-16LE')
43
+ end
44
+ str2 = str2[0, @static_length / 2] if @static_length.is_a? Integer
45
+ idx = str2.index(+"\x00".encode('UTF-16LE'))
46
+ str2 = str2[0, idx] unless idx.nil?
47
+ self.replace str2
48
+ self
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,200 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen for more informations
3
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
+ # This program is published under MIT license.
5
+
6
+ # frozen_string_literal: true
7
+
8
+ module PacketGen::Plugin
9
+ class SMB
10
+ # Transaction Request.
11
+ #
12
+ # See also {Blocks}, as {TransRequest} is a specialization of {Blocks#words}
13
+ # and {Blocks#bytes}.
14
+ # @author Sylvain Daubert
15
+ # @since 0.1.0
16
+ class TransRequest < PacketGen::Header::Base
17
+ # @!attribute word_count
18
+ # The size, in 2-byte words, of the SMB command parameters. It should
19
+ # be +14 + setup_count+.
20
+ # @return [Integer]
21
+ define_field :word_count, PacketGen::Types::Int8, default: 14
22
+ # @!attribute total_param_count
23
+ # The total number of transaction parameter bytes.
24
+ # @return [Integer]
25
+ define_field :total_param_count, PacketGen::Types::Int16le
26
+ # @!attribute total_data_count
27
+ # The total number of transaction data bytes.
28
+ # @return [Integer]
29
+ define_field :total_data_count, PacketGen::Types::Int16le
30
+ # @!attribute max_param_count
31
+ # The maximum number of parameter bytes that the client will accept
32
+ # in transaction response.
33
+ # @return [Integer]
34
+ define_field :max_param_count, PacketGen::Types::Int16le
35
+ # @!attribute max_data_count
36
+ # The maximum number of data bytes that the client will accept
37
+ # in transaction response.
38
+ # @return [Integer]
39
+ define_field :max_data_count, PacketGen::Types::Int16le
40
+ # @!attribute max_setup_count
41
+ # The maximum number of setup bytes that the client will accept
42
+ # in transaction response.
43
+ # @return [Integer]
44
+ define_field :max_setup_count, PacketGen::Types::Int8
45
+ # @!attribute rsv1
46
+ # 8-bit reserved field
47
+ # @return [Integer]
48
+ define_field :rsv1, PacketGen::Types::Int8, default: 0
49
+ # @!attribute flags
50
+ # 16-bit flags
51
+ # @return [Integer]
52
+ define_field :flags, PacketGen::Types::Int16le
53
+ # @!attribute timeout
54
+ # 32-bit timeout
55
+ # @return [Integer]
56
+ define_field :timeout, PacketGen::Types::Int32le
57
+ # @!attribute rsv2
58
+ # 16-bit reserved field
59
+ # @return [Integer]
60
+ define_field :rsv2, PacketGen::Types::Int16le, default: 0
61
+ # @!attribute param_count
62
+ # 16-bit number of transaction parameter bytes that the clients attempts to
63
+ # send to the server in this request.
64
+ # @return [Integer]
65
+ define_field :param_count, PacketGen::Types::Int16le
66
+ # @!attribute param_offset
67
+ # 16-bit offset (in bytes) from the start of the SMB header to the start of the
68
+ # transaction parameters.
69
+ # @return [Integer]
70
+ define_field :param_offset, PacketGen::Types::Int16le
71
+ # @!attribute data_count
72
+ # 16-bit number of transaction data bytes that the clients sends to
73
+ # the server in this request.
74
+ # @return [Integer]
75
+ define_field :data_count, PacketGen::Types::Int16le
76
+ # @!attribute data_offset
77
+ # 16-bit offset (in bytes) from the start of the SMB header to the start
78
+ # of the data field.
79
+ # @return [Integer]
80
+ define_field :data_offset, PacketGen::Types::Int16le
81
+ # @!attribute setup_count
82
+ # 8-bit number of setup words (ie 16-bit words) contained in {#setup} field.
83
+ define_field :setup_count, PacketGen::Types::Int8
84
+ # @!attribute rsv3
85
+ # 8-bit reserved field
86
+ # @return [Integer]
87
+ define_field :rsv3, PacketGen::Types::Int8
88
+ # @!attribute setup
89
+ # Array of 2-byte words.
90
+ # @return [Array]
91
+ define_field :setup, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:setup_count]) }
92
+ # @!attribute byte_count
93
+ # @return [Integer]
94
+ define_field :byte_count, PacketGen::Types::Int16le
95
+ # @!attribute padname
96
+ # 8-bit optional padding to align {#name} on a 2-byte boundary.
97
+ # @return [Integer]
98
+ define_field :padname, PacketGen::Types::Int8
99
+ # @!attribute name
100
+ # Pathname of the mailslot or named pipe.
101
+ # @return [String]
102
+ define_field :name, SMB::String
103
+ # @!attribute pad1
104
+ # Padding to align {#body} on 4-byte boundary.
105
+ # @return [String]
106
+ define_field :pad1, PacketGen::Types::String, default: "\0" * 4,
107
+ builder: ->(h, t) { t.new(length_from: -> { h.data_offset - SMB.new.sz - (h.offset_of(:name) + h[:name].sz) }) }
108
+ define_field :body, PacketGen::Types::String
109
+
110
+ # Give protocol name for this class
111
+ # @return [String]
112
+ def protocol_name
113
+ 'SMB::TransRequest'
114
+ end
115
+ end
116
+
117
+ # Transaction Response.
118
+ #
119
+ # See also {Blocks}, as {TransResponse} is a specialization of {Blocks#words}
120
+ # and {Blocks#bytes}.
121
+ # @author Sylvain Daubert
122
+ # @since 0.1.0
123
+ class TransResponse < PacketGen::Header::Base
124
+ # @!attribute word_count
125
+ # The size, in 2-byte words, of the SMB command parameters. It should
126
+ # be +14 + setup_count+.
127
+ # @return [Integer]
128
+ define_field :word_count, PacketGen::Types::Int8, default: 10
129
+ # @!attribute total_param_count
130
+ # The total number of transaction parameter bytes.
131
+ # @return [Integer]
132
+ define_field :total_param_count, PacketGen::Types::Int16le
133
+ # @!attribute total_data_count
134
+ # The total number of transaction data bytes.
135
+ # @return [Integer]
136
+ define_field :total_data_count, PacketGen::Types::Int16le
137
+ # @!attribute rsv1
138
+ # 16-bit reserved field
139
+ # @return [Integer]
140
+ define_field :rsv1, PacketGen::Types::Int16le, default: 0
141
+ # @!attribute param_count
142
+ # 16-bit number of transaction parameter bytes sent in this response.
143
+ # @return [Integer]
144
+ define_field :param_count, PacketGen::Types::Int16le
145
+ # @!attribute param_offset
146
+ # 16-bit offset (in bytes) from the start of the SMB header to the start of the
147
+ # transaction parameters.
148
+ # @return [Integer]
149
+ define_field :param_offset, PacketGen::Types::Int16le
150
+ # @!attribute param_displacement
151
+ # 16-bit offset (in bytes) relative to all of the transaction
152
+ # parameter bytes in this transaction response at which this block of
153
+ # parameter bytes SHOULD be placed.
154
+ # @return [Integer]
155
+ define_field :param_displacement, PacketGen::Types::Int16le
156
+ # @!attribute data_count
157
+ # 16-bit number of transaction data bytes sent in this response.
158
+ # @return [Integer]
159
+ define_field :data_count, PacketGen::Types::Int16le
160
+ # @!attribute data_offset
161
+ # 16-bit offset (in bytes) from the start of the SMB header to the start
162
+ # of the data field.
163
+ # @return [Integer]
164
+ define_field :data_offset, PacketGen::Types::Int16le
165
+ # @!attribute data_displacement
166
+ # 16-bit offset (in bytes) relative to all of the transaction data bytes in
167
+ # this transaction response at which this block of data bytes SHOULD be placed.
168
+ # @return [Integer]
169
+ define_field :data_displacement, PacketGen::Types::Int16le
170
+ # @!attribute setup_count
171
+ # 8-bit number of setup words (ie 16-bit words) contained in {#setup} field.
172
+ define_field :setup_count, PacketGen::Types::Int8
173
+ # @!attribute rsv3
174
+ # 8-bit reserved field
175
+ # @return [Integer]
176
+ define_field :rsv2, PacketGen::Types::Int8
177
+ # @!attribute setup
178
+ # Array of 2-byte words.
179
+ # @return [ArrayPacketGen::]
180
+ define_field :setup, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:setup_count]) }
181
+ # @!attribute byte_count
182
+ # @return [Integer]
183
+ define_field :byte_count, PacketGen::Types::Int16le
184
+ # @!attribute pad1
185
+ # Padding before {#body} to align it on 32-bit boundary
186
+ # @return [Integer]
187
+ define_field :pad1, PacketGen::Types::String, default: "\0" * 4,
188
+ builder: ->(h, t) { t.new(length_from: -> { h.data_offset - SMB.new.sz - (h.offset_of(:byte_count) + h[:byte_count].sz) }) }
189
+ define_field :body, PacketGen::Types::String
190
+
191
+ # Give protocol name for this class
192
+ # @return [String]
193
+ def protocol_name
194
+ 'SMB::TransResponse'
195
+ end
196
+ end
197
+
198
+ self.bind_command 'trans'
199
+ end
200
+ end
@@ -0,0 +1,5 @@
1
+ module PacketGen
2
+ module Plugin
3
+ SMB_VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'packetgen/plugin/smb_version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'packetgen-plugin-smb'
7
+ spec.version = PacketGen::Plugin::SMB_VERSION
8
+ spec.authors = ['Sylvain Daubert']
9
+ spec.email = ['sylvain.daubert@laposte.net']
10
+
11
+ spec.summary = %q{SMB plugin for packetgen.}
12
+ #spec.description = %q{TODO: Write a longer description or delete this line.}
13
+ spec.homepage = 'https://github.com/sdaubert/packetgen-plugin-smb'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(test|spec|features)/})
17
+ end
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'packetgen', '~>2.8', '>= 2.8.1'
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.16'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.7'
25
+ spec.add_development_dependency 'simplecov', '~> 0.16'
26
+ spec.add_development_dependency 'yard', '~> 0.9'
27
+
28
+
29
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: packetgen-plugin-smb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sylvain Daubert
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: packetgen
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.8'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.8.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.8'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.8.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.16'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.16'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '10.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '10.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.7'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.7'
75
+ - !ruby/object:Gem::Dependency
76
+ name: simplecov
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.16'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.16'
89
+ - !ruby/object:Gem::Dependency
90
+ name: yard
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.9'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.9'
103
+ description:
104
+ email:
105
+ - sylvain.daubert@laposte.net
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - ".gitignore"
111
+ - ".travis.yml"
112
+ - Gemfile
113
+ - LICENSE
114
+ - README.md
115
+ - Rakefile
116
+ - lib/packetgen-plugin-smb.rb
117
+ - lib/packetgen/plugin/smb.rb
118
+ - lib/packetgen/plugin/smb/blocks.rb
119
+ - lib/packetgen/plugin/smb/close.rb
120
+ - lib/packetgen/plugin/smb/filetime.rb
121
+ - lib/packetgen/plugin/smb/nt_create_and_x.rb
122
+ - lib/packetgen/plugin/smb/string.rb
123
+ - lib/packetgen/plugin/smb/trans.rb
124
+ - lib/packetgen/plugin/smb_version.rb
125
+ - packetgen-plugin-smb.gemspec
126
+ homepage: https://github.com/sdaubert/packetgen-plugin-smb
127
+ licenses: []
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.7.6
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: SMB plugin for packetgen.
149
+ test_files: []