4

How can I prevent users from tampering with, stopping or crashing a Windows Service that is doing work in the background that may take a while to complete?

Upon receiving a stop request, the service should wait until the work is complete before stopping.

There is the CanStop flag for services, but I'm not sure how to respond to the OnStop message. And if the user does try to crash the service, how can I prevent further tampering?


Edit: Generalised question from parental control to any background process.

Petrus Theron
  • 26,491
  • 34
  • 146
  • 272
  • There have been a lot of questions asking whether it's possible to prevent a task from being terminated. These always raise another question: what if I pull out the power cord? – wj32 Nov 25 '10 at 08:56
  • @wj32: I prefer to focus on solving a problem that *can* be addressed. – Petrus Theron Nov 25 '10 at 11:42
  • My point is that you can't address the problem. Consider the example I gave you. What's the difference between that and a software termination method, like calling PsTerminateProcess from a driver? – wj32 Nov 26 '10 at 02:50
  • The difference is I can't make it any harder for the user to hit the power button. Calling PsTerminateProcess from a driver - I'd have to Google that. As in my comment to T.E.D., I know there is no fool-proof way - but at least I can make it hard. – Petrus Theron Nov 26 '10 at 06:47

3 Answers3

3

Users have to have admin privs to stop services. I don't think there is a foolproof way to protect a program from someone who has admin on the box. If you don't want "untrusted users" stopping the serivce, don't give "untrusted users" admin privs.

There seems to be some tripping over this point, so let me clarify a bit. Suppose an administrator decides she wants to uninstall your program. That's normally only a few mouse clicks. Are you going to take steps to prevent that?

Think carefully about your answer here. Any program that purposely tries to prevent uninstallation by an administrator is by definition malware.

I know that it has been pretty much standard since NT came out to give all home PC users admin rights, so that they can install and play games to their heart's content. However, that isn't really nessecary anymore with Vista and Win7, and people should get out of that habit. It is very bad security practice, even for a "trusted" user.

Telling your users that they have to actually follow some security practices is not a bad thing. They will find they have to clean far less malware and viruses off their machines that way as well.

T.E.D.
  • 42,800
  • 9
  • 66
  • 134
  • Yes, but sometimes the user will have administrator rights, even though that is a perfectly reasonable restriction. I know there's probably not a fool-proof way, but how can I make it hard/effort for the untrusted user to thwart the service? – Petrus Theron Nov 24 '10 at 12:54
  • 1
    But an administrator is by definition a trusted user – shf301 Nov 24 '10 at 13:19
  • Users with admin rights are also often the ones that make buying decisions. You piss them off at your peril. – Hans Passant Nov 24 '10 at 13:24
  • I appreciate the discourse on malware, but this is a specific application which should not be stoppable at certain times and at other times, it should be stoppable. I want the service to "block" on a stop request until it has completed its worker process, which could take a few seconds or a few minutes. This is for a legitimate function that is controlled by the user. – Petrus Theron Nov 25 '10 at 07:48
  • @FreshCode - Well, there really is no technical reason why you *have to* respond nicely to a stop request. But for any well-behaved program on a Windows platform the administrator **must** have a nice well-defined way to stop it (including automatically as part of system shutdown) and it should respond properly to an administrator's uninstall request. I don't see how you can possibly do either if you don't trust the administrator. – T.E.D. Nov 29 '10 at 13:59
1

What's your threat model? Without a threat model, it's impossible to figure out the right way to spend your effort.

For the moment, let's just consider preventing a service from being stopped, rather than the prevention or tampering or crashing.

T.E.D is correct in saying that if any admin wants to stop the service, you shouldn't normally try to prevent this. Otherwise how can the administrator do fault isolation, start Windows in bare-bones mode, and so on?

As you say, the ServiceBase.CanStop property is used to prevent service stopping. This property is normally used only by OS-critical services that must run.

In the main service thread, you could just ignore the OnStop event and loop forever. So the SCM would think the service was stopped, even though it's still running. This is rather nasty, but should work. The SCM is just issuing a stop request, not actually forcing the stop.

HTTP 410
  • 16,882
  • 12
  • 75
  • 126
  • I am not too concerned about devious attackers, but I don't want the logged-in user who started a worker process (conducted by the service) to be able to stop the service until that process has completed. The service should block a stop request until it has completed. – Petrus Theron Nov 25 '10 at 07:51