Class: Rex::Proto::MsDtyp::MsDtypSecurityDescriptor

Inherits:
BinData::Record
  • Object
show all
Defined in:
lib/rex/proto/ms_dtyp.rb

Overview

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#daclObject

Returns the value of attribute dacl.



719
720
721
# File 'lib/rex/proto/ms_dtyp.rb', line 719

def dacl
  @dacl
end

#group_sidObject

Returns the value of attribute group_sid.



719
720
721
# File 'lib/rex/proto/ms_dtyp.rb', line 719

def group_sid
  @group_sid
end

#owner_sidObject

Returns the value of attribute owner_sid.



719
720
721
# File 'lib/rex/proto/ms_dtyp.rb', line 719

def owner_sid
  @owner_sid
end

#saclObject

Returns the value of attribute sacl.



719
720
721
# File 'lib/rex/proto/ms_dtyp.rb', line 719

def sacl
  @sacl
end

Class Method Details

.from_sddl_text(sddl_text, domain_sid:) ⇒ Object



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/rex/proto/ms_dtyp.rb', line 274

def self.from_sddl_text(sddl_text, domain_sid:)
  sacl_set = dacl_set = false
  sd = self.new
  sddl_text = sddl_text.dup.gsub(/\s/, '')  # start by removing all whitespace
  sddl_text.scan(/([OGDS]:(?:.(?!:))*)/).each do |part,|
    component, _, value = part.partition(':')
    case component
    when 'O'
      if sd.owner_sid.present?
        raise RuntimeError.new('SDDL parse error on extra owner SID')
      end

      sd.owner_sid = self.parse_sddl_sid(value, domain_sid: domain_sid)
    when 'G'
      if sd.group_sid.present?
        raise RuntimeError.new('SDDL parse error on extra group SID')
      end

      sd.group_sid = self.parse_sddl_sid(value, domain_sid: domain_sid)
    when 'D'
      raise RuntimeError.new('SDDL parse error on extra DACL') if dacl_set

      value.upcase!
      dacl_set = true
      access_control = true
      flags = value.split('(', 2).first || ''
      flags.split(/(P|AR|AI|NO_ACCESS_CONTROL)/).each do |flag|
        case flag
        when 'AI'
          sd.control.di = true
        when 'AR'
          sd.control.dc = true
        when 'P'
          sd.control.pd = true
        when 'NO_ACCESS_CONTROL'
          access_control = false
        when ''
        else
          raise RuntimeError.new('SDDL parse error on unknown DACL flag: ' + flag)
        end
      end

      next unless access_control

      sd.dacl = MsDtypAcl.new
      sd.dacl.aces = self.parse_sddl_aces(value.delete_prefix(flags), domain_sid: domain_sid)
    when 'S'
      raise RuntimeError.new('SDDL parse error on extra SACL') if sacl_set

      value.upcase!
      sacl_set = true
      access_control = true
      flags = value.split('(', 2).first || ''
      flags.split(/(P|AR|AI|NO_ACCESS_CONTROL)/).each do |flag|
        case flag
        when 'AI'
          sd.control.si = true
        when 'AR'
          sd.control.sc = true
        when 'P'
          sd.control.ps = true
        when 'NO_ACCESS_CONTROL'
          access_control = false
        when ''
        else
          raise RuntimeError.new('SDDL parse error on unknown SACL flag: ' + flag)
        end
      end

      next unless access_control

      sd.sacl = MsDtypAcl.new
      sd.sacl.aces = self.parse_sddl_aces(value.delete_prefix(flags), domain_sid: domain_sid)
    else
      raise RuntimeError.new('SDDL parse error on unknown directive: ' + part[0])
    end
  end

  sd
end

Instance Method Details

#do_read(val) ⇒ Object



693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
# File 'lib/rex/proto/ms_dtyp.rb', line 693

def do_read(val)
  value = super
  if offset_owner != 0
    @owner_sid = MsDtypSid.read(buffer[offset_owner - buffer.rel_offset..])
  end
  if offset_group != 0
    @group_sid = MsDtypSid.read(buffer[offset_group - buffer.rel_offset..])
  end
  if offset_sacl != 0
    @sacl = MsDtypAcl.read(buffer[offset_sacl - buffer.rel_offset..])
  end
  if offset_dacl != 0
    @dacl = MsDtypAcl.read(buffer[offset_dacl - buffer.rel_offset..])
  end
  value
end

#initialize_instanceObject



684
685
686
687
688
689
690
691
# File 'lib/rex/proto/ms_dtyp.rb', line 684

def initialize_instance
  value = super
  @owner_sid = get_parameter(:owner_sid)
  @group_sid = get_parameter(:group_sid)
  @sacl = get_parameter(:sacl)
  @dacl = get_parameter(:dacl)
  value
end

#initialize_shared_instanceObject



675
676
677
678
679
680
681
682
# File 'lib/rex/proto/ms_dtyp.rb', line 675

def initialize_shared_instance
  # define accessor methods for the custom fields to expose the same API as BinData
  define_field_accessors_for2(:owner_sid)
  define_field_accessors_for2(:group_sid)
  define_field_accessors_for2(:sacl)
  define_field_accessors_for2(:dacl)
  super
end

#snapshotObject



710
711
712
713
714
715
716
717
# File 'lib/rex/proto/ms_dtyp.rb', line 710

def snapshot
  snap = super
  snap[:owner_sid] ||= owner_sid&.snapshot
  snap[:group_sid] ||= group_sid&.snapshot
  snap[:sacl] ||= sacl&.snapshot
  snap[:dacl] ||= dacl&.snapshot
  snap
end