Runas de-elevated user

Windows specific forum
jassing
Addict
Addict
Posts: 1774
Joined: Wed Feb 17, 2010 12:00 am

Runas de-elevated user

Post by jassing »

I have an exe that runs as a UAC admin (aka: elevated)
I need that exe to launch a process as a non-elevated application.

Any ideas?
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Runas de-elevated user

Post by Little John »

I have asked this question already some time ago. :-)
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4663
Joined: Sun Apr 12, 2009 6:27 am

Re: Runas de-elevated user

Post by RASHAD »

Hi
Try any one of the next
I myself prefer the Shim tech.

Code: Select all

;**********************************************************
cmd /min /C "set __COMPAT_LAYER=RUNASINVOKER && start "" %1"
;*************  Compatibility Shim  ****************************
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\example\\application.exe"="RunAsInvoker"
Egypt my love
fryquez
Enthusiast
Enthusiast
Posts: 367
Joined: Mon Dec 21, 2015 8:12 pm

Re: Runas de-elevated user

Post by fryquez »

You need a normal user token and pass it to CreateProcessAsUser

Code: Select all

#SAFER_LEVELID_FULLYTRUSTED = $40000
#SAFER_LEVELID_CONSTRAINED  = $10000
#SAFER_LEVELID_NORMALUSER   = $20000
#SAFER_LEVELID_UNTRUSTED    = $01000
#SAFER_SCOPEID_USER         = 2
#SAFER_LEVEL_OPEN           = 1

Procedure RunAsNormalUser(iCommand, iWorkingdir = 0, iShowflag = #SW_NORMAL)
  
  Protected hSafer, hToken, si.STARTUPINFO, pi.PROCESS_INFORMATION, lReturn
  
  If SaferCreateLevel_(#SAFER_SCOPEID_USER,
                       #SAFER_LEVELID_NORMALUSER,
                       #SAFER_LEVEL_OPEN,
                       @hSafer,
                       0)
    
    If SaferComputeTokenFromLevel_(hSafer,
                                   0,
                                   @hToken,
                                   0,
                                   0)
      
      
      si\cb = SizeOf(STARTUPINFO)
      si\dwFlags = #STARTF_USESHOWWINDOW
      si\wShowWindow = iShowflag
      
      lReturn = CreateProcessAsUser_(hToken,
                                     0,
                                     iCommand,
                                     0,
                                     0,
                                     0,
                                     0,
                                     0,
                                     0,
                                     @si,
                                     @pi)
    EndIf
    SaferCloseLevel_(hSafer)
    
  EndIf
  
  ProcedureReturn lReturn
  
EndProcedure
jassing
Addict
Addict
Posts: 1774
Joined: Wed Feb 17, 2010 12:00 am

Re: Runas de-elevated user

Post by jassing »

RASHAD wrote:Hi
Try any one of the next
I myself prefer the Shim tech.
Thank you Rashad.
I will play around with it -- the program may need to be "run as" administrator by others, so I'm not sure if that'll be a good way -- but I will try it & see what happens. I'll try the cmd way too. Thanks.
fryquez wrote:You need a normal user token and pass it to CreateProcessAsUser
Thanks - pb 5.70 beta2 and 5.62 (both x64) didn't like any of the safe* functions.
I tried with a quick "import" but that didn't work too well; will try using prototypes...
jassing
Addict
Addict
Posts: 1774
Joined: Wed Feb 17, 2010 12:00 am

Re: Runas de-elevated user

Post by jassing »

fryquez wrote:You need a normal user token and pass it to CreateProcessAsUser
Using this code

Code: Select all

EnableExplicit
#SAFER_LEVELID_FULLYTRUSTED = $40000
#SAFER_LEVELID_CONSTRAINED  = $10000
#SAFER_LEVELID_NORMALUSER   = $20000
#SAFER_LEVELID_UNTRUSTED    = $01000
#SAFER_SCOPEID_USER         = 2
#SAFER_LEVEL_OPEN           = 1

;Import "Advapi32.lib"
;  SaferCreateLevel(dwScopeID,dwLevelID,OpenFlags,*pLevelHandle,lpReserved)
;  SaferComputeTokenFromLevel( *levelHandle.SAFER_LEVEL_HANDLE , inAccessToken, outAccessToken, dwFlags, lpReserved)
;  SaferCloseLevel(hSafer)
;EndImport

Prototype ptSaferCreateLevel(dwScopeID,dwLevelID,OpenFlags,*pLevelHandle,lpReserved)
Prototype ptSaferComputeTokenFromLevel( *levelHandle, inaccessToken, outAccessToken, dwFlags, lpReserved)
Prototype ptSaferCloseLevel( hSafer )

Procedure RunAsNormalUser(iCommand, iWorkingdir = 0, iShowflag = #SW_NORMAL)
  
  Protected hSafer, hToken, si.STARTUPINFO, pi.PROCESS_INFORMATION, lReturn
  Protected hAdvapi32
  Protected SaferCreateLevel_.ptSaferCreateLevel
  Protected SaferComputeTokenFromLevel_.ptSaferCreateLevel
  Protected SaferCloseLevel_.ptSaferCloseLevel
  
  hAdvapi32 = OpenLibrary(#PB_Any,"advapi32.dll")
  If hAdvapi32
    SaferCreateLevel_ = GetFunction(hAdvapi32,"SaferCreateLevel")
    SaferComputeTokenFromLevel_ = GetFunction(hAdvapi32,"SaferComputeTokenFromLevel")
    SaferCloseLevel_ = GetFunction(hAdvapi32,"SaferCloseLevel")  
  EndIf
  
  If SaferCreateLevel_(#SAFER_SCOPEID_USER,
                       #SAFER_LEVELID_NORMALUSER,
                       #SAFER_LEVEL_OPEN,
                       @hSafer,
                       0)
    
    If SaferComputeTokenFromLevel_(hSafer,
                                   0,
                                   @hToken,
                                   0,
                                   0)
      
      si\cb = SizeOf(STARTUPINFO)
      si\dwFlags = #STARTF_USESHOWWINDOW
      si\wShowWindow = iShowflag
      
      lReturn = CreateProcessAsUser_(hToken,
                                     0,
                                     iCommand,
                                     0,
                                     0,
                                     0,
                                     0,
                                     0,
                                     0,
                                     @si,
                                     @pi)
    EndIf
    SaferCloseLevel_(hSafer)    
  EndIf
  
  If IsLibrary(hAdvapi32)
    CloseLibrary(hAdvapi32)
  EndIf
  
  ProcedureReturn lReturn  
EndProcedure

RunProgram("c:\windows\system32\cmd.exe")
RunAsNormalUser(@"c:\windows\system32\cmd.exe")
When the program is run "as administrator", Both cmd's are created also elevated

**BUT** if I run my test program; it is launched w/o elevation. Curious, but I think it may work!!!
Last edited by jassing on Thu Oct 18, 2018 2:17 am, edited 1 time in total.
jassing
Addict
Addict
Posts: 1774
Joined: Wed Feb 17, 2010 12:00 am

Re: Runas de-elevated user

Post by jassing »

RASHAD wrote:

Code: Select all

cmd /min /C "set __COMPAT_LAYER=RUNASINVOKER && start "" %1"
When I run that from an elevated command prompt (in a batch file) the program is run with elevated rights.
RASHAD wrote:

Code: Select all

[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\temp\\isuseradmin.exe"="RunAsInvoker"
Regardless if I ran my elevated user test or elevated cmd then ran it; if run from an elevated app, it too was elevated.
fryquez
Enthusiast
Enthusiast
Posts: 367
Joined: Mon Dec 21, 2015 8:12 pm

Re: Runas de-elevated user

Post by fryquez »

Hmm, yes the new process is flagged as elevated and high integrity, but have the rights of a normal user.

It would look better with logon token obtained by WinStationQueryInformationW, but it requires system rights.

Maybe stealing explorer.exe token is an alternative: https://www.purebasic.fr/german/viewtop ... 85#p311385
jassing
Addict
Addict
Posts: 1774
Joined: Wed Feb 17, 2010 12:00 am

Re: Runas de-elevated user

Post by jassing »

fryquez wrote:Hmm, yes the new process is flagged as elevated and high integrity, but have the rights of a normal user.

It would look better with logon token obtained by WinStationQueryInformationW, but it requires system rights.

Maybe stealing explorer.exe token is an alternative: https://www.purebasic.fr/german/viewtop ... 85#p311385

Thanks.
What was curious is that I ran cmd.exe, both came up as "Administrator" -- and when I ran the elevated tester, they both showed elevated; but when I ran the elevated tester directly it worked. Clearly, more testing is needed.

Thanks for the link -- gives me more to look at.

-j
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4663
Joined: Sun Apr 12, 2009 6:27 am

Re: Runas de-elevated user

Post by RASHAD »

Hi
I suggest to have 3 programs
1 st. one (Main) works like an Invisible watch dog that starts your Main program and keep looking ( compile in User mode )

2 nd. one is your main and it should be compiled with admin rights
(compile using Admin mode)

3 rd. one should be compiled normally
(compile in user mode)

When you want to run the normal one just send a flag to the watch dog to run it

I made a test and it works fine with me
Egypt my love
jassing
Addict
Addict
Posts: 1774
Joined: Wed Feb 17, 2010 12:00 am

Re: Runas de-elevated user

Post by jassing »

Great idea! Simple, I like it! thanks.
Post Reply