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.



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

def dacl
  @dacl
end

#group_sidObject

Returns the value of attribute group_sid.



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

def group_sid
  @group_sid
end

#owner_sidObject

Returns the value of attribute owner_sid.



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

def owner_sid
  @owner_sid
end

#saclObject

Returns the value of attribute sacl.



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

def sacl
  @sacl
end

Class Method Details

.from_sddl_text(sddl_text, domain_sid:) ⇒ Object



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
805
# File 'lib/rex/proto/ms_dtyp.rb', line 726

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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