Jump to content

Make your program "super topmost" -- UIAccess UDF


tubaba
 Share

Recommended Posts

Firstly, this idea comes from https://github.com/killtimer0/uiaccess

 

2023-07-07_132813.jpg.1e6e7d05e63671d13d8f2aeaf8bc479d.jpg

Normally, you cannot use the screenshot tool to capture the start menu or the Task manager. But here, if you use the screenshot tool with the UIAccess attribute, you can do this.As shown in the above figure


This project is used to obtain UIAccess permissions. It can enable your program window to obtain a higher Z order, such as higher than the Task manager. It is on the same level as the on-screen keyboard. It can be used to solve the problem of window occlusion when making screen markers/recording tools.

 

Quote

Normally, In order for the program to have UIAccess properties, it is necessary to set<requestedExecutionLevel level="asInvoker" uiAccess="true"/>in the program manifest

https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-account-control-allow-uiaccess-applications-to-prompt-for-elevation-without-using-the-secure-desktop

UIA programs must be highly trusted. To be considered trusted, a UIA program must be digitally signed. By default, UIA programs can be run only from the following protected paths:

..\Program Files\ (and subfolders)
..\Program Files (x86)\ (and subfolders, in 64-bit versions of Windows only)
..\Windows\System32\

 

 

But here, you don't need to do this!You can put the program anywhere on the hard disk without restrictions. The only thing you need is Administrator permission!

The 'TokenUIAccess' attribute is present in the process token, which means that after we raise the permission, we can set this permission through' SetTokenInformation 'to bypass the digital signature and the specified installation path.


But after some testing, I finally found that to complete this operation, I must have the 'SeTcbPrivilege' permission, so one solution is to 'steal' a token from other system processes in order to obtain the permission. However, modifying the UIAccess of a running program is invalid, so in the end, a new process can only be started. Although this may have some flaws, it still has better more practical than digital signatures.

 

 

This UDF requires administrator privileges, but you can still use it to create a process with standard user privileges and uiaccess attributes

USAGE: Just include it into your scripts.

Example:

#include <GUIConstantsEx.au3>
#include <_uiaccess.au3>

Local $hGUI = GUICreate("Example", 300, 300)

Local $Checkbox1 = GUICtrlCreateCheckbox("TOPMOST", 10, 50, 340, 20)

GUISetState(@SW_SHOW, $hGUI)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $Checkbox1
            If BitAND(GUICtrlRead($Checkbox1), $GUI_CHECKED) Then
                WinSetOnTop($hGUI, "", 1)
            Else
                WinSetOnTop($hGUI, "", 0)
            EndIf
    EndSwitch
WEnd

20230711 add: Process SessionId check.

 

20240221 fix:Some handles were not properly closed 

_uiaccess.au3

Edited by tubaba
Link to comment
Share on other sites

Hi! I have some questions.

1)  The author from github compares TokenSessionId of our process with TokenSessionId of winlogon.exe, but You dont. Is it not necessary?

2)  The author from github creates process like this:

GetStartupInfo(&si);
if (CreateProcessAsUser(hTokenUIAccess, NULL, GetCommandLine(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))

You add "-s" to command line, add flags BitOR($NORMAL_PRIORITY_CLASS, $CREATE_NEW_CONSOLE) and add   @SW_SHOW to $tStartupInfo structure.

Why?

3) If You disabled uac  then Func __CheckForUIAccess() will not work.

But You can check TokenUIAccess with creating gui and calling GetWindowBand.

On autohotkey like this:

   Gui, +HWNDhGui +AlwaysOnTop
   DllCall("GetWindowBand", "uptr", hGui, "uint*", band)
   Gui, Destroy
   hGui := ""
   if (band = 1)   ; ZBID_DESKTOP

 

Link to comment
Share on other sites

1.I used a method to verify that the username is SYSTEM and the process name is winlogon.exe to ensure that it is the desired SID

By using the SetThreadToken function to assign simulation tokens to its main thread, its own thread has the same permissions as winlogon.exe.Using this method, you can freely create processes with SYSTEM permissions, even trustedistaller permissions.

2023-07-11_094819.thumb.jpg.707542a47e5e11b81421ffd7b7ff9f0a.jpg

2.Sorry, this UDF was stripped from another script of mine, so this cmdline parameter is not necessary.

3.I don't understand what disabled uac means, like this? If that's the case, it will work properly on my computer regardless of whether it is disabled or not.

2023-07-11_094216.jpg.95d9872c0c088835782489c520551119.jpg

Link to comment
Share on other sites

1) Yes, It is good that You check that process runs from system account, but if there are several users on PC, then there are will be several winlogon.exe from system account with different TokenSessionIds. Will it be ok, that We will use token from different SessionId?

2) I tested on autohotkey. When You install it has an option run with ui access.

If I run next script with ahk ui access and uac disabled then I will get TokenUIAccess = 0, but band = 2.

Therefore I said that this function does not work.

Code on ahk:

DllCall("advapi32.dll\OpenProcessToken", "ptr", DllCall("GetCurrentProcess", "ptr"), "uint", 0x0008, "ptr*", hTokenSelf)   ; TOKEN_QUERY
DllCall("advapi32\GetTokenInformation", "ptr", hTokenSelf, "uint", 26, "uint*", TokenUIAccess, "uint", 4, "uint*", ReturnLength)
msgbox % TokenUIAccess
Gui, +HWNDhGui +AlwaysOnTop
DllCall("GetWindowBand", "ptr", hGui, "uint*", band)
msgbox % band

Could You please give example how to create process with system and trustedinstaller permissions?

Also I do not understand why do We need to call LookupPrivilegeValue, PrivilegeCheck and RevertToSelf functions.

Edited by malcev
Link to comment
Share on other sites

43 minutes ago, malcev said:

1) Yes, It is good that You check that process runs from system account, but if there are several users on PC, then there are will be several winlogon.exe from system account with different TokenSessionIds. Will it be ok, that We will use token from different SessionId?

This is a good idea, I will try to join it. now the UDF is update.

 

about SYSTEM Rights

This is just an example, and there is not too much error checking. Creating a TI process is a bit more complicated

1. Copy the token for winlogon.exe

2. Use SetThreadToken to assign  winlogon.exe's simulation tokens to threads

3. Start the TrustedInstaller service

4. Copy the token for TrustedInstaller.exe

5. Use TrustedInstaller's token create a new process

You can try to complete it yourself according to the above ideas

system permissions.au3

Link to comment
Share on other sites

4 hours ago, malcev said:

Also I do not understand why do We need to call LookupPrivilegeValue, PrivilegeCheck and RevertToSelf functions.

LookupPrivilegeValue Ensure that you have this privilege in your system

After calling SetThreadToken, calling RevertToSelf at the appropriate time to terminate is just a habit, in order to prevent the original process from having undue privileges, although the original process will exit after successful simulation.

You will find that the privileges required to access winlogon.exe and lsass.exe are different, even if they are both system processes.

maybe need SeDebugPrivilege to access lsass.exe, winlogon.exe is not.

Link to comment
Share on other sites

  • 5 months later...
  • 1 month later...
On 12/22/2023 at 8:03 AM, Andreik said:

@tubaba In _CreateUIAccessToken() you missed to close the token handle? You close the handle just when _Security__GetTokenInformation() failed but what if doesn't?

It's my problem, not closing the handle correctly may cause a memory leak

Link to comment
Share on other sites

  • 5 months later...

tubaba, you check that winlogon.exe is running from system with LookupAccountSid, but I think it will not work with non-english OS.

You can use IsWellKnownSid instead of LookupAccountSid.

On autohotkey it will be like that:

if DllCall("advapi32\IsWellKnownSid", "ptr", pSid, "uint", WinLocalSystemSid := 22)

   msgbox SystemSid

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...