-->

Is it possible to click on Windows UAC dialog usin

2020-07-23 09:17发布

问题:

I'm working on a custom remote desktop in Java using java.awt.Robot on Windows 7. It all works apart from running a Command Prompt as an administrator. The UAC dialog appears, however button clicks are not accepted on the Yes button using mousePress()/mouseRelease(), neither are key presses with keyPress()/keyRelease(). The application is launched via a launch4j launcher in launcher rather than wrap mode.

Things I've done so far

Disabled secure desktop for UAC. This allowed the screen grabber part of the application to at least 'see' the prompt

  • Changed group policy to disable PromptOnSecureDesktop from UAC Group Policy Settings and Registry Key Settings

Followed Security Considerations for Assistive Technologies - this has allowed the remote desktop to interact with the Command Prompt once launched but not allowed pressing the Yes button.

  • added a manifest to launch4j specifying uiaccess=true
  • Signed the .exe using signtool.exe using self signed certificate generated with makecert.exe
  • Installed certificate as Trusted root certificate
  • Verified the .exe is marked as Trusted via Right click properties, Digital Signatures
  • Ensured .exe is in Trusted location, c:\Program Files (x86)\ in this case.
  • Tried to run part of the app as a service as Administrator - however I could not get a Windows Service that ran as Admin AND allowed access to the desktop - it seems only LocalSystem can do that...?

Questions

  • Is this ultimately possible?
  • Does the javaw.exe being a child process of the launch4j wrapper effect things? I've read through Windows Integrity Mechanism Design however I don't know how this effects launch4j.

Launch4j manifest file

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
            <requestedPrivileges>
            <requestedExecutionLevel level="asInvoker" uiAccess="true" />
        </requestedPrivileges>
    </security>
    </trustInfo>
</assembly>

回答1:

Short answer, Yes.

Understanding the problem

  • The uiAccess flag in the executable manifest appears to only apply to that exe not any child executions, i.e. if foo-launcher.exe is uiAccess enabled and starts javaw.exe that does not mean javaw.exe is uiAccess enabled.
  • The only reason I saw working correctly when running foo-launcher.exe as Administrator is that foo-launcher.exe also starts javaw.exe as Administrator which allows it enough integrity to not require the uiAccess check.
  • javaw.exe has its own internal manifest which contains uiAccess true
  • Internal manifests are prefered over external - see UAC: Manifest file is ignored and
  • A registry key exists to toggle behaviour of preferring internal over external manifests - see How to prevent embedded manifest from being used?
  • Launch4j generated executables uses CreateProcess which means executables are launched without manifest data, apparently ShellExecuteEx should be used instead - See How can I run a child process that requires elevation and wait?

Working around the problem

  • Extract the internal manifest from javaw.exe and place in same directory with the filename javaw.exe.manifest - this can be done manually as it is plain text - I used notepad++. Various 3rd party tools exist if you need automation.
  • Edit the manifest to uiAccess="true"
  • Apply the registry fix Registry fix

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide] "PreferExternalManifest"=dword:00000001

  • Touch javaw.exe to update the modification timestamp - otherwise changes are not picked up - this can be done with "copy /b javaw.exe +,," see Windows equivalent of the Linux command 'touch'?

  • Double check javaw.exe is installed in C:\Program Files, C:\Program Files (x86) or some other trusted location
  • Double check javaw.exe is signed with a trusted certificate.
  • Don't use launch4j generated executables - they simply don't support launching javaw.exe with uiAccess enabled, use Shortcut files (.lnk) or some other method built on ShellExecuteEx