wraithdu

Elevate Your Script to the SYSTEM Account

52 posts in this topic

#1 ·  Posted (edited)

First, thanks to arcker for his Services UDF for making this possible. It works like this:

When launched, the app will install itself as a service, launch the service, then exit. The service runs in the SYSTEM account. To interact with the desktop of the currently logged on user it will get the security information from the winlogon.exe token and the user's environment from the explorer.exe token. The service will relaunch the app with these security settings and environment, then stop. On relaunch, the process will wait for the service to end then uninstall it. The process will now be running in the SYSTEM account in the currently logged on user's session with the user's environment. If you look into the _Svc_Main() function there's a note about how to relaunch the process in Session 0 (same as the service) if you need to do this. In this case it will be running solely in the SYSTEM account in Session 0 with it's own environment.

I've included two more functions for when you need to access certain other user specific items, such as using the @UserName macro, or accessing the HKCU branch of the registry (these things are not taken from the environment, but from the security context of the process). You should test any macros you intend to use to make sure the correct information is returned before running your process for real. _ImpersonateUserStart() and _ImpersonateUserEnd() will enable and disable this impersonation. Keep in mind this alters your security access as well, you will have the same security level as the logged on user during this time.

NOTE: For retrieval of the user environment and user impersonation it is required that explorer.exe is running. If you're using a 3rd party shell replacement, you can edit the UDF to change the requirements to another process, but I can't guarantee it will work.

I've included a stripped down version of arcker's UDF, since not all of it is needed. If I could get some test results from users running XP and Vista/7 with UAC, that would be great too.

Sources:

Link 1

Link 2

ANY SCRIPT USING THESE FUNCTIONS MUST BE COMPILED TO WORK. IT WILL NOT WORK FROM SCITE.

ADMIN RIGHTS REQUIRED AS WELL.

UPDATE 1 (2009/10/29)

- added a function to launch a process as the user of a currently running process in the specified session (ie, to de-elevate a process back to your user account).

UPDATE 2 (2009/10/29)

- fixed a wrong function export which caused problems on XP (thanks trancexxx)

UPDATE 3 (2009/10/30)

- I think I have a stable version now, tested on Win7, XP SP3 VM, and a physical XP SP3 box. As a bonus the service control handler now works in Win7 as well, so we can have a fully functioning service.

_Services_Mini.au3

SystemElevate.au3

Edited by wraithdu
2 people like this

Share this post


Link to post
Share on other sites



Small update.

Share this post


Link to post
Share on other sites

Excellent

that's how remote installation works :)

(psexec is a good example, or other deployment software )


-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

I'm still curious how psexec works (if it's not by this same procedure). I wish Sysinternals would release source for their apps. So much to learn...

1 person likes this

Share this post


Link to post
Share on other sites

Excellent

that's how remote installation works :)

(psexec is a good example, or other deployment software )

What do you mean 'Excellent'? It works for you?

@wraithdu, CreateProcessAsUser function is exported by advapi32.dll.

I got it working, but some funny crashes while. XP SP3.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

I don't have XP readily available to test, so if there are problems I'll try to look into it. Anything more specific to offer? Post the contents of the log maybe?

Edited by wraithdu

Share this post


Link to post
Share on other sites

I don't have XP readily available to test, so if there are problems I'll try to look into it. Anything more specific to offer? Post the contents of the log maybe?

Logs are gone.

This:

$ret = DllCall("kernel32.dll", "int", "CreateProcessAsUserW", "ptr", $hDupToken, "ptr", 0, "wstr", $sAppPath, "ptr", 0, "ptr", 0, "int", 0, _
                    "dword", $dwCreationFlags, "ptr", $pEnvBlock, "ptr", 0, "ptr", DllStructGetPtr($SI), "ptr", DllStructGetPtr($PI))
    If Not @error And $ret[0] Then
...

It's not "kernel32.dll".


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Good catch. Strangely CreateProcessAsUser is also exported by kernel32 on Win7. Guess that's why I didn't notice.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Fixed and updated.

Also tested in an XP SP3 VM and it works fine after the fix.

Edited by wraithdu

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Good catch. Strangely CreateProcessAsUser is also exported by kernel32 on Win7. Guess that's why I didn't notice.

Microsoft have moved lots of the api's that was currently inside different modules into kernel32.dll. This is probably because the speed / efficiency increase is now more important than the memory footprint. The exports in advapi32 and similar are just probably just redirects and are probably there because microsoft doesn't want applications to break on win7 (very strange indeed :)).

Edited by monoceres

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Btw, I found what was/is causing the crash.

It's ProcessWaitClose($CmdLine[2]) you use. It should be:

Case "-run"
            ; as elevated app
            ; wait for service to end and uninstall service (PID passed as $CmdLine[2])
            ProcessClose($CmdLine[2]) ; <- This!
            MsgBox(0, "Hey", "Closed")
            _RemoveService()
...

edit:

Or something like that :)

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

No, it's supposed to be ProcessWaitClose() as the Service will stop itself properly, and the process must wait for it to close before removing it.

That said, I tested on another XP system and did get a crash, but it's a crash in the service, not the newly spawned process. Once you close the crashed app the new process will continue. I still don't know why the service is crashing though.

Edited by wraithdu

Share this post


Link to post
Share on other sites

It's crashing right here

_Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0)

WTF?

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

Turns out the problem is stopping the service cleanly in Win7. I can issue a _Service_Stop() command even from in the service in XP and it ends. In 7 that control message is never received so the thing doesn't exit cleanly (leaves a crash log in Event Viewer).

Unless arcker or someone can figure that out, I might just switch to using ProcessClose() to kill the service before removing it. It's ugly and bad, but I don't have another workaround at the moment.

EDIT:

I'm confused again. Now it seems to work OK the way I had it in Vista. Maybe I just need to use _Service_Stop() in XP instead.

Edited by wraithdu

Share this post


Link to post
Share on other sites

Turns out the problem is stopping the service cleanly in Win7. I can issue a _Service_Stop() command even from in the service in XP and it ends. In 7 that control message is never received so the thing doesn't exit cleanly (leaves a crash log in Event Viewer).

Unless arcker or someone can figure that out, I might just switch to using ProcessClose() to kill the service before removing it. It's ugly and bad, but I don't have another workaround at the moment.

EDIT:

I'm confused again. Now it seems to work OK the way I had it in Vista. Maybe I just need to use _Service_Stop() in XP instead.

I think there is a problem with logic.

Why don't you exit after successful CreateProcessAsUserW. Don't return if ok, just exit. That makes sense to you?


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Doesn't matter. I tried, but it was still crashing / hanging.

But I've had a breakthrough! I switched to use RegisterServiceCtrlHandlerExW() and a HandlerEx() callback and....it works in Win7! So I'm testing a proper course of events here where the new process stops the service, waits for it to close, then removes it. So far it is working in Win7 and I'm about to do testing in XP.

It also seems that calling the _DebugLog() function at certain times causes a hang, especially if it's called from the child before the server has ended, so we must be careful about that.

Share this post


Link to post
Share on other sites

I think I have it stable now. I'm going to test again tomorrow on my XP computer at work and make sure it works there too, then I'll post the update.

Share this post


Link to post
Share on other sites

Updated above. It seems to be stable on all my test machines/VMs now. As a bonus I've got the service control handler working in Win7 :)

Share this post


Link to post
Share on other sites

I noticed an uneven number a downloads above...be sure to download both scripts, as they both have been updated.

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

I noticed an uneven number a downloads above...be sure to download both scripts, as they both have been updated.

You mean:

Mod($iNumberofDownloads, 2) = True

or not? :)

edit:

Not crashing and working ok on XP SP3. Nice job. 5 from me.

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
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