Bypassing ServerLock protection

From: Jan Rutkowski (jkrutkowski_at_ELKA.PW.EDU.PL)
Date: 07/18/03

  • Next message: Kimmo Kasslin: "Attacks on Kerberos V in a Windows 2000 Environment."
    Date:         Fri, 18 Jul 2003 00:25:23 +0200
    To: NTBUGTRAQ@LISTSERV.NTBUGTRAQ.COM
    
    

                       Bypassing ServerLock protection on
                                 Windows 2000

                               Jan K. Rutkowski
                         <jkrutkowski@elka.pw.edu.pl>

    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: http://www.watchguard.com.

    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 (
            hTargetProc,
            ...
            addr_of_LoadLibrary,
            addr_of_"bad.dll"_in_target_process,
            ...
            );

    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
    rootkit.abc 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
    rootkit.abc 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:

    C:\>funWithLinks.exe
    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:
    https://www.watchguard.com/archive/softwarecenter.asp

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

    oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
    Are You "Certifiable"? Summer's Hottest Certification Just Got HOTTER!

    With a growth rate exceeding 110%, the TICSA security practitioner
    certification is one of the hottest IT credentials available. And now, for
    a limited time, you can save 33% off of the TICSA certification exam! To
    learn more about the TICSA certification, and to register as a TICSA
    candidate online, just go to

    http://www.trusecure.com/offer/s0100/

    oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo


  • Next message: Kimmo Kasslin: "Attacks on Kerberos V in a Windows 2000 Environment."