HaO 2023-07-13:

Goal

Send keystrokes from a TCL application to other applications and the Windows login password field

Application

My company authors integration software where data scanned by barcode scanners are handled and sent to other programs.

First tests

Using TWAPI, one may send keystrokes to the foreground program. Here is a simple test line sending an "a" (this is over-complicated, TWAPI can do it better, but only for testing procedures with maximum control):

twapi::send_input [list [list key 65 0x1e]]

I wrap the script using basekits from Ashok [L1 ], test file is "tclkit-gui-8_6_13-twapi-4_7_2-x86-max.exe". My platform is Windows 10 64 bit with German localisation.

If the program is started as normal user, one can send keystrokes to other user programs, but not to elevated programs. If the program is started with Adminstrator rights, you can send keystrokes to all user programs and administrator programs.

If you lock the screen, you may open the login screen of Windows while the program is running. You can change from the picture screen to the password entry screen using the program. But you can not enter any data to the password entry field to unlock the session.

The situation is the same, if you run the program as a Windows service.

Assistive technology

Assistive technology may help you to handle your computer and allows programs to send keystrokes to any program including the login password screen. You may test this using the on-screen keyboard. It also works within the login password screen.

The important point is the Integrity Level (IL) of the application, which will allow or disallow to send keystrokes [L2 ]. Assistive technology is allowed to get a higher IL [L3 ].

Programs for assistive technology have the manifest switch uiAccess set to true [L4 ]. The scandard wish and starkit manifest contains the following trust information (use ResHacker.exe to extract).

    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
            <requestedPrivileges>
                <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
            </requestedPrivileges>
        </security>
    </trustInfo>

You may use ResHacker.exe to change uiAccess="true". The result was a smaller and not starting any more executable. So, I asked Ashok, to build a starkit with this set from scratch. The starting error message is normal and will always show-up, if the executable is not signed with a certifificate which goes to the trusted root certificates.

The error message looks in German localization like that:

win_error_message_uiaccess_true_not_signed.png

A translation of the text would be: "A reference evaluation was returned from the server.".

The requirements for assistive technology programs are: [L5 ]

  • Executable signed with a certificate which goes to a trusted root certificate
  • Secure location, for example "C:\program files(x86)\..."
  • Manifest with uiAcess = true

Code signing

So, lets attack code signing [L6 ].

Paul has given a recipe to sign starkits on this page: SDX under Windows. That works great.

My company has purchased an EV certificate from GlobalSign, which took two weeks of processing time and costs around 300$ per year. It is on a secure USB stick. I also downloaded all the "cross certificates" and made a double-click on them to get them in the certificate store of my computer.

I use the signtool provided by MS-VisualStudio and enter the following command:

"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe" sign /n "Elmicron Dr. Harald Oehlmann GmbH" /tr http://timestamp.globalsign.com/tsa/r6advanced1 /td SHA256 starkit.exe

The "/n" is required, as I now have a lot of certificates on the computer and I shall choose the right one, otherwise "/a" may be used.

After entering the USB stick password, the comment "signing succeeded" is shown. Now, the executable may be executed, even with "uiAccess=true".

Secure position

The program is moved to "c:\program files(x86)" using "InnoSetup" (what is also signed with the same key by the setup change:

[Setup]
SignTool=MsSign $f

and Tools->Signtool configuration->MsSign:

"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe" sign /n "Elmicron Dr. Harald Oehlmann GmbH" /tr http://timestamp.globalsign.com/tsa/r6advanced1 /td SHA256  /fd SHA256 $p

)

Test

Now, it is possible to send keystrokes from a normal user process to administrator processes. So, something is happenning and a certain aim is acheved.

When starting the program with Administrator rights, the login password can still not be changed. This does not work as user program or as a service with an administrator or LocalSystemAdmin user.

Register assistive technology program

Assistive technology programs may be registered within the system as explained here: [L7 ].

I tried to acheve this and setting the required registry keys using inno setup, but it did not work for me. The registry keys just disappear for me. I will try again.

Pointers

Here is the set of pointers about this issue:

  • Credential providers: [L8 ] -> for new ways to login, but not to enhance present logins
  • Run with Windows welcome process: [L9 ]
  • Driver method [L10 ]

Ideas welcome

If others have any ideas - you are welcome. I want to thank ET99 for his constant testing in the clt thread "MS-Windows: Send keys to login/unlock page/Asisstive Technology Application" started on 2023-06-07. I also want to thank Ashok for his constant support.