Re: restricting permissions for services in Win2K

From: KJK::Hyperion (
Date: 02/20/02

Date: Wed, 20 Feb 2002 07:05:05 +0100
To: <>
From: "KJK::Hyperion" <>

At 19.34 19/02/2002, you wrote:
>I have a question regarding the proper way to better lock down Win2K
>services. I know that IIS for example requires system level access to
>run, and that can't be changed, or IIS won't work.

AFAIK, it runs with any account to which the TCB ("Act as part of the
operating system") and "Substitution of a process's primary token"
privileges are granted. These two privileges are needed by any account that
logs on users [1], and you should know that IIS creates two unprivileged
user accounts to run web applications, and needs to be able to log them on
(NT security is way more fine-grained than on any Unix, and as such much
more complex - power, as always, comes at a cost [2])

>But I should be able to limit the privileges of other services running on
>my server. My question is how do I determine what minimum privileges are
>required for a given service to function properly? This way, if a service
>on my server is compromised, it won't give system level access to the "hacker".

Most services that don't use NT security will run smoothly as a member of
the Users group, or Power Users if they need write access to shared program
or system files. Those that do use NT security, like IIS, may need some
privileges to function properly (or to function at all), see above. The
problem is essentially that privileges are horribly documented, and the
implications of granting/revoking a privilege are never explored, so most
(Microsoft techs included) choose the easy way out: run as SYSTEM

>For example, I want to run Apache on my Win2K box. I install it, and now
>it shows up as a service. I open the service, select the "Log On"
>tab. By default, "Local System Account" is selected. I want to change
>that so Apache doesn't have that level of control. First, do I create a
>new user, or do I use an existing one?

Create a new user, named "Apache" or "httpd", in the Users group. And use
that. Deny to this account any kind of login other than as a service (this
is done with privileges). Just give it write access to the logs directory,
and nowhere else (unfortunately Apache for Windows is based on Win32, that
hides the NT support for "append-only" access, so it will be still possible
for an attacker to hide traces by tampering with the log files). Of course,
if you want to provide dynamic sites, give write access to the directories
that need it. The cacls utility is useful to do this from automated scripts

This is the way I did it, and Apache has worked for months on this machine

[1] just for fun: SeTcbPrivilege is needed to log on a user, that is
connecting to the LSASS, sending an username and password (unfortunately,
no privilege grants password-less access: this is an important difference
with Unix, and a serious limitation. It's the reason why Apache on Unix
doesn't need the password for the httpd account to spawn unprivileged
children, while IIS on Windows does, even if both run as super-user), and
receiving a token that can be impersonated; SeAssignprimarytokenPrivilege
is needed to create a new process with a different primary token than self
(usually, to create a process as a different user). Related Win32 calls:
LogonUser() and CreateProcessAsUser()

[2] suggested reading: ignore the s***t Microsoft PR's feed to the press,
for real information on NT security see the "Security" topic in the MSDN
Library, especially the "access control" stuff (you can skip crypto,
authentication, etc., they're entirely different beasts)