packetgen-plugin-smb 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -1
  3. data/Gemfile +0 -3
  4. data/README.md +18 -1
  5. data/lib/packetgen-plugin-smb.rb +1 -0
  6. data/lib/packetgen/plugin/gssapi.rb +3 -2
  7. data/lib/packetgen/plugin/netbios.rb +17 -0
  8. data/lib/packetgen/plugin/netbios/datagram.rb +108 -0
  9. data/lib/packetgen/plugin/netbios/name.rb +64 -0
  10. data/lib/packetgen/plugin/netbios/session.rb +71 -0
  11. data/lib/packetgen/plugin/smb.rb +2 -2
  12. data/lib/packetgen/plugin/smb/browser.rb +6 -6
  13. data/lib/packetgen/plugin/smb/browser/domain_announcement.rb +0 -5
  14. data/lib/packetgen/plugin/smb/browser/host_announcement.rb +8 -5
  15. data/lib/packetgen/plugin/smb/browser/local_master_announcement.rb +0 -5
  16. data/lib/packetgen/plugin/smb/close/request.rb +1 -1
  17. data/lib/packetgen/plugin/smb/close/response.rb +1 -1
  18. data/lib/packetgen/plugin/smb/filetime.rb +20 -1
  19. data/lib/packetgen/plugin/smb/ntcreateandx/request.rb +1 -1
  20. data/lib/packetgen/plugin/smb/ntcreateandx/response.rb +1 -1
  21. data/lib/packetgen/plugin/smb/trans/request.rb +1 -1
  22. data/lib/packetgen/plugin/smb/trans/response.rb +1 -1
  23. data/lib/packetgen/plugin/smb2.rb +7 -5
  24. data/lib/packetgen/plugin/smb2/negotiate/context.rb +12 -24
  25. data/lib/packetgen/plugin/smb2/negotiate/request.rb +6 -6
  26. data/lib/packetgen/plugin/smb2/negotiate/response.rb +7 -6
  27. data/lib/packetgen/plugin/smb2/session_setup/request.rb +1 -1
  28. data/lib/packetgen/plugin/smb2/session_setup/response.rb +1 -1
  29. data/lib/packetgen/plugin/smb_version.rb +1 -1
  30. data/packetgen-plugin-smb.gemspec +1 -1
  31. metadata +8 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc233d3dcb94925757db9c4f5dde9647f97cce4d1e73001f3bbbcb41309ed435
4
- data.tar.gz: 50d2ebf353a37d073bae3f6f7458057e4db8a7f2b5c0932094e1820056ab2746
3
+ metadata.gz: f3f0164d4068b3b829fac802f5ce944c33bf86275fb90aa46150e57926a236f3
4
+ data.tar.gz: 001d57bf0ec000e0e738b25d1116ea0b73bc7a2c0de61b68e6c16ef75a130d4b
5
5
  SHA512:
6
- metadata.gz: 5862b573e7b9bba3826f10ef8e1ac8bbb34817e49f93338223ca5fbfcd0ad19cbeb65b64428fc1832c7603fe8a5a5cfc32cb6ac31d63c2e66de4a518ab89de6d
7
- data.tar.gz: bb9a3e27eb4c36e3b6197d6450bef4efd73af1e3a0849c07383ea32924d155e0e21f975f7c91b4092ba70cce3d03cb368f92d38311a1a6585c946b5c1462dae5
6
+ metadata.gz: 661c09099b29c3c747e5b4d1831b05fb3945123e1d5ff7aaabc053221c100ed1113fd04a72af5fdbc245a9d0789419f6b6fc1c8a37a558c64da53ef1b30c4e8e
7
+ data.tar.gz: 06b857556ca716b954a4fb935ec3e6e91ab2a0416442b31e3ad7e9eec7631fe33d6c3bb96814fd949fbffd2d58c97fc80fbbd18dd4b66cd5a603663f58169bb9
@@ -1,4 +1,3 @@
1
- TargetRubyVersion: 2.3
2
1
  Layout/SpaceAroundEqualsInParameterDefault:
3
2
  EnforcedStyle: no_space
4
3
  Lint/EmptyWhen:
data/Gemfile CHANGED
@@ -1,6 +1,3 @@
1
1
  source 'https://rubygems.org'
2
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
3
  gemspec
data/README.md CHANGED
@@ -3,7 +3,20 @@
3
3
 
4
4
  # Packetgen::Plugin::SMB
5
5
 
6
- This is a plugin for [PacketGen gem](https://github.com/sdaubert/packetgen). It adds some support for SMB protocol suite.
6
+ This is a plugin for [PacketGen gem](https://github.com/sdaubert/packetgen). It adds some support for SMB protocol suite:
7
+
8
+ * SMB:
9
+ * SMB common header,
10
+ * Close command,
11
+ * NtCreateAndX command,
12
+ * Trans command,
13
+ * Browser subprotocol,
14
+ * SMB2:
15
+ * SMB2 common header (support 2.x and 3.x dialects),
16
+ * Negotiate command,
17
+ * SessionSetup command,
18
+ * GSSAPI, used to transport negotiation over SMB2 commands.
19
+
7
20
 
8
21
  ## Installation
9
22
 
@@ -25,6 +38,10 @@ Or install it yourself as:
25
38
 
26
39
  TODO
27
40
 
41
+ ## See also
42
+
43
+ API documentation: http://www.rubydoc.info/gems/packetgen-plugin-smb
44
+
28
45
  ## License
29
46
 
30
47
  MIT License (see [LICENSE](https://github.com/sdaubert/packetgen-plugin-smb/blob/master/LICENSE))
@@ -8,5 +8,6 @@
8
8
  require 'packetgen'
9
9
  require_relative 'packetgen/plugin/smb_version'
10
10
  require_relative 'packetgen/plugin/gssapi'
11
+ require_relative 'packetgen/plugin/netbios'
11
12
  require_relative 'packetgen/plugin/smb'
12
13
  require_relative 'packetgen/plugin/smb2'
@@ -86,7 +86,7 @@ module PacketGen::Plugin
86
86
  'accept-incomplete' => 1,
87
87
  'reject' => 2,
88
88
  'request-mic' => 3
89
- }
89
+ }.freeze
90
90
  sequence :token, explicit: 1, class: :context, constructed: true,
91
91
  content: [enumerated(:negstate, enum: NEG_STATES, explicit: 0, class: :context, constructed: true, optional: true),
92
92
  objectid(:supported_mech, explicit: 1, class: :context, constructed: true, optional: true),
@@ -106,8 +106,9 @@ module PacketGen::Plugin
106
106
  def initialize(args={})
107
107
  token = args.delete(:token)
108
108
  super
109
- self[:gssapi].chosen = (token == :init) ? 0 : 1
109
+ self[:gssapi].chosen = token == :init ? 0 : 1
110
110
  end
111
+
111
112
  # Populate Object from +str+
112
113
  # @param [String] str
113
114
  # @return [self]
@@ -0,0 +1,17 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen-plugin-smb 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
+ # Module to group all NetBIOS headers
10
+ # @author Sylvain Daubert
11
+ module NetBIOS
12
+ end
13
+ end
14
+
15
+ require_relative 'netbios/name'
16
+ require_relative 'netbios/session'
17
+ require_relative 'netbios/datagram'
@@ -0,0 +1,108 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen-plugin-smb 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
+ # Module to group all NetBIOS headers
10
+ # @author Sylvain Daubert
11
+ module NetBIOS
12
+ # NetBIOS Session Service messages.
13
+ # @author Sylvain Daubert
14
+ class Datagram < PacketGen::Header::Base
15
+ # Give protocol name
16
+ # @return [String]
17
+ def self.protocol_name
18
+ 'NetBIOS::Datagram'
19
+ end
20
+
21
+ # Port number for NetBIOS Session Service over TCP
22
+ UDP_PORT = 138
23
+
24
+ # Datagram packet types
25
+ TYPES = {
26
+ 'direct_unique' => 0x10,
27
+ 'direct_group' => 0x11,
28
+ 'broadcast' => 0x12,
29
+ 'error' => 0x13,
30
+ 'query_request' => 0x14,
31
+ 'positive_query_resp' => 0x15,
32
+ 'negative_query_resp' => 0x16,
33
+ }.freeze
34
+
35
+ # @!attribute type
36
+ # 8-bit session packet type
37
+ # @return [Integer]
38
+ define_field :type, PacketGen::Types::Int8Enum, enum: TYPES
39
+ # @!attribute flags
40
+ # 8-bit flags
41
+ # @return [Integer]
42
+ define_field :flags, PacketGen::Types::Int8
43
+ # @!attribute dgm_id
44
+ # 16-bit next transaction ID for datagrams
45
+ # @return [Integer]
46
+ define_field :dgm_id, PacketGen::Types::Int16
47
+ # @!attribute src_ip
48
+ # Source IP address
49
+ # @return [IP::Addr]
50
+ define_field :src_ip, PacketGen::Header::IP::Addr
51
+ # @!attribute src_port
52
+ # Source port
53
+ # @return [IP::Addr]
54
+ define_field :src_port, PacketGen::Types::Int16
55
+ # @!attribute dgm_length
56
+ # Length of data + second level of encoded names. Not present in error datagram.
57
+ # @return [Integer]
58
+ define_field :dgm_length, PacketGen::Types::Int16, optional: ->(h) { h.type != 0x13 }
59
+ # @!attribute packet_offset
60
+ # Not present in error datagram.
61
+ # @return [Integer]
62
+ define_field :packet_offset, PacketGen::Types::Int16, optional: ->(h) { h.type != 0x13 }
63
+ # @!attribute error_code
64
+ # Error code. Only present in error datagrams.
65
+ # @return [Integer]
66
+ define_field :error_code, PacketGen::Types::Int16, optional: ->(h) { h.type == 0x13 }
67
+ # @!attribute src_name
68
+ # NetBIOS source name. Only present in direct_unique, direct_group and broadcast datagrams.
69
+ # @return []
70
+ define_field :src_name, Name, default: '', optional: ->(h) { (h.type >= 0x10) && (h.type <= 0x12) }
71
+ # @!attribute dst_name
72
+ # NetBIOS destination name. Present in all but error datagrams.
73
+ # @return []
74
+ define_field :dst_name, Name, default: '', optional: ->(h) { h.type != 0x13 }
75
+ # @!attribute body
76
+ # User data. Ony present in direct_unique, direct_group and broadcast datagrams.
77
+ # @return [String]
78
+ define_field :body, PacketGen::Types::String, optional: ->(h) { (h.type >= 0x10) && (h.type <= 0x12) }
79
+
80
+ # @!attribute :rsv
81
+ # 4-bit rsv field. 4 upper bits of {#flags}
82
+ # @return [Integer]
83
+ # @!attribute :snt
84
+ # 2-bit SNT (Source end-Node Type) field from {#flags}.
85
+ # @return [Integer]
86
+ # @!attribute f
87
+ # First packet flag. If set then this is first
88
+ # (and possibly only) fragment of NetBIOS datagram.
89
+ # @return [Boolean]
90
+ # @!attribute m
91
+ # More flag. If set then more NetBIOS datagram
92
+ # fragments follow.
93
+ # @return [Boolean]
94
+ define_bit_fields_on :flags, :rsv, 4, :snt, 2, :f, :m
95
+
96
+ # Compute and set {#dgm_length} field
97
+ # @return [Integer] calculated length
98
+ def calc_length
99
+ length = self[:body].sz
100
+ length += self[:src_name].sz if present?(:src_name)
101
+ length += self[:dst_name].sz if present?(:dst_name)
102
+ self.dgm_length = length
103
+ end
104
+ end
105
+ PacketGen::Header.add_class Datagram
106
+ PacketGen::Header::UDP.bind Datagram, dport: Datagram::UDP_PORT, sport: Datagram::UDP_PORT
107
+ end
108
+ end
@@ -0,0 +1,64 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen-plugin-smb 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
+ # Module to group all NetBIOS headers
10
+ # @author Sylvain Daubert
11
+ module NetBIOS
12
+ # NetBIOS Name.
13
+ # @author Sylvain Daubert
14
+ class Name < PacketGen::Header::DNS::Name
15
+ # Size, in bytes, of an encoded NetBIOS name
16
+ ENCODED_NAME_SIZE = 32
17
+
18
+ # Read a NetBIOS name from a string
19
+ # @param [String] str
20
+ # @return [Name] self
21
+ def from_human(str)
22
+ clear
23
+ return self if str.nil?
24
+
25
+ encoded_name = encode_name(str)
26
+ super(encoded_name)
27
+ end
28
+
29
+ # Get a human readable string
30
+ # @return [String]
31
+ def to_human
32
+ encoded_name = super
33
+ decode_name(encoded_name)
34
+ end
35
+
36
+ private
37
+
38
+ def encode_name(name)
39
+ basename, *scope_id = name.split('.')
40
+ basename = '' if basename.nil?
41
+ scope_id = scope_id.join('.')
42
+ encoded_name = +''
43
+ basename.each_byte do |byte|
44
+ a = (byte >> 4) + 0x41
45
+ b = (byte & 0xf) + 0x41
46
+ encoded_name << [a, b].pack('C2')
47
+ end
48
+ encoded_name << 'CA' * ((ENCODED_NAME_SIZE - encoded_name.size) / 2) if encoded_name.size < ENCODED_NAME_SIZE
49
+ encoded_name << ".#{scope_id}" if scope_id
50
+ encoded_name
51
+ end
52
+
53
+ def decode_name(encoded_name)
54
+ name = +''
55
+ encoded_name.partition('.').first.scan(/../).map do |duo|
56
+ a = (duo[0].ord - 0x41) & 0xf
57
+ b = (duo[1].ord - 0x41) & 0xf
58
+ name << (a << 4 | b).chr
59
+ end
60
+ name.strip
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,71 @@
1
+ # This file is part of PacketGen
2
+ # See https://github.com/sdaubert/packetgen-plugin-smb 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
+ # Module to group all NetBIOS headers
10
+ # @author Sylvain Daubert
11
+ module NetBIOS
12
+ # NetBIOS Session Service messages.
13
+ # @author Sylvain Daubert
14
+ class Session < PacketGen::Header::Base
15
+ # Give protocol name
16
+ # @return [String]
17
+ def self.protocol_name
18
+ 'NetBIOS::Session'
19
+ end
20
+
21
+ # Port number for NetBIOS Session Service over TCP
22
+ TCP_PORT = 139
23
+ # Port number for NetBIOS Session Service over TCP (mainly used yb {SMB2})
24
+ TCP_PORT2 = 445
25
+
26
+ # Session packet types
27
+ TYPES = {
28
+ 'message' => 0,
29
+ 'request' => 0x81,
30
+ 'positive_response' => 0x82,
31
+ 'negative_response' => 0x83,
32
+ 'retarget_response' => 0x84,
33
+ 'keep_alive' => 0x85,
34
+ }.freeze
35
+
36
+ # @!attribute type
37
+ # 8-bit session packet type
38
+ # @return [Integer]
39
+ define_field :type, PacketGen::Types::Int8Enum, enum: TYPES
40
+ # @!attribute length
41
+ # 17-bit session packet length
42
+ # @return [Integer]
43
+ define_field :length, PacketGen::Types::Int24
44
+ # @!attribute body
45
+ # @return [String]
46
+ define_field :body, PacketGen::Types::String
47
+
48
+ # Compute and set {#length} field
49
+ # @return [Integer] calculated length
50
+ def calc_length
51
+ PacketGen::Header::Base.calculate_and_set_length(self, header_in_size: false)
52
+ end
53
+
54
+ # @api private
55
+ # @note This method is used internally by PacketGen and should not be
56
+ # directly called
57
+ # @since 2.7.0 Set TCP sport according to bindings, only if sport is 0.
58
+ # Needed by new bind API.
59
+ def added_to_packet(packet)
60
+ return unless packet.is? 'TCP'
61
+ return unless packet.tcp.sport.zero?
62
+ packet.tcp.sport = TCP_PORT
63
+ end
64
+ end
65
+ PacketGen::Header.add_class Session
66
+ PacketGen::Header::TCP.bind Session, dport: Session::TCP_PORT
67
+ PacketGen::Header::TCP.bind Session, sport: Session::TCP_PORT
68
+ PacketGen::Header::TCP.bind Session, dport: Session::TCP_PORT2
69
+ PacketGen::Header::TCP.bind Session, sport: Session::TCP_PORT2
70
+ end
71
+ end
@@ -190,8 +190,8 @@ module PacketGen::Plugin
190
190
  end
191
191
  end
192
192
  PacketGen::Header.add_class SMB
193
- PacketGen::Header::NetBIOS::Session.bind SMB, body: ->(val) { val.nil? ? SMB::MARKER : val[0..3] == SMB::MARKER }
194
- PacketGen::Header::NetBIOS::Datagram.bind SMB, body: ->(val) { val.nil? ? SMB::MARKER : val[0..3] == SMB::MARKER }
193
+ NetBIOS::Session.bind SMB, body: ->(val) { val.nil? ? SMB::MARKER : val[0..3] == SMB::MARKER }
194
+ NetBIOS::Datagram.bind SMB, body: ->(val) { val.nil? ? SMB::MARKER : val[0..3] == SMB::MARKER }
195
195
  end
196
196
 
197
197
  require_relative 'smb/string'
@@ -11,6 +11,12 @@ module PacketGen::Plugin
11
11
  # See subclasses.
12
12
  # @author Sylvain Daubert
13
13
  class Browser < PacketGen::Header::Base
14
+ # Give protocol name for this class
15
+ # @return [String]
16
+ def self.protocol_name
17
+ 'SMB::Browser'
18
+ end
19
+
14
20
  OPCODES = {
15
21
  'HostAnnouncement' => 1,
16
22
  'HostAnnouncementReq' => 2,
@@ -57,12 +63,6 @@ module PacketGen::Plugin
57
63
  end
58
64
  end
59
65
 
60
- # Give protocol name for this class
61
- # @return [String]
62
- def protocol_name
63
- 'SMB::Browser'
64
- end
65
-
66
66
  # Callback called when a Browser header is added to a packet.
67
67
  # Here, add +#smb_browser+ method as a shortcut to existing
68
68
  # +#smb_browser_*+ method.
@@ -20,11 +20,6 @@ module PacketGen::Plugin
20
20
  alias browser_conf_ver_min os_ver_min
21
21
  alias machine_group server_name
22
22
  alias local_master_name comment
23
-
24
- # @return [String]
25
- def protocol_name
26
- 'SMB::Browser::DomainAnnouncement'
27
- end
28
23
  end
29
24
  PacketGen::Header.add_class DomainAnnouncement
30
25
  SMB::Trans::Request.bind DomainAnnouncement, name: '\\MAILSLOT\\BROWSE', body: ->(v) { v[0] == OPCODES['DomainAnnouncement'] }
@@ -14,6 +14,14 @@ module PacketGen::Plugin
14
14
  # specify the types of resources and services it supports.
15
15
  # @author Sylvain Daubert
16
16
  class HostAnnouncement < Browser
17
+ # @return [String]
18
+ def self.protocol_name
19
+ return @protocol_name if @protocol_name
20
+
21
+ basename = to_s.sub(/^.*::/, '')
22
+ @protocol_name = "SMB::Browser::#{basename}"
23
+ end
24
+
17
25
  remove_field :body
18
26
  update_field :opcode, default: 1
19
27
  # @!attribute update_count
@@ -58,11 +66,6 @@ module PacketGen::Plugin
58
66
  # Null-terminated ASCII string.
59
67
  # @return [String]
60
68
  define_field :comment, PacketGen::Types::CString
61
-
62
- # @return [String]
63
- def protocol_name
64
- 'SMB::Browser::HostAnnouncement'
65
- end
66
69
  end
67
70
  PacketGen::Header.add_class HostAnnouncement
68
71
  SMB::Trans::Request.bind HostAnnouncement, name: '\\MAILSLOT\\BROWSE', body: ->(v) { v[0] == OPCODES['HostAnnouncement'] }
@@ -15,11 +15,6 @@ module PacketGen::Plugin
15
15
  # @author Sylvain Daubert
16
16
  class LocalMasterAnnouncement < HostAnnouncement
17
17
  update_field :opcode, default: 15
18
-
19
- # @return [String]
20
- def protocol_name
21
- 'SMB::Browser::LocalMasterAnnouncement'
22
- end
23
18
  end
24
19
  PacketGen::Header.add_class LocalMasterAnnouncement
25
20
  SMB::Trans::Request.bind LocalMasterAnnouncement, name: '\\MAILSLOT\\BROWSE', body: ->(v) { v[0] == OPCODES['LocalMasterAnnouncement'] }
@@ -36,7 +36,7 @@ module PacketGen::Plugin
36
36
 
37
37
  # Give protocol name for this class
38
38
  # @return [String]
39
- def protocol_name
39
+ def self.protocol_name
40
40
  'SMB::Close::Request'
41
41
  end
42
42
  end
@@ -27,7 +27,7 @@ module PacketGen::Plugin
27
27
 
28
28
  # Give protocol name for this class
29
29
  # @return [String]
30
- def protocol_name
30
+ def self.protocol_name
31
31
  'SMB::Close::Response'
32
32
  end
33
33
  end
@@ -17,6 +17,11 @@ module PacketGen::Plugin
17
17
  # Numbers of 100ns in one second
18
18
  ONE_SEC = 10_000_000
19
19
 
20
+ # String to format time
21
+ FORMAT_TIME_STR = '%Y-%m-%d %H:%M:%S.%9N %Z'
22
+ # String to parse time
23
+ PARSE_TIME_STR = '%Y-%m-%d %H:%M:%S.%N %Z'
24
+
20
25
  # @param [Hash] options
21
26
  # @option options [Integer] :filetime
22
27
  # @option options [Time] :time
@@ -49,10 +54,24 @@ module PacketGen::Plugin
49
54
  if no_time?
50
55
  'no time'
51
56
  else
52
- @time.strftime("%Y-%m-%d %H:%M:%S.%9N %Z")
57
+ @time.strftime(FORMAT_TIME_STR)
53
58
  end
54
59
  end
55
60
 
61
+ # @return [self]
62
+ def from_human(str)
63
+ return self if str.nil?
64
+
65
+ @time = if str == 'no time'
66
+ Time.at(NO_TIME)
67
+ else
68
+ DateTime.strptime(str, PARSE_TIME_STR).to_time
69
+ end
70
+ @int.value = time2filetime
71
+
72
+ self
73
+ end
74
+
56
75
  # Get filetime integer value
57
76
  # @return [Integer]
58
77
  def to_i
@@ -141,7 +141,7 @@ module PacketGen::Plugin
141
141
 
142
142
  # Give protocol name for this class
143
143
  # @return [String]
144
- def protocol_name
144
+ def self.protocol_name
145
145
  'SMB::NtCreateAndX::Request'
146
146
  end
147
147
 
@@ -101,7 +101,7 @@ module PacketGen::Plugin
101
101
 
102
102
  # Give protocol name for this class
103
103
  # @return [String]
104
- def protocol_name
104
+ def self.protocol_name
105
105
  'SMB::NtCreateAndX::Response'
106
106
  end
107
107
 
@@ -112,7 +112,7 @@ module PacketGen::Plugin
112
112
 
113
113
  # Give protocol name for this class
114
114
  # @return [String]
115
- def protocol_name
115
+ def self.protocol_name
116
116
  'SMB::Trans::Request'
117
117
  end
118
118
  end
@@ -85,7 +85,7 @@ module PacketGen::Plugin
85
85
 
86
86
  # Give protocol name for this class
87
87
  # @return [String]
88
- def protocol_name
88
+ def self.protocol_name
89
89
  'SMB::Trans::Response'
90
90
  end
91
91
  end
@@ -148,6 +148,12 @@ module PacketGen::Plugin
148
148
  self.bind kresponse, command: SMB2::COMMANDS[command], flags: ->(v) { v.nil? ? 0 : (v & 1 == 1) }
149
149
  end
150
150
 
151
+ # Invert {#flags_response?}
152
+ # @return [self]
153
+ def reply!
154
+ self.flags_response = !flags_response?
155
+ end
156
+
151
157
  # @return [String]
152
158
  def inspect
153
159
  super do |attr|
@@ -166,13 +172,9 @@ module PacketGen::Plugin
166
172
  end
167
173
  end
168
174
  end
169
- # TODO: move this in netbios file when packetgen3 will be out
170
- PacketGen::Header::TCP.bind PacketGen::Header::NetBIOS::Session, dport: 445
171
- PacketGen::Header::TCP.bind PacketGen::Header::NetBIOS::Session, sport: 445
172
175
 
173
176
  PacketGen::Header.add_class SMB2
174
- PacketGen::Header::NetBIOS::Session.bind SMB2, body: ->(val) { val.nil? ? SMB2::MARKER : val[0..3] == SMB2::MARKER }
175
- PacketGen::Header::NetBIOS::Datagram.bind SMB2, body: ->(val) { val.nil? ? SMB2::MARKER : val[0..3] == SMB2::MARKER }
177
+ NetBIOS::Session.bind SMB2, body: ->(val) { val.nil? ? SMB2::MARKER : val[0..3] == SMB2::MARKER }
176
178
  end
177
179
 
178
180
  require_relative 'smb2/base'
@@ -47,31 +47,11 @@ module PacketGen::Plugin
47
47
  # @!attribute pad
48
48
  # Padding to align next context on a 8-byte offset
49
49
  # @return [String]
50
- define_field :pad, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: -> { v = 8 - (h.offset_of(:data) + h.data_length) % 8; v == 8 ? 0 : v }) }
50
+ define_field :pad, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: -> { (8 - (h.offset_of(:data) + h.data_length) % 8) % 8 }) }
51
51
 
52
52
  # @private
53
53
  alias old_read read
54
54
 
55
- # Populate object from a binary string
56
- # @param [String] str
57
- # @return [Context]
58
- def read(str)
59
- return self if str.nil?
60
- if self.instance_of? Context
61
- self[:type].read str[0, 2]
62
- name = TYPES.key(type)
63
- return old_read(str) if name.nil?
64
-
65
- klassname = name.downcase.capitalize.gsub(/_(\w)/) { $1.upcase }
66
- return old_read(str) unless Negotiate.const_defined? klassname
67
-
68
- klass = Negotiate.const_get(klassname)
69
- klass.new.read str
70
- else
71
- old_read str
72
- end
73
- end
74
-
75
55
  # Get human-readable type
76
56
  # @return [String]
77
57
  def human_type
@@ -104,7 +84,7 @@ module PacketGen::Plugin
104
84
  # Salt value for hash
105
85
  # @return [String]
106
86
  define_field_before :pad, :salt, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: h[:salt_length]) }
107
- update_field :pad, builder: ->(h, t) { t.new(length_from: -> { v = 8 - (h.offset_of(:salt) + h.salt_length) % 8; v == 8 ? 0 : v }) }
87
+ update_field :pad, builder: ->(h, t) { t.new(length_from: -> { (8 - (h.offset_of(:salt) + h.salt_length) % 8) % 8 }) }
108
88
  end
109
89
 
110
90
  class EncryptionCap < Context
@@ -118,14 +98,22 @@ module PacketGen::Plugin
118
98
  # algorithms
119
99
  # @return [PacketGen::Types::ArrayOfInt16le]
120
100
  define_field_before :pad, :ciphers, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:hash_alg_count]) }
121
- update_field :pad, builder: ->(h, t) { t.new(length_from: -> { v = 8 - (h.offset_of(:cipher_count) + h[:cipher_count].sz) % 8; v == 8 ? 0 : v }) }
101
+ update_field :pad, builder: ->(h, t) { t.new(length_from: -> { (8 - (h.offset_of(:cipher_count) + h[:cipher_count].sz) % 8) % 8 }) }
122
102
  end
123
103
 
124
104
  # Array of {Context}
125
105
  # @author Sylvain Daubert
126
106
  class ArrayOfContext < PacketGen::Types::Array
127
107
  set_of Context
108
+
109
+ private
110
+
111
+ def real_type(ctx)
112
+ name = Context::TYPES.key(ctx.type)
113
+ klassname = name.downcase.capitalize.gsub(/_(\w)/) { $1.upcase }
114
+ Negotiate.const_defined?(klassname) ? Negotiate.const_get(klassname) : ctx.class
115
+ end
128
116
  end
129
117
  end
130
118
  end
131
- end
119
+ end
@@ -124,6 +124,12 @@ module PacketGen::Plugin
124
124
  # @return [ArrayOfContext]
125
125
  define_field :context_list, ArrayOfContext, builder: ->(h, t) { t.new(counter: h[:context_count]) }
126
126
 
127
+ # Protocol name
128
+ # @return [String]
129
+ def self.protocol_name
130
+ 'SMB2::Negotiate::Request'
131
+ end
132
+
127
133
  # @return [String]
128
134
  def inspect
129
135
  super do |attr|
@@ -154,12 +160,6 @@ module PacketGen::Plugin
154
160
  def calc_length
155
161
  self.context_offset = SMB2.new.sz + offset_of(:context_list)
156
162
  end
157
-
158
- # Protocol name
159
- # @return [String]
160
- def protocol_name
161
- 'SMB2::Negotiate::Request'
162
- end
163
163
  end
164
164
  end
165
165
  end
@@ -152,10 +152,17 @@ module PacketGen::Plugin
152
152
  # @return [ArrayOfContext]
153
153
  define_field :context_list, ArrayOfContext, builder: ->(h, t) { t.new(counter: h[:context_count]) }
154
154
 
155
+ # Protocol name
156
+ # @return [String]
157
+ def self.protocol_name
158
+ 'SMB2::Negotiate::Response'
159
+ end
160
+
155
161
  # @return [String]
156
162
  def inspect
157
163
  super do |attr|
158
164
  next unless attr == :capabilities
165
+
159
166
  value = bits_on(attr).reject { |_, v| v > 1 }
160
167
  .keys
161
168
  .select { |b| send("#{b}?") }
@@ -178,12 +185,6 @@ module PacketGen::Plugin
178
185
  self.buffer_length = buffer.sz
179
186
  context_list.each { |ctx| ctx.calc_length if ctx.respond_to? :calc_length }
180
187
  end
181
-
182
- # Protocol name
183
- # @return [String]
184
- def protocol_name
185
- 'SMB2::Negotiate::Response'
186
- end
187
188
  end
188
189
  end
189
190
  end
@@ -89,7 +89,7 @@ module PacketGen::Plugin
89
89
 
90
90
  # Protocol name
91
91
  # @return [String]
92
- def protocol_name
92
+ def self.protocol_name
93
93
  'SMB2::SessionSetup::Request'
94
94
  end
95
95
  end
@@ -60,7 +60,7 @@ module PacketGen::Plugin
60
60
 
61
61
  # Protocol name
62
62
  # @return [String]
63
- def protocol_name
63
+ def self.protocol_name
64
64
  'SMB2::SessionSetup::Response'
65
65
  end
66
66
  end
@@ -1,5 +1,5 @@
1
1
  module PacketGen
2
2
  module Plugin
3
- SMB_VERSION = "0.3.0"
3
+ SMB_VERSION = "0.4.0"
4
4
  end
5
5
  end
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.required_ruby_version = '>= 2.3.0'
21
21
 
22
- spec.add_dependency 'packetgen', '~>2.8', '>= 2.8.7'
22
+ spec.add_dependency 'packetgen', '~>3.0'
23
23
  spec.add_dependency 'rasn1', '~>0.6', '>= 0.6.7'
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 1.16'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: packetgen-plugin-smb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Daubert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-18 00:00:00.000000000 Z
11
+ date: 2018-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: packetgen
@@ -16,20 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.8'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 2.8.7
19
+ version: '3.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '2.8'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 2.8.7
26
+ version: '3.0'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: rasn1
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +130,10 @@ files:
136
130
  - Rakefile
137
131
  - lib/packetgen-plugin-smb.rb
138
132
  - lib/packetgen/plugin/gssapi.rb
133
+ - lib/packetgen/plugin/netbios.rb
134
+ - lib/packetgen/plugin/netbios/datagram.rb
135
+ - lib/packetgen/plugin/netbios/name.rb
136
+ - lib/packetgen/plugin/netbios/session.rb
139
137
  - lib/packetgen/plugin/smb.rb
140
138
  - lib/packetgen/plugin/smb/blocks.rb
141
139
  - lib/packetgen/plugin/smb/browser.rb