[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

Prevent task manager from killing service process as admin

Posted on 2008-01-27
13
Medium Priority
?
3,741 Views
Last Modified: 2012-05-05
I'm looking for a way to prevent an administrator from terminating a service running in its own process space as SYSTEM. Perhaps by removing a permission so that OpenProcess fails when requesting PROCESS_TERMINATE permission? I haven't debugged taskmgr yet to determine how exactly it kills processes, but hopefully someone has an idea of how to block admins from terminating a service process.

I'm using VC++ 6, WinXP+.
0
Comment
Question by:jimstar
13 Comments
 
LVL 29

Expert Comment

by:pepr
ID: 20753771
When the administrator is not capable to decide what process should or should not be killed then he or she should not be the administrator. In other words, who will administer such system that can be out of control?

The solution in your case may be not to give the user administrator rights.
0
 
LVL 6

Accepted Solution

by:
SeanDurkin earned 1000 total points
ID: 20754228
It probably uses the TerminateProcess() function to terminate processes using the "End Process" button, so the way I'd go about doing this would be to inject a DLL into Windows Task Manager and hook TerminateProcess() causing it to fail on whatever process you wish.
0
 
LVL 86

Expert Comment

by:jkr
ID: 20754377
The only way is to disable the 'SeDebugName' privilege, yet thathas to be done *before* the task manager is launched:

BOOL DisablePrivilege(PCSTR name)
{
    TOKEN_PRIVILEGES priv = {1, {0, 0, SE_PRIVILEGE_REMOVED}};
    LookupPrivilegeValue(0, name, &priv.Privileges[0].Luid);

    HANDLE hToken;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);

    AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof priv, 0, 0);
    BOOL rv = GetLastError() == ERROR_SUCCESS;

    CloseHandle(hToken);
    return rv;
}

However, that privilege - though it is granted to administrators by default - usually is disabled anyway, so you should not encounter a problem here in the 1st place.
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
LVL 4

Author Comment

by:jimstar
ID: 20755947
pepr,

Thanks for the suggestion. For purposes of this question, I'm trying to figure out how, at a lower level, to prevent an administrator from being able to terminate the process via taskmgr. I'm aware that ultimately an admin can always figure out some way to get around the barriers that I implement, such as enabling privileges, overwriting memory, etc, but I'm only concerned with the taskmgr at this point, not the other possibilities. This makes it quite a bit easier.

SeanDurkin,

Thanks for the suggestion. While that would most definitely work, I'm trying to figure out the lowest-footprint solution. If it is possible to remove a neccessary privilege so that the action fails, that eliminates the need to have code loaded into each process in the system, and would be much cleaner than DLL injection. However, I may come back to this as the best solution after I investigate the other options.

jkr,

The fact that I can go in and kill MyService.exe process running as SYSTEM, from my interactive admin login, means that somehow either the process DACL grants Administrators permission to system processes, or else taskmgr requests those permissions, as you allude to in your response above. I went ahead and debugged taskmgr.exe, and discovered that it performs the following actions when a user clicks End Process:

1. It locates the selected process' PID in the process array.
2. Calls IsSystemProcess, which I suspect checks if the System process is selected (the process name, I suspect, not the process owner - though it really doesn't matter).
3. Calls CPrivilegeEnable, which enables SeDebugPrivilege for the EffectiveToken.
4. Calls kernel32 ! TerminateProcess.

So, the means by which it terminates the process is TerminateProcess(), and the granting of SeDebugPrivilege. That pretty much says it all - SeDebugPrivilege allows it to bypass the DACL-checking on an object, so that's the master key that needs to be withheld.

Expanding on this privilege issue, I'm thinking about a few options to explore:

1. Remove the privilege from the administrator's token (which would require creating a new, restricted token, and somehow swapping that for the user's primary token - not really sure how to do this at the moment).  I think malware does this to prevent the admin from running malware-removal apps. Also, I'm unsure if a process token actually has SeDebugPrivilege rights, or if it obtains those from the user account that owns the process (thus, removing it from the owning  user would immediately prevent the process from having that right). Either way, removing this on-the-fly would be messy I think (?).

2. Block the ability for administrators to enable SeDebugPrivilege by intercepting the call and failing. Similar to blocking/intercepting TerminateProcess() api.

3. Removing the Administrators group from the local security policy rights assignment for Debug Processes. This would require a logoff/logon to make it effective for the logged-on-user. Because it's not instantaneous, I don't really like this option.

I'm going to play around with this some more, but at the moment API interception for TerminateProcess seems like the best bet. Unless, of course, I can find a good way to block the termination via privilege management. But it's not looking promising.
0
 
LVL 4

Author Comment

by:jimstar
ID: 20755965
>> Also, I'm unsure if a process token actually has SeDebugPrivilege rights,
>> or if it obtains those from the user account that owns the process

If the process itself has the privilege assignments, then I could poll the system process list (or watch for process creations) and then create a restricted token from taskmgr.exe's primary token, removing the SeDebugPrivilege, and then somehow swapping in the new, restricted token. Because I'm only concerned about taskmgr.exe, this may be a cleaner solution...

If the privileges however are derived from the user's token whenever they are checked, then this would not work as it would affect all processes, not just taskmgr.exe. I'll have to read up on how permissions work in this regard to determine if I should pursue this angle.
0
 
LVL 4

Author Comment

by:jimstar
ID: 20756015
At first glance, it appears that a process token copies all permissions that the owning user has at creation time, and then there is no relationship between the two tokens as far as conferring rights are concerned. Thus, I'd be able to create a restricted process token whenever I see taskmgr.exe open, and remove SeDebugPrivilege from this list, essentially causing the AdjustTokenPrivileges to fail as if a normal user had created the task manager process.

Only issue may be the lag time in adjusting the process token... assuming I can recognize a proc creation and adjust the token within 500-1000ms, which seems reasonable, then this may work.
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 1000 total points
ID: 20756567
>> Also, I'm unsure if a process token actually has SeDebugPrivilege rights,
>> or if it obtains those from the user account that owns the process

The latter is the case, or a mix of both. I e.g. launch my task manager via a launcher that enblesthis privilege and starts the process, so the settings are inherited and I canc onveniently kill services. The process topen is what it is all about.

I was entertaining the idea to manipulate this token, yet I did not follow that idea, since an admin process can also change the token to regain access, thus I'll sum that up as: You can, but there's no bullet proof solution. To some extent, you won't be able to prevent the killing of services, you can just make it harder.
0
 
LVL 4

Author Comment

by:jimstar
ID: 20756632
In my particular case, it is safe to assume that no custom code is on the computer (just Windows default applications). When I investigated, however, I discovered that you cannot replace a process' primary token. In Server 2003 and later, you can actually remove privileges from an existing token, but this won't work for me as I need XP compatibility. Another option is to have each thread in the target proc impersonate the restricted token with SeDebug removed, essentially getting the desired reduction in privilege. This is messy, and also requires additional messing around with the token to allow impersonation. Of course, if the target app called RevertToSelf, it would gain full access again - though again in my case, because we're assuming that only Windows-default apps are installed/available, this would only occur if taskmgr itself called Revert which would be easy to check (and I'm guessing it doesn't happen).

Now that I've fully explored (I think) the privilege option, I'll probably go the route of CBT-style hook injection and overwrite the IAT entry for TerminateProcess within taskmgr.exe. I'll update the thread once I've done that.
0
 
LVL 86

Expert Comment

by:jkr
ID: 20756660
Stupid remark: Why don't you launch your processes to run under a non-privileged account that cannot kill services in teh 1st place?
0
 
LVL 4

Author Comment

by:jimstar
ID: 20756700
The issue is that task manager gets started by winlogon.exe, so I cannot tell it to create that process as a non-privileged account. Of course, this issue wouldn't be an issue if interactive users always ran under a non-privileged account except for true admins. But, as you know, this isn't always the case so I need to do what I can to account for the inexperienced customer.
0
 
LVL 86

Expert Comment

by:jkr
ID: 20756773
>>The issue is that task manager gets started by winlogon.exe

Err, no, that process is started only if you want it to (e.g. by adding it to any autostart means or launching it manually. If you want an easy solution, revoke the access rights:

cacls.exe %SystemRoot%\system32\taskmgr.exe /E /R Everyone
0
 
LVL 4

Author Comment

by:jimstar
ID: 20756798
Ah, I see what you're saying. The problem is that completely preventing taskmgr from running is fairly extreme... users and admins need to be able to kill off their own misbehaving apps, and I doubt they'd be happy if it was completely disabled. I'm trying to find a balance where they can still access the functionality to manage their own procs via CTRL+ALT+DEL->TaskMgr (which is where winlogon.exe starts it), but at the same time prohibiting them from mucking with my service.

I'm almost finished with intercepting OpenProcess to remove the PROCESS_TERMINATE permission bit whenever it opens my service's PID from within taskmgr.exe, which should cause TerminateProcess to fail by itself with access denied.
0
 
LVL 86

Expert Comment

by:jkr
ID: 20756817
>>The problem is that completely preventing taskmgr from running is fairly
>>extreme...

Not really, depending on the environment. With a 'kiosk' like setup, that would be quite OK. Admins can easily regain access by a hearty

cacls.exe %SystemRoot%\system32\taskmgr.exe /E /G Admonistrator:F

yet that is a limit. One of a few you can impose.
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

612 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question