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.



829
830
831
# File 'lib/rex/proto/ms_dtyp.rb', line 829

def dacl
  @dacl
end

#group_sidObject

Returns the value of attribute group_sid.



830
831
832
# File 'lib/rex/proto/ms_dtyp.rb', line 830

def group_sid
  @group_sid
end

#owner_sidObject

Returns the value of attribute owner_sid.



830
831
832
# File 'lib/rex/proto/ms_dtyp.rb', line 830

def owner_sid
  @owner_sid
end

#saclObject

Returns the value of attribute sacl.



829
830
831
# File 'lib/rex/proto/ms_dtyp.rb', line 829

def sacl
  @sacl
end

Class Method Details

.from_sddl_text(sddl_text, domain_sid:) ⇒ Object



677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
# File 'lib/rex/proto/ms_dtyp.rb', line 677

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 SDDLParseError.new('extra owner SID')
      end

      sd.owner_sid = MsDtypSid.from_sddl_text(value, domain_sid: domain_sid)
    when 'G'
      if sd.group_sid.present?
        raise SDDLParseError.new('extra group SID')
      end

      sd.group_sid = MsDtypSid.from_sddl_text(value, domain_sid: domain_sid)
    when 'D'
      raise SDDLParseError.new('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 SDDLParseError.new('unknown DACL flag: ' + flag)
        end
      end

      next unless access_control

      sd.dacl = MsDtypAcl.new
      sd.dacl.aces = self.aces_from_sddl_text(value.delete_prefix(flags), domain_sid: domain_sid)
    when 'S'
      raise SDDLParseError.new('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 SDDLParseError.new('unknown SACL flag: ' + flag)
        end
      end

      next unless access_control

      sd.sacl = MsDtypAcl.new
      sd.sacl.aces = self.aces_from_sddl_text(value.delete_prefix(flags), domain_sid: domain_sid)
    else
      raise SDDLParseError.new('unknown directive: ' + part[0])
    end
  end

  sd
end

Instance Method Details

#dacl_to_sddl_text(domain_sid: nil) ⇒ Object



647
648
649
650
651
652
653
654
655
656
657
658
659
660
# File 'lib/rex/proto/ms_dtyp.rb', line 647

def dacl_to_sddl_text(domain_sid: nil)
  sddl_text = ''

  if !dacl?
    sddl_text << 'NO_ACCESS_CONTROL'
  else
    sddl_text << 'P' if control.pd == 1
    sddl_text << 'AR' if control.dc == 1
    sddl_text << 'AI' if control.di == 1
    sddl_text << dacl.aces.map { |ace| "(#{ace.to_sddl_text(domain_sid: domain_sid)})" }.join
  end

  sddl_text
end

#do_read(val) ⇒ Object



793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
# File 'lib/rex/proto/ms_dtyp.rb', line 793

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



784
785
786
787
788
789
790
791
# File 'lib/rex/proto/ms_dtyp.rb', line 784

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

#initialize_shared_instanceObject



775
776
777
778
779
780
781
782
# File 'lib/rex/proto/ms_dtyp.rb', line 775

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

#sacl_to_sddl_text(domain_sid: nil) ⇒ Object



662
663
664
665
666
667
668
669
670
671
672
673
674
675
# File 'lib/rex/proto/ms_dtyp.rb', line 662

def sacl_to_sddl_text(domain_sid: nil)
  sddl_text = ''

  if !sacl?
    sddl_text << 'NO_ACCESS_CONTROL'
  else
    sddl_text << 'P' if control.ps == 1
    sddl_text << 'AR' if control.sc == 1
    sddl_text << 'AI' if control.si == 1
    sddl_text << sacl.aces.map { |ace| "(#{ace.to_sddl_text(domain_sid: domain_sid)})" }.join
  end

  sddl_text
end

#snapshotObject



810
811
812
813
814
815
816
817
# File 'lib/rex/proto/ms_dtyp.rb', line 810

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

#to_sddl_text(domain_sid: nil) ⇒ Object



637
638
639
640
641
642
643
644
645
# File 'lib/rex/proto/ms_dtyp.rb', line 637

def to_sddl_text(domain_sid: nil)
  sddl_text = ''
  sddl_text << "O:#{owner_sid.to_sddl_text(domain_sid: domain_sid)}" if owner_sid?
  sddl_text << "G:#{group_sid.to_sddl_text(domain_sid: domain_sid)}" if group_sid?
  sddl_text << "D:#{dacl_to_sddl_text(domain_sid: domain_sid)}" if dacl?
  sddl_text << "S:#{sacl_to_sddl_text(domain_sid: domain_sid)}" if sacl?

  sddl_text
end