0

I have a computer with configured Auto-Logon.
After a restart of Windows it automatically performs a login with a predefined user.

I would also like to connect via Remote Desktop to this computer. But therefore I need the password for this specific user.

I already know that the AutoLogon can be configured in the registry:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
AutoAdminLogon(REG_SZ) = 1
DefaultDomainName(REG_SZ) = MyDomain (or empty)
DefaultUserName(REG_SZ) = MyUser
DefaultPassword(REG_SZ) = MyPass
But in my case there is NO entry of DefaultPassword. Despite this missing password the AutoLogon still works. And the password is NOT a empty string.

How can I retrieve the password?

2 Answers 2

0

Solution: LsaRetrievePrivateData

Windows can store key-value pairs in a hidden way and when automatic login is enabled on a system, the password is stored in the DefaultPassword field. To retrieve it use the following way:

  • LsaOpenPolicy(NULL, &attribs, POLICY_ALL_ACCESS, &lsa_handle) opens a LSA_HANDLE object
  • You create a LSA_UNICODE_STRING structure and let it point to a wchar_t data buffer containing DefaultPassword.
  • And then you call LsaRetrievePrivateData(lsa_handle, &key, &ptr_value), to which the string structure is passed as key.
  • The returned pointer (ptr_value) holds a new Unicode string data structure where the decrypted password should be contained, or not if none exists.

The call must be made under administrator privileges, otherwise access will be denied.

Origin: https://www.opengate.at/blog/2021/11/win32-stored-password/

And here is the necessary C code which worked and revealed the password in my case:

#include <string>
#include <exception>
#include <wchar.h>
#include <iostream>
#include <sstream>
#include <stdexcept>

#include "windows.h"
#include "Ntsecapi.h"

typedef std::string string_t;
typedef std::wstring wstring_t;

struct LsaHandle
{
private:
    LsaHandle(const LsaHandle&);
    LsaHandle& operator=(const LsaHandle&);
    LSA_HANDLE handle;

public:
    LsaHandle(LSA_HANDLE h = LSA_HANDLE()) 
        : handle(h) 
    {
    }
    
    ~LsaHandle()
    { 
        if(this->handle)
        {
            LsaClose(this->handle);
        }
    }

    LSA_HANDLE& operator*() 
    { 
        return this->handle; 
    }
};

wstring_t getSecretPwd()
{
    LsaHandle hPolicy;
    LSA_OBJECT_ATTRIBUTES attribs;
    ZeroMemory(&attribs, sizeof(attribs));
    NTSTATUS dwStatus = LsaOpenPolicy(NULL, &attribs, POLICY_ALL_ACCESS, &*hPolicy);
    DWORD dwError = LsaNtStatusToWinError(dwStatus);
    if(dwError != 0)
    {
        DWORD dwError = ::GetLastError();
        std::stringstream ss;
        ss << "Failed to open storage, error-code = " << dwError;
        throw std::runtime_error(ss.str());
    }

    WCHAR wstrKeyName[] = L"DefaultPassword";
    LSA_UNICODE_STRING keyName;
    keyName.Buffer = wstrKeyName;
    keyName.Length = static_cast<USHORT>(wcslen(wstrKeyName) * sizeof(wstrKeyName[0]));
    keyName.MaximumLength = static_cast<USHORT>((wcslen(wstrKeyName) + 1) * sizeof(wstrKeyName[0]));

    PLSA_UNICODE_STRING privateData = NULL;

    dwStatus = LsaRetrievePrivateData(*hPolicy, &keyName, &privateData);
    if(dwStatus != 0)
    {
        dwError = LsaNtStatusToWinError(dwStatus);
        std::stringstream ss;
        ss << "Failed to retrieve data, error-code = " << dwError;
        throw std::runtime_error(ss.str());
    }
    wstring_t secret_pwd(privateData->Buffer, privateData->Length / sizeof(privateData->Buffer[0]));
    LsaFreeMemory(privateData);
    return secret_pwd;
}


struct KeyHandle
{
private:
    HKEY    handle;
    KeyHandle(const KeyHandle&);
    KeyHandle& operator=(const KeyHandle&);
public:
    KeyHandle(HKEY h = HKEY()) 
        : handle(h) 
    {
    }
    ~KeyHandle()
    { 
        if(this->handle)
        {
            RegCloseKey(this->handle);
        }
    }
    HKEY& operator*() 
    { 
        return this->handle;
    }
};

wstring_t getRegistryPwd()
{
    wchar_t strPass[2048];
    DWORD dwType;
    DWORD dwSize = sizeof(strPass);

    KeyHandle hKey;
    LONG result = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
                                L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
                                0,
                                KEY_QUERY_VALUE,
                                &*hKey);

    if(ERROR_SUCCESS != result)
    {
        throw std::exception("Failed to open storage");
    }

    result = RegQueryValueExW(*hKey, L"DefaultPassword", 0, &dwType, (LPBYTE)strPass, &dwSize);
    switch(result)
    {
    case ERROR_SUCCESS:
        {
            if(dwType != REG_SZ) 
                return wstring_t();
            else
                return wstring_t(strPass, dwSize / 2);
            break;
        }
    case ERROR_FILE_NOT_FOUND:  
    case ERROR_PATH_NOT_FOUND:
        {
            return wstring_t();
        }
    default:
        {
            throw std::exception("Failed to retrieve data");
        }
    }

}

void showPassword(wstring_t(*pwdfunc)(), char const* pwdname)
{
    wstring_t pwd;
    try
    {
        pwd = pwdfunc();
        if(!pwd.empty())
        {
            std::cout << "[" << pwdname << " = ";
            std::wcout << pwd;
            std::cout << "]" << std::endl;
        }
        else
        {
            std::cout << "No " << pwdname << std::endl;
        }
    }
    catch(std::exception& ex)
    {
        std::cout << "[" << pwdname << "] Exception: " << ex.what() << std::endl;

    }
    catch(...)
    {
        std::cout << "[" << pwdname << "] Unknown exception" << std::endl;
    }
}


int main()
{
    showPassword(&getSecretPwd, "Secret Password");
    showPassword(&getRegistryPwd, "Default Password");

    return 0;
}
0

There exist products that can retrieve the Windows AutoLogon password, although you might need to temporarily disable Defender's Real-time protection in order for it to not detect them as viruses.

Here are a couple :

Nirsoft Network Password Recovery

enter image description here

DecryptAutologon.exe

enter image description here

From the two products, I trust Nirsoft better.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .