2

I have a windows service which started with local System account. In this service, it use CreateProcessAsUser API to create a new process with user1 account . After the process is created:

  1. Logon the system as Administrator, I can find the owner of the process is user1, and I can stop/resume/kill the process.

  2. Logon the system as user1, but I cannot stop/resume/kill the process, and I got the "access denied" error. Why?

Here is my test code:

import os
import psutil
import win32process
import win32security
import win32con
import win32api
import win32file


def log(msg):
    with open('C:\\test\\my.log', 'a') as f:
        f.write(msg)
        f.write('\n')

username = 'user1'
password = 'user1'
domain = 'testpc'


try:
    token = win32security.LogonUser (
        username,
        domain,
        password,
        win32con.LOGON32_LOGON_SERVICE,
        win32con.LOGON32_PROVIDER_DEFAULT
    )
    win32security.ImpersonateLoggedOnUser(token)

    cmd = "ping -n 600 localhost"
    cwd = 'c:\\test'
    env = os.environ

    dwCreationFlags = win32con.NORMAL_PRIORITY_CLASS
    startup = win32process.STARTUPINFO()

    (hProcess, hThread, dwProcessId, dwThreadId) = \
        win32process.CreateProcessAsUser(token, None, cmd, None, None, True,
                                         dwCreationFlags, env, cwd, startup)
    log("hProcess=%s, hThread=%s, dwProcessId=%s, dwThreadId=%s" % (hProcess, hThread, dwProcessId, dwThreadId))

    process = psutil.Process(dwProcessId)
    log('process: %s' % process)

    return_code = process.wait()

    win32file.CloseHandle(hThread)
    win32file.CloseHandle(hProcess)
except win32security.error as e:
    log(e)

Could someone help me? Many thanks.

kongxx
  • 103
  • 1
  • 7
  • Process Monitor (available from the MS web site) can show you what permissions are being set on the process. According to the documentation, they ought to work the way you want them to, but perhaps that is out of date or just wrong. (It might have something to do with the fact that the process is being created in session 0.) Anyway, if they aren't being set the way you want, you can use the `lpProcessAttributes` argument to set them explicitly, though I don't know how easy that will be in whatever language you're using. – Harry Johnston Oct 09 '17 at 05:08
  • you make 2 mistakes - first you use `LOGON32_LOGON_SERVICE` in call to `LogonUser`. but in this case *The account provided must have the service privilege enabled.* the second mistake - you not check any errors. if you check this - you can view that `LogonUser` fail with error `ERROR_LOGON_TYPE_NOT_GRANTED` (*Logon failure: the user has not been granted the requested logon type at this computer.*) - what next - you use the 0 `token` in call `CreateProcessAsUser`. this is valid value and process created, but with system *DACL* – RbMm Oct 09 '17 at 08:33
  • I checked the code in my environment, no error found. And I can get a valid token like: "token: ". In addition, I also can get valid token if used win32con.LOGON32_LOGON_BATCH in LogonUser() method. In the same time, use this token I can start the process with CreateProcessAsUser() method. (I can make sure the sub process is started and the owner is user1) So, the problem is the owner user1 cannot stop/resume/kill the sub process which started by CreateProcessAsUser() method. – kongxx Oct 09 '17 at 09:19
  • @RbMm, In my environment, no exception or error raise. And also no error found in windows event viewer. – kongxx Oct 09 '17 at 09:34
  • 1
    user1 has all access, but when created from your service the process is at high integrity. If the user is logged on at medium integrity, the user's rights for the process are filtered to only allow querying limited information (e.g. the image name), synchronizing (waiting), and terminating. So killing the process should still work. It works for me with Task Manager. OTOH, `taskkill.exe /f /pid ...` tries to open a handle with the right to query full information, which fails with access denied. – Eryk Sun Oct 09 '17 at 09:46
  • @eryksun - *but when created from your service the process is at high integrity* - this depend from `user1` account type. high integrity will be only if it admin account type and we not use not use `LOGON32_LOGON_INTERACTIVE` (which is filter user token). but if `user1` is admin and use say `LOGON32_LOGON_BATCH` - yes will be high integrity. and when `user1` then logon interactive - it will me medium – RbMm Oct 09 '17 at 13:13
  • @kongxx - if your `user1` account can log with type `LOGON32_LOGON_SERVICE` (this is admin account and allowed login as service(?)) - src of error can be - your process exec as admin and when you log to system as `user1` interactive - you really not admin (token filtered). and for what you call `ImpersonateLoggedOnUser(token)` ? this not need. and say `token` who close ? – RbMm Oct 09 '17 at 13:18
  • 2
    @RbMm, the token logged on as a service (`LOGON32_LOGON_SERVICE`) has a high integrity label, and the created process is at high integrity (in its SACL). I verified this before commenting by creating a standard user (not admin) that was specifically granted the right to log on as a service. – Eryk Sun Oct 09 '17 at 13:23
  • @RbMm, if this code is actually in a Python function, then the Token handle will be closed by automatic reference counting when the function returns, i.e. when the reference count on `token` becomes 0. It's better to be explicit, however, with a try/finally that calls `token.close()`. – Eryk Sun Oct 09 '17 at 13:29
  • @eryksun - yes, you right here. really `S-1-16-12288 'High Mandatory Level'` label exist in process `DACL` in case `LOGON32_LOGON_SERVICE`. i simply at begin assume that logon is fail (very unusual when user account have this privilege). really high label problem . and i dont know python. but call `win32security.ImpersonateLoggedOnUser(token)` anyway not need here – RbMm Oct 09 '17 at 13:36
  • 1
    The mandatory label ACE is stored in the SACL, but it's special cased not require SeSecurityPrivilege. – Eryk Sun Oct 09 '17 at 14:16
  • kongxx, to clarify, if you use `LOGON32_LOGON_BATCH` is the user still unable to kill the process? @eryksun, does using `LOGON32_LOGON_BATCH` still result in a high integrity process? – Harry Johnston Oct 09 '17 at 20:49
  • @HarryJohnston, a batch logon uses medium integrity, so the user should have complete, unfiltered access. To test this, I gave the user the right to log on as batch and changed the OP's code to use `LOGON32_LOGON_BATCH`. The logged on token has a "Mandatory Label\Medium Mandatory Level" SID , and the process SACL has a medium-integrity mandatory label ACE that's flagged no read-up, no write-up. – Eryk Sun Oct 09 '17 at 21:32
  • @all I re-create a new standard user which named user2 for this test. I found the new user's process can be killed by this user, even if the user LOGON32_LOGON_SERVICE or LOGON32_LOGON_BATCH. So maybe the user1 has some security setting changes, but I am not sure. I will continue check the user1's setting. – kongxx Oct 12 '17 at 05:36
  • So, now I can kill the process which created by user2 through "Task Manager" and "Process Explorer", but the process still cannot be suspend/resume by "Process Explorer". Maybe @eryksun is right, the suspend/resume operation "tries to open a handle with the right to query full information, which fails with access denied" . – kongxx Oct 12 '17 at 05:37
  • Is that when logged on as batch or a service? When run as a standard user with a batch logon, the user should have all access since the process should be run with a medium integrity level. – Eryk Sun Oct 12 '17 at 07:34
  • @eryksun the user is logon as bach, and the user only can kill the process by "Task Manager" and "Process Explorer". But cannot stop/resume the process by "Process Explorer". – kongxx Oct 12 '17 at 07:56
  • I cannot reproduce that result in Windows 10 with a *standard* (not admin) account that was granted the right to log on as batch and service. For me, only a service logon is at high integrity. A batch logon is at medium integrity, and the user has full access. – Eryk Sun Oct 12 '17 at 08:19

0 Answers0