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.



877
878
879
# File 'lib/rex/proto/ms_dtyp.rb', line 877

def dacl
  @dacl
end

#group_sidObject

Returns the value of attribute group_sid.



878
879
880
# File 'lib/rex/proto/ms_dtyp.rb', line 878

def group_sid
  @group_sid
end

#owner_sidObject

Returns the value of attribute owner_sid.



878
879
880
# File 'lib/rex/proto/ms_dtyp.rb', line 878

def owner_sid
  @owner_sid
end

#saclObject

Returns the value of attribute sacl.



877
878
879
# File 'lib/rex/proto/ms_dtyp.rb', line 877

def sacl
  @sacl
end

Class Method Details

.from_sddl_text(sddl_text, domain_sid:) ⇒ Object



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
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
# File 'lib/rex/proto/ms_dtyp.rb', line 725

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



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

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



841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
# File 'lib/rex/proto/ms_dtyp.rb', line 841

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



832
833
834
835
836
837
838
839
# File 'lib/rex/proto/ms_dtyp.rb', line 832

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



823
824
825
826
827
828
829
830
# File 'lib/rex/proto/ms_dtyp.rb', line 823

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



710
711
712
713
714
715
716
717
718
719
720
721
722
723
# File 'lib/rex/proto/ms_dtyp.rb', line 710

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



858
859
860
861
862
863
864
865
# File 'lib/rex/proto/ms_dtyp.rb', line 858

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



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

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