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/modules/auxiliary/admin/registry_security_descriptor.rb
Views: 11780
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::SMB::Client::Authenticated7include Msf::OptionalSession::SMB8include Msf::Util::WindowsRegistry910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Windows Registry Security Descriptor Utility',15'Description' => %q{16Read or write a Windows registry security descriptor remotely.1718In READ mode, the `FILE` option can be set to specify where the19security descriptor should be written to.2021The following format is used:22```23key: <registry key>24security_info: <security information>25sd: <security descriptor as a hex string>26```2728In WRITE mode, the `FILE` option can be used to specify the information29needed to write the security descriptor to the remote registry. The file must30follow the same format as described above.31},32'Author' => [33'Christophe De La Fuente'34],35'License' => MSF_LICENSE,36'Actions' => [37[ 'READ', { 'Description' => 'Read a Windows registry security descriptor' } ],38[ 'WRITE', { 'Description' => 'Write a Windows registry security descriptor' } ]39],40'Notes' => {41'Stability' => [CRASH_SAFE],42'Reliability' => [],43'SideEffects' => [CONFIG_CHANGES]44},45'DefaultAction' => 'READ'46)47)4849register_options(50[51OptString.new('KEY', [ false, 'Registry key to read or write' ]),52OptString.new('SD', [ false, 'Security Descriptor to write as a hex string' ], conditions: %w[ACTION == WRITE], regex: /^([a-fA-F0-9]{2})+$/),53OptInt.new('SECURITY_INFORMATION', [54true,55'Security Information to read or write (see '\56'https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/23e75ca3-98fd-4396-84e5-86cd9d40d343 '\57'(default: OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)',58RubySMB::Field::SecurityDescriptor::OWNER_SECURITY_INFORMATION |59RubySMB::Field::SecurityDescriptor::GROUP_SECURITY_INFORMATION |60RubySMB::Field::SecurityDescriptor::DACL_SECURITY_INFORMATION61]),62OptString.new('FILE', [63false,64'File path to store the security descriptor when reading or source file path used to write the security descriptor when writing'65])66]67)68end6970def do_connect71if session72print_status("Using existing session #{session.sid}")73client = session.client74self.simple = ::Rex::Proto::SMB::SimpleClient.new(client.dispatcher.tcp_socket, client: client)75simple.connect("\\\\#{simple.address}\\IPC$")76else77connect78begin79smb_login80rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e81fail_with(Module::Failure::NoAccess, "Unable to authenticate ([#{e.class}] #{e}).")82end83end8485report_service(86host: simple.address,87port: simple.port,88host_name: simple.client.default_name,89proto: 'tcp',90name: 'smb',91info: "Module: #{fullname}, last negotiated version: SMBv#{simple.client.negotiated_smb_version} (dialect = #{simple.client.dialect})"92)9394begin95@tree = simple.client.tree_connect("\\\\#{simple.address}\\IPC$")96rescue RubySMB::Error::RubySMBError => e97fail_with(Module::Failure::Unreachable, "Unable to connect to the remote IPC$ share ([#{e.class}] #{e}).")98end99100begin101@winreg = @tree.open_file(filename: 'winreg', write: true, read: true)102@winreg.bind(endpoint: RubySMB::Dcerpc::Winreg)103rescue RubySMB::Error::RubySMBError => e104fail_with(Module::Failure::Unreachable, "Error when connecting to 'winreg' interface ([#{e.class}] #{e}).")105end106end107108def run109do_connect110111case action.name112when 'READ'113action_read114when 'WRITE'115action_write116else117print_error("Unknown action #{action.name}")118end119ensure120@winreg.close if @winreg121@tree.disconnect! if @tree122# Don't disconnect the client if it's coming from the session so it can be reused123unless session124simple.client.disconnect! if simple&.client.is_a?(RubySMB::Client)125disconnect126end127end128129def action_read130fail_with(Failure::BadConfig, 'Unknown registry key, please set the `KEY` option') if datastore['KEY'].blank?131132sd = @winreg.get_key_security_descriptor(datastore['KEY'], datastore['SECURITY_INFORMATION'], bind: false)133print_good("Raw security descriptor for #{datastore['KEY']}: #{sd.bytes.map { |c| '%02x' % c.ord }.join}")134135unless datastore['FILE'].blank?136remote_reg = Msf::Util::WindowsRegistry::RemoteRegistry.new(@winreg, name: :sam)137remote_reg.save_to_file(datastore['KEY'], sd, datastore['SECURITY_INFORMATION'], datastore['FILE'])138print_good("Saved to file #{datastore['FILE']}")139end140end141142def action_write143if datastore['FILE'].blank?144fail_with(Failure::BadConfig, 'Unknown security descriptor, please set the `SD` option') if datastore['SD'].blank?145fail_with(Failure::BadConfig, 'Unknown registry key, please set the `KEY` option') if datastore['KEY'].blank?146sd = datastore['SD']147key = datastore['KEY']148security_info = datastore['SECURITY_INFORMATION']149else150print_status("Getting security descriptor info from file #{datastore['FILE']}")151remote_reg = Msf::Util::WindowsRegistry::RemoteRegistry.new(@winreg, name: :sam)152sd_info = remote_reg.read_from_file(datastore['FILE'])153sd = sd_info['sd']154key = sd_info['key']155security_info = sd_info['security_info']156vprint_line(" key: #{key}")157vprint_line(" security information: #{security_info}")158vprint_line(" security descriptor: #{sd}")159end160161sd = sd.chars.each_slice(2).map { |c| c.join.to_i(16).chr }.join162@winreg.set_key_security_descriptor(key, sd, security_info, bind: false)163print_good("Security descriptor set for #{key}")164rescue RubySMB::Dcerpc::Error::WinregError => e165fail_with(Failure::Unknown, "Unable to set the security descriptor for #{key}: #{e}")166end167end168169170