Accessibility Features Overview

Windows contains many accessibility features to help users before they have logged onto a system, such as the on screen keyboard or narrator. These accessibility binaries can be manipulated to execute an arbitrary binary instead of the legitimate ones. 2 ways of doing this are by replacing a legitimate binary with cmd.exe or otherwise (to get a command prompt), or by adding a debugger to the files by using Image File Execution Options (IFEO) in the registry which then makes the debugger binary execute instead of the legitimate binary.

Accessibility Features Analysis

Lab Example

RED TEAM: ATTACK

The legitimate On Screen Keyboard (OSK.exe) has been replaced with a copy of cmd.exe, and a debugger has been set for DisplaySwitch.exe to instead execute calc.exe

T1015 - Accessibility Features 1

At the logon screen we can now enable the onscreen keyboard using the accessibility features icon in the bottom left to get a SYSTEM level command prompt. We can also use WIN + P to trigger the Display Switcher and run calc.exe as SYSTEM.

T1015 - Accessibility Features 2

The end result is whenever the computer boots we no longer need to logon and can simply spawn a command prompt. If wanted we could create a new user, or even run explorer.exe from the logon screen, but be warned it may have some unexpected outcomes due to the ‘SYSTEM’ account user profile.

T1015 - Accessibility Features 2

BLUE TEAM: DEFEND

Modification of Accessibility files can be detected using the below PowerShell. It will show the original name of accessibility files which may be a dead giveaway, and it also checks the registry for any attached debugger.

$path = "C:\Windows\System32\*";
$files = @("osk.exe", "DisplaySwitch.exe", "Magnify.exe","Narrator.exe","AtBroker.exe","utilman.exe","sethc.exe");
gci -path $path -include $files -force -ea 0| Get-ItemPropertyValue -Name VersionInfo | Select OriginalFilename;
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\*" | where-object {$_.Debugger -notlike $null } | Select PSChildName,Debugger;

For those without ‘Get-ItemPropertyValue’ you can achieve a similar result by chaining the findstr command.

$path = "C:\Windows\System32\*";
$files = @("osk.exe", "DisplaySwitch.exe", "Magnify.exe","Narrator.exe","AtBroker.exe","utilman.exe","sethc.exe");
gci -path $path -include $files -force -ea 0| FL VersionInfo | findstr OriginalFilename;
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\*" | where-object {$_.Debugger -notlike $null } | Select PSChildName,Debugger;