packetgen-plugin-smb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []