Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!

TUCoPS :: Security App Flaws :: bt670.txt

Bypassing ServerLock protection on Windows 2000

		   Bypassing ServerLock protection on
			     Windows 2000

			   Jan K. Rutkowski

1. Background

ServerLock for Windows 2000 is product of Watch Guard company. The
purpose of this tool is to protect integrity of the operating system
by ensuring that nobody can modify certain files (like DLLs or
drivers), some registry keys and load unknown drivers.

Watch Guard homepage:

There are two bugs in the recent version of Server Lock for Windows
2000 which can be exploited to completely bypass its protection.

2. Bug #1 - loading arbitrary modules (using Runtime Process Infection)

2.1. Basics

It is possible to circumvent ServerLock protection, so that attacker
can load arbitrary module into kernel. Normally such action is
restricted by ServerLock, because:

a) it is not possible to create keys under
HKLM\System\CurrentControlSet\Services, so official Windows 2000
mechanism to load drivers cannot be used (SCM and ZwLoadDriver() which
is used by SCM, require that each driver has a dedicated subkey under
the 'services' key in the registry).

b) it is not possible to replace a 'legal' driver (files form
\Winnt\System32\drivers directory), because ServerLock protects these
files from write access.

c) there exists undocumented function: ZwSetSystemInformation(), which
can be used to load driver, and this function doesn't require any keys
in the registry. ServerLock protects these function, so that only
'trusted' programs can use it.

The method of attack, presented below, assumes ServerLock 2.0.1 for
Windows 2000. Prior versions have not been tested, but it is likely
that they are also vulnerable.

2.2. DLL injection

First of all, we should explain what 'trusted' program means. Every
EXE file, which is guarded (i.e. modification is not allowed) by
ServerLock is considered 'trusted'. The reason for this, is that
attacker cannot change the trusted program's code.

However this is not true, when we are considering running process.
Attacker can open process object by means of OpenProcess() function,
and then can use for example CreateRemoteThread() in order to inject
DLL library of his choice into the target process address space. This
is called 'DLL injection' and has been researched years ago, and can
look like this (simplified):

CreateRemoteThread (

Of course before that, one must ensure that "bad.dll" string is
present in the target process address space. This can be done by means
of VirtualAllocEx() and WriteProcessMemory() functions.

As we all know, just after DLL is loaded into the process memory,
DLL's entry point, usually called DllMain, is executed.

We see, that attacker, with proper privileges, can supply arbitrary
instructions to 'trusted' process and these instructions will be
executed. It should be noted that DLL injection is not the only
technique to achieve this runtime process infection, but is the
simplest one. Other techniques do not requires creation of additional
file ("bad.dll") in the filesystem (which is not very stealthy).

2.3. Calling ZwSetSystemInformation()

Assuming that attacker's rootkit resides in file rootkit.sys, we can
copy this file into \WINNT\system32\drivers\ directory as a for example. ServerLock forbids creation only files with
some known extensions like .sys, but for ZwSetSystemInformation()
function extension doesn't matter.

Using DLL injection technique (described above) we can force any
'trusted' process to execute ZwSetSystemInformation()
(SystemLoadAndCallImage class), thus allowing attacker to load his module into kernel.

2.4. Other usage of OpenProcess()

Despite exploiting ZwSetSystemInfomration(), OpenProcess() function
can be used to do API hooking in other processes. This future is used
by some recently popular Windows usermode rootkis, like hxdef. It
would be a good idea to restrict OpenProcess() then.

3. Bug #2 - improper handling of symlinks to \Device\PhysicalMemory

Server Lock is trying to restrict access to \Device\PhysicalMemory to
disallow accessing kernel memory. However it is possible to create
some symlinks to this object and then, open this device via symlink.

The following output demonstrates just few possibilities:

creating link: \hak1 --> \Device
creating link: \hak2 --> \Device\PhysicalMemory
creating link: \hak3 --> \
creating link: \hak4 -->  [failed]
creating link: \Device\hak5 --> \Device
creating link: \Device\hak6 --> \??\GLOBALROOT

trying to open for READ|WRITE:
opening \Device\PhysicalMemory ... [failed]
opening \hak1\PhysicalMemory ... [it worked!]
opening \hak2 ... [it worked!]
opening \Device\hak5\PhysicalMemory ... [it worked!]
opening \Device\hak5\hak5\PhysicalMemory ... [it worked!]
opening \??\GLOBALROOT\Device\PhysicalMemory ... [it worked!]
opening \Device\hak6\hak1\PhysicalMemory ... [it worked!]

It should be obvious that having possibility to open
\Device\PhysicalMemory for writing we can do whatever we want with the
system, like loading some rootkits and backdoors. It means complete
system compromise. Although this is not trivial, since we must
translate linear addresses to physical, proof-of-concept codes can be
found on the net.

4. Vendor response

17.02.2003:	bug 1 has been reported to Watch Guard
10.03.2003:	bug 2 has been reported to Watch Guard
28.03.2003:	SL 2.0.3 has been released which fixed bug #1
02.07.2003:	SL 2.0.4 has been released which fixed bug #2

SL 2.0.3 does not restrict OpenProcess(), but SL 2.0.4 does, which
should stop Runtime Process Infection efforts.

5. Epilog

These bugs have been fixed and a patch made available to all current
subscribers on vendor's LiveSecurity Web site at:

Watch Guard refused to provide details about how they fixed the bugs.

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2015 AOH