Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/msf/util/windows_registry/remote_registry.rb
Views: 11784
module Msf1module Util2module WindowsRegistry34class RemoteRegistry5# Constants6ROOT_KEY = 0x2c7REG_NONE = 0x008REG_SZ = 0x019REG_EXPAND_SZ = 0x0210REG_BINARY = 0x0311REG_DWORD = 0x0412REG_MULTISZ = 0x0713REG_QWORD = 0x0b1415def initialize(winreg, name: nil, inline: false)16@winreg = winreg17@inline = inline18case name19when :sam20require_relative 'sam'21extend Sam22when :security23require_relative 'security'24extend Security25else26wlog("[Msf::Util::WindowsRegistry::RemoteRegistry] Unknown :name argument: #{name}") unless name.blank?27end28end2930def create_ace(sid)31access_mask = RubySMB::Dcerpc::Winreg::Regsam.new({32write_dac: 1,33read_control: 1,34key_enumerate_sub_keys: 1,35key_query_value: 136})37Rex::Proto::MsDtyp::MsDtypAce.new({38header: {39ace_type: Rex::Proto::MsDtyp::MsDtypAceType::ACCESS_ALLOWED_ACE_TYPE,40ace_flags: { container_inherit_ace: 1 }41},42body: {43access_mask: Rex::Proto::MsDtyp::MsDtypAccessMask.read(access_mask.to_binary_s),44sid: sid45}46})47end4849def backup_file_path50return @backup_file_path if @backup_file_path5152if ! File.directory?(Msf::Config.local_directory)53FileUtils.mkdir_p(Msf::Config.local_directory)54end55remote_host = @winreg.tree.client.dns_host_name56remote_host = @winreg.tree.client.dispatcher.tcp_socket.peerhost if remote_host.blank?57path = File.join(Msf::Config.local_directory, "remote_registry_sd_backup_#{remote_host}_#{Time.now.strftime("%Y%m%d%H%M%S")}.#{Rex::Text.rand_text_alpha(6)}.yml")58@backup_file_path = File.expand_path(path)59end6061def save_to_file(key, security_descriptor, security_information, path = backup_file_path)62sd_info = {63'key' => key,64'security_info' => security_information,65'sd' => security_descriptor.b.bytes.map { |c| '%02x' % c.ord }.join66}67File.open(path, 'w') do |fd|68fd.write(sd_info.to_yaml)69end70end7172def read_from_file(filepath)73sd_info = YAML.safe_load_file(filepath)74sd_info['security_info'] = sd_info['security_info'].to_i75sd_info76end7778def delete_backup_file(path = backup_file_path)79File.delete(path) if File.file?(path)80end8182def change_dacl(key, sid)83security_information =84RubySMB::Field::SecurityDescriptor::OWNER_SECURITY_INFORMATION |85RubySMB::Field::SecurityDescriptor::GROUP_SECURITY_INFORMATION |86RubySMB::Field::SecurityDescriptor::DACL_SECURITY_INFORMATION8788security_descriptor = @winreg.get_key_security_descriptor(key, security_information, bind: false)89dlog("[Msf::Util::WindowsRegistry::RemoteRegistry] Security descriptor for #{key}: #{security_descriptor.b.bytes.map { |c| '%02x' % c.ord }.join}")90save_to_file(key, security_descriptor, RubySMB::Field::SecurityDescriptor::DACL_SECURITY_INFORMATION)9192parsed_sd = Rex::Proto::MsDtyp::MsDtypSecurityDescriptor.read(security_descriptor)93ace = create_ace(sid)94parsed_sd.dacl.aces << ace95parsed_sd.dacl.acl_count += 196parsed_sd.dacl.acl_size += ace.num_bytes97dlog("[Msf::Util::WindowsRegistry::RemoteRegistry] New security descriptor for #{key}: #{parsed_sd.to_binary_s.b.bytes.map { |c| '%02x' % c.ord }.join}")9899@winreg.set_key_security_descriptor(key, parsed_sd.to_binary_s, RubySMB::Field::SecurityDescriptor::DACL_SECURITY_INFORMATION, bind: false)100101security_descriptor102rescue RubySMB::Dcerpc::Error::WinregError => e103elog("[Msf::Util::WindowsRegistry::RemoteRegistry] Error while changing DACL on key `#{key}`: #{e}")104end105106def restore_dacl(key, security_descriptor)107begin108dlog("[Msf::Util::WindowsRegistry::RemoteRegistry] Restoring DACL on key `#{key}`")109@winreg.set_key_security_descriptor(key, security_descriptor, RubySMB::Field::SecurityDescriptor::DACL_SECURITY_INFORMATION, bind: false)110rescue StandardError => e111elog(112"[Msf::Util::WindowsRegistry::RemoteRegistry] Error while restoring DACL on key `#{key}`: #{e}\n"\113"The original security descriptor has been saved in `#{backup_file_path}`. "\114"The auxiliary module `admin/registry_security_descriptor` can be used to "\115"restore the security descriptor from this file."116)117# Reset the `backup_file_path` instance variable to make sure a new118# backup filename will be generated. This way, this backup file won't119# be deleted the next time `#restore_dacl` is called.120@backup_file_path = nil121return122end123delete_backup_file124end125126def enum_values(key)127sd_backup = change_dacl(key, Rex::Proto::Secauthz::WellKnownSids::DOMAIN_ALIAS_SID_ADMINS) if @inline128@winreg.enum_registry_values(key, bind: false).map do |value|129value.to_s.encode(::Encoding::ASCII_8BIT)130end131ensure132restore_dacl(key, sd_backup) if @inline && sd_backup133end134135def enum_key(key)136sd_backup = change_dacl(key, Rex::Proto::Secauthz::WellKnownSids::DOMAIN_ALIAS_SID_ADMINS) if @inline137@winreg.enum_registry_key(key, bind: false).map do |key|138key.to_s.encode(::Encoding::ASCII_8BIT)139end140ensure141restore_dacl(key, sd_backup) if @inline && sd_backup142end143144def get_value(key, value_name = nil)145sd_backup = change_dacl(key, Rex::Proto::Secauthz::WellKnownSids::DOMAIN_ALIAS_SID_ADMINS) if @inline146root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)147root_key_handle = @winreg.open_root_key(root_key)148subkey_handle = @winreg.open_key(root_key_handle, sub_key)149begin150reg_value = @winreg.query_value(subkey_handle, value_name.nil? ? '' : value_name)151[reg_value.type.to_i, reg_value.data.to_s.b]152rescue RubySMB::Dcerpc::Error::WinregError153nil154end155ensure156@winreg.close_key(subkey_handle) if subkey_handle157@winreg.close_key(root_key_handle) if root_key_handle158restore_dacl(key, sd_backup) if @inline && sd_backup159end160161end162end163end164end165166167168169