Class: Msf::Util::WindowsRegistry::RemoteRegistry
- Inherits:
-
Object
- Object
- Msf::Util::WindowsRegistry::RemoteRegistry
- Defined in:
- lib/msf/util/windows_registry/remote_registry.rb
Constant Summary collapse
- ROOT_KEY =
Constants
0x2c
- REG_NONE =
0x00
- REG_SZ =
0x01
- REG_EXPAND_SZ =
0x02
- REG_BINARY =
0x03
- REG_DWORD =
0x04
- REG_MULTISZ =
0x07
- REG_QWORD =
0x0b
Instance Method Summary collapse
- #backup_file_path ⇒ Object
- #change_dacl(key, sid) ⇒ Object
- #create_ace(sid) ⇒ Object
- #delete_backup_file(path = backup_file_path) ⇒ Object
- #enum_key(key) ⇒ Object
- #enum_values(key) ⇒ Object
- #get_value(key, value_name = nil) ⇒ Object
-
#initialize(winreg, name: nil, inline: false) ⇒ RemoteRegistry
constructor
A new instance of RemoteRegistry.
- #read_from_file(filepath) ⇒ Object
- #restore_dacl(key, security_descriptor) ⇒ Object
- #save_to_file(key, security_descriptor, security_information, path = backup_file_path) ⇒ Object
Constructor Details
#initialize(winreg, name: nil, inline: false) ⇒ RemoteRegistry
Returns a new instance of RemoteRegistry.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 16 def initialize(winreg, name: nil, inline: false) @winreg = winreg @inline = inline case name when :sam require_relative 'sam' extend Sam when :security require_relative 'security' extend Security else wlog("[Msf::Util::WindowsRegistry::RemoteRegistry] Unknown :name argument: #{name}") unless name.blank? end end |
Instance Method Details
#backup_file_path ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 50 def backup_file_path return @backup_file_path if @backup_file_path if ! File.directory?(Msf::Config.local_directory) FileUtils.mkdir_p(Msf::Config.local_directory) end remote_host = @winreg.tree.client.dns_host_name remote_host = @winreg.tree.client.dispatcher.tcp_socket.peerhost if remote_host.blank? path = 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") @backup_file_path = File.(path) end |
#change_dacl(key, sid) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 83 def change_dacl(key, sid) security_information = RubySMB::Field::SecurityDescriptor::OWNER_SECURITY_INFORMATION | RubySMB::Field::SecurityDescriptor::GROUP_SECURITY_INFORMATION | RubySMB::Field::SecurityDescriptor::DACL_SECURITY_INFORMATION security_descriptor = @winreg.get_key_security_descriptor(key, security_information, bind: false) dlog("[Msf::Util::WindowsRegistry::RemoteRegistry] Security descriptor for #{key}: #{security_descriptor.b.bytes.map { |c| '%02x' % c.ord }.join}") save_to_file(key, security_descriptor, RubySMB::Field::SecurityDescriptor::DACL_SECURITY_INFORMATION) parsed_sd = Rex::Proto::MsDtyp::MsDtypSecurityDescriptor.read(security_descriptor) ace = create_ace(sid) parsed_sd.dacl.aces << ace parsed_sd.dacl.acl_count += 1 parsed_sd.dacl.acl_size += ace.num_bytes dlog("[Msf::Util::WindowsRegistry::RemoteRegistry] New security descriptor for #{key}: #{parsed_sd.to_binary_s.b.bytes.map { |c| '%02x' % c.ord }.join}") @winreg.set_key_security_descriptor(key, parsed_sd.to_binary_s, RubySMB::Field::SecurityDescriptor::DACL_SECURITY_INFORMATION, bind: false) security_descriptor rescue RubySMB::Dcerpc::Error::WinregError => e elog("[Msf::Util::WindowsRegistry::RemoteRegistry] Error while changing DACL on key `#{key}`: #{e}") end |
#create_ace(sid) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 31 def create_ace(sid) access_mask = RubySMB::Dcerpc::Winreg::Regsam.new({ write_dac: 1, read_control: 1, key_enumerate_sub_keys: 1, key_query_value: 1 }) Rex::Proto::MsDtyp::MsDtypAce.new({ header: { ace_type: Rex::Proto::MsDtyp::MsDtypAceType::ACCESS_ALLOWED_ACE_TYPE, ace_flags: { container_inherit_ace: 1 } }, body: { access_mask: Rex::Proto::MsDtyp::MsDtypAccessMask.read(access_mask.to_binary_s), sid: sid } }) end |
#delete_backup_file(path = backup_file_path) ⇒ Object
79 80 81 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 79 def delete_backup_file(path = backup_file_path) File.delete(path) if File.file?(path) end |
#enum_key(key) ⇒ Object
136 137 138 139 140 141 142 143 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 136 def enum_key(key) sd_backup = change_dacl(key, Rex::Proto::Secauthz::WellKnownSids::DOMAIN_ALIAS_SID_ADMINS) if @inline @winreg.enum_registry_key(key, bind: false).map do |key| key.to_s.encode(::Encoding::ASCII_8BIT) end ensure restore_dacl(key, sd_backup) if @inline && sd_backup end |
#enum_values(key) ⇒ Object
127 128 129 130 131 132 133 134 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 127 def enum_values(key) sd_backup = change_dacl(key, Rex::Proto::Secauthz::WellKnownSids::DOMAIN_ALIAS_SID_ADMINS) if @inline @winreg.enum_registry_values(key, bind: false).map do |value| value.to_s.encode(::Encoding::ASCII_8BIT) end ensure restore_dacl(key, sd_backup) if @inline && sd_backup end |
#get_value(key, value_name = nil) ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 145 def get_value(key, value_name = nil) sd_backup = change_dacl(key, Rex::Proto::Secauthz::WellKnownSids::DOMAIN_ALIAS_SID_ADMINS) if @inline root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2) root_key_handle = @winreg.open_root_key(root_key) subkey_handle = @winreg.open_key(root_key_handle, sub_key) begin reg_value = @winreg.query_value(subkey_handle, value_name.nil? ? '' : value_name) [reg_value.type.to_i, reg_value.data.to_s.b] rescue RubySMB::Dcerpc::Error::WinregError nil end ensure @winreg.close_key(subkey_handle) if subkey_handle @winreg.close_key(root_key_handle) if root_key_handle restore_dacl(key, sd_backup) if @inline && sd_backup end |
#read_from_file(filepath) ⇒ Object
73 74 75 76 77 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 73 def read_from_file(filepath) sd_info = YAML.safe_load_file(filepath) sd_info['security_info'] = sd_info['security_info'].to_i sd_info end |
#restore_dacl(key, security_descriptor) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 107 def restore_dacl(key, security_descriptor) begin dlog("[Msf::Util::WindowsRegistry::RemoteRegistry] Restoring DACL on key `#{key}`") @winreg.set_key_security_descriptor(key, security_descriptor, RubySMB::Field::SecurityDescriptor::DACL_SECURITY_INFORMATION, bind: false) rescue StandardError => e elog( "[Msf::Util::WindowsRegistry::RemoteRegistry] Error while restoring DACL on key `#{key}`: #{e}\n"\ "The original security descriptor has been saved in `#{backup_file_path}`. "\ "The auxiliary module `admin/registry_security_descriptor` can be used to "\ "restore the security descriptor from this file." ) # Reset the `backup_file_path` instance variable to make sure a new # backup filename will be generated. This way, this backup file won't # be deleted the next time `#restore_dacl` is called. @backup_file_path = nil return end delete_backup_file end |
#save_to_file(key, security_descriptor, security_information, path = backup_file_path) ⇒ Object
62 63 64 65 66 67 68 69 70 71 |
# File 'lib/msf/util/windows_registry/remote_registry.rb', line 62 def save_to_file(key, security_descriptor, security_information, path = backup_file_path) sd_info = { 'key' => key, 'security_info' => security_information, 'sd' => security_descriptor.b.bytes.map { |c| '%02x' % c.ord }.join } File.open(path, 'w') do |fd| fd.write(sd_info.to_yaml) end end |