【Windows】检查/删除登陆用户密码

 检查当前登陆用户是否需要密码的代码:

#define UNICODE
#define SECURITY_WIN32
#include <iostream>
#include <windows.h>
#include <wtsapi32.h>

#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "wtsapi32.lib")

struct UserInfo {
    std::wstring userName;
    std::wstring domainName;
};

bool IsRunningAsAdmin() {
    BOOL isAdmin = FALSE;
    HANDLE tokenHandle = NULL;

    // 获取当前进程的访问令牌
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
    {
        TOKEN_ELEVATION elevation{};
        DWORD cbSize = sizeof(TOKEN_ELEVATION);

        // 获取令牌中的权限信息,判断是否为管理员权限
        if (GetTokenInformation(tokenHandle, TokenElevation,
            &elevation, sizeof(elevation), &cbSize))
        {
            isAdmin = elevation.TokenIsElevated;
        }
        CloseHandle(tokenHandle);
    }
    else {
        std::cerr << "[-] Unable to obtain process token. Error code: "
            << GetLastError() << std::endl;
    }

    return isAdmin;
}

bool CheckAndStartSeclogonService() {
    SC_HANDLE scManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!scManager) {
        std::cerr << "[-] Error: Failed to open service manager. Error code: "
            << GetLastError() << std::endl;
        return false;
    }

    SC_HANDLE seclogonService = OpenService(
        scManager, L"seclogon",
        SERVICE_QUERY_STATUS | SERVICE_START);

    if (!seclogonService) {
        std::cerr << "[-] Error: Failed to open seclogon service. Error code: "
            << GetLastError() << std::endl;
        CloseServiceHandle(scManager);
        return false;
    }

    SERVICE_STATUS_PROCESS serviceStatus{};
    DWORD bytesNeeded;
    if (QueryServiceStatusEx(seclogonService, SC_STATUS_PROCESS_INFO, 
        (LPBYTE)&serviceStatus, sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded))
    {
        if (serviceStatus.dwCurrentState != SERVICE_RUNNING) {
            if (!StartService(seclogonService, 0, NULL)) {
                std::cerr << "[-] Error: Failed to start seclogon service. Error code: "
                    << GetLastError() << std::endl;

                CloseServiceHandle(seclogonService);
                CloseServiceHandle(scManager);
                return false;
            }
            else {
                std::cout << "[+] Seclogon service started successfully." << std::endl;
            }
        }
        else {
            std::cout << "[+] Seclogon service is already running." << std::endl;
        }
    }
    else {
        std::cerr << "[-] Error: Failed to query seclogon service status. Error code: "
            << GetLastError() << std::endl;

        CloseServiceHandle(seclogonService);
        CloseServiceHandle(scManager);
        return false;
    }

    CloseServiceHandle(seclogonService);
    CloseServiceHandle(scManager);
    return true;
}

// 获取当前活动会话的用户名和域名
UserInfo GetActiveUserNameAndDomain() {
    PWTS_SESSION_INFO pSessionInfo = NULL;
    DWORD sessionCount = 0;
    UserInfo activeUserInfo;

    // 枚举所有会话
    if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, 
        &pSessionInfo, &sessionCount))
    {
        for (DWORD i = 0; i < sessionCount; ++i) {
            // 查找当前活动的会话
            if (pSessionInfo[i].State == WTSActive) {
                DWORD sessionId = pSessionInfo[i].SessionId;
                LPTSTR pUserName = NULL;
                LPTSTR pDomainName = NULL;
                DWORD bytesReturned = 0;

                // 从活动会话获取用户名
                if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, 
                    WTSUserName, &pUserName, &bytesReturned) && bytesReturned > 0)
                {
                    activeUserInfo.userName = pUserName;
                }

                // 从活动会话获取域名
                if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, 
                    WTSDomainName, &pDomainName, &bytesReturned) && bytesReturned > 0)
                {
                    activeUserInfo.domainName = pDomainName;
                }

                // 释放获取到的内存
                if (pUserName) {
                    WTSFreeMemory(pUserName);
                }
                if (pDomainName) {
                    WTSFreeMemory(pDomainName);
                }

                break; // 找到活动用户后,退出循环
            }
        }
        WTSFreeMemory(pSessionInfo);
    }
    else {
        std::cerr << "[-] Unable to enumerate sessions, error code: "
            << GetLastError() << std::endl;
    }

    return activeUserInfo;
}


const INT GetAccountPasswordRequirement(
    const std::wstring& specialArg, 
    const bool IsRunStricted = true
)
{
    bool isCheckSrvFailed = false;
    std::wstring passwordW = L"";  // 空密码

    // 自动解析当前用户名和域名
    UserInfo activeUser = GetActiveUserNameAndDomain();
    if (!activeUser.userName.empty()) {
        // 打印域名和用户名
        std::wcout << L"[+] Domain: " << activeUser.domainName << std::endl;
        std::wcout << L"[+] Username: " << activeUser.userName << std::endl;
    }
    else {
        std::wcout << L"[-] No active users were found." << std::endl;
        return -1;
    }

    // 检查并启动 seclogon 服务
    if (IsRunStricted && !CheckAndStartSeclogonService()) {
        std::cerr << "[-] Error: Unable to ensure seclogon service is running." << std::endl;
        isCheckSrvFailed = true;
    }

    // 获取当前进程的可执行文件路径
    WCHAR modulePath[4096];
    wmemset(modulePath, 0, 4096);
    GetModuleFileNameW(NULL, modulePath, 4095);

    // 构造命令行,包括自身路径和特殊参数
    std::wstring commandLine = L"\"";
    commandLine += modulePath;
    commandLine += L"\" ";
    commandLine += specialArg;  // 添加特殊参数

    // 创建进程信息结构体
    PROCESS_INFORMATION processInfo;
    ZeroMemory(&processInfo, sizeof(processInfo));

    // 创建启动信息结构体
    STARTUPINFOW startupInfo;
    ZeroMemory(&startupInfo, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);
    startupInfo.wShowWindow = SW_HIDE;

    // 使用 CreateProcessWithLogonW 尝试创建进程
    BOOL result = CreateProcessWithLogonW(
        activeUser.userName.c_str(),   // 用户名
        (activeUser.domainName.empty() ? NULL
            : activeUser.domainName.c_str()),  // 如果域名为空则传入 NULL
        passwordW.c_str(),   // 密码为空
        LOGON_WITH_PROFILE,  // 登录类型
        NULL,                // 不需要具体应用程序
        (LPWSTR)commandLine.c_str(), // 启动参数
        CREATE_NO_WINDOW,  // 创建新控制台
        NULL,                // 环境块
        NULL,                // 当前目录
        &startupInfo,        // 启动信息
        &processInfo         // 进程信息
    );

    // 检查返回结果
    if (!result) {
        DWORD error = GetLastError();
        if (error == 1326) { // ERROR_LOGON_FAILURE
            std::cout << "[+] Password required." << std::endl;
            return 1;
        }
        else if (error == 2) { // ERROR_FILE_NOT_FOUND
            std::cout << "[+] Password not required." << std::endl;
            return 0;
        }
        else if (error == 1385) { // ERROR_LOGON_TYPE_NOT_GRANTED
            std::cerr << "[-] Error 1385: Logon failure, " 
                << "user doesn't have required logon type." << std::endl;
            return 0;
        }
        else if ((!IsRunStricted || isCheckSrvFailed) && error == 5) {
            std::cerr << "[-] Error 5: Unable to access service controller, "
                << "Seclogon service may not start properly." << std::endl;
            return -1;
        }
        else {
            std::cerr << "[-] Error: " << error << std::endl;
            return -1;
        }
    }

    // 成功创建进程,关闭句柄
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);

    return 0; // 无需密码
}

int wmain(int argc, wchar_t* argv[]) {

    // 检查是否有传递的参数
    if (argc > 1) {
        std::wstring arg = argv[1];
        if (arg == L"--terminate") {
            std::wcout << L"[+] Special argument detected: " << arg << std::endl;
            std::wcout << L"Process will terminate immediately." << std::endl;
            return 0;  // 立即退出
        }
    }

    const bool IsRunStricted = IsRunningAsAdmin();

    if (IsRunStricted) {
        std::cout << "[+] The current process is running as an administrator." << std::endl;
    }
    else {
        std::cout << "[-] The current process is not running as an administrator." << std::endl;
    }

    const INT requireCode = GetAccountPasswordRequirement(L"--terminate", IsRunStricted);

    if (requireCode == 1) {
        std::cout << "[*] The current user requires a password. " << std::endl;
        return 1;
    }
    else if(requireCode == 0) {
        std::cout << "[*] The current user does not require a password. " << std::endl;
        return 0;
    }
    else {
        std::cout << "[*] Unknown Type. " << std::endl;
        return requireCode;
    }
}

支持两种模式:

  • (管理员身份启动):严格检查 Seclogon 服务是否启动;
  • (普通模式):测试程序是否能够以管理员身份启动自身,以此来判断是否需要密码。

返回值:

  • 0   —— 无密码
  • 1   —— 有密码
  • -1 或其他值  —— 未知状态,可能由异常导致

效果截图:

标题

等同于命令:

runas /u:your_domain\a_test_user your_application_name

额外:

【启用/禁用设置中 Windows Hello 登陆选项】

修改以下注册表配置单元:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyManager\default\

Settings\AllowSignInOptions

  1. 进入 AllowSignInOptions 子键后,检查右侧名为 value 的值。

  2. 如果存在,双击它并将数值数据设置为 1(启用)/ 0(禁用)

  3. 如果不存在,请通过右键单击右侧面板,选择新建,然后选择 DWORD(32 位)值来创建一个新的 DWORD(32 位)值。

  4. 将此新值命名为 value 并将值数据设置为 1(启用)/ 0(禁用)

  5. 注销登陆会话或者重启计算机生效(主要是使得 smss 和 winlogon 等登陆验证程序更新其内存中的配置)

禁用后设置灰显,无法再操作

【删除 Windows Hello 登陆容器 -- 清除 PIN 密钥】

注意:此操作不需要权限提升,但需要用户注销后才能生效。清除的是当前用户 SID 下的 PIN 密钥。

命令行参数(C:\Windows\System32\CertUtil.exe):

CertUtil -DeleteHelloContainer

删除成功提示

如果已经删除或者不存在容器存根,则会提示:

找不到存根

另一个非官方的方式是通过手动删除存根文件夹及其目录文件。

Windows Hello 登陆容器的本地存储:

C:\Windows\ServiceProfiles\LocalService\AppData\Local\Microsoft\Ngc

此目录下子文件夹名称即用户账户的 SID,文件夹里面包括了多个 dat 文件。

注意:用户需要 TrustedInstaller 权限才能够访问这些目录和文件。(手动删除是比较危险的,仅当您知晓您正在做什么的情况下完成,并且根据分析,注册表中的一些键值也需要正确清除)

您可以使用两种常用的方式之一,操作此文件夹:

  1. (方法一)使用 takeown 获取所有权,然后使用 icacls 授予当前用户访问文件夹及其子目录和文件的完全控制权限;
  2. (方法二)使用 NSudo 等权限提升工具打开具有 TrustedInstaller 特权组并且进程完整性为“系统” 的 cmd.exe 进程,在此命令行中使用 dir 、del、xcopy 等命令操作此目录。

逆向代码(持续更新,目前没有处理错误处理的代码):

此代码等效于 CertUtil.exe ,注意一旦运行将导致 PIN 以及指纹登陆等均被清除(需要注销),且不可逆。下一次登陆将需要用户输入最初设定的登陆密码,所以请谨慎操作!!!

// HelloContainerController.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <Windows.h>
#include <sddl.h>
#include <wincrypt.h>
#include <ncrypt.h>

#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "ncrypt.lib")


typedef HRESULT(__fastcall* __NgcDeleteContainerEx)(PSID pSid, INT nNgcKey);
typedef HRESULT(__fastcall* __NgcLocalFindCredential)(PSID pSid, LONG* lpStatus);
typedef HRESULT(__fastcall* __NgcLocalRemoveCredential)(PSID pSid, LONGLONG unKnown);
typedef HRESULT(__fastcall* __NgcEnumUserIdKeys)(LPCWSTR a1, LPCWSTR a2, LPCWSTR a3,
    LPWSTR lpSidStr, HLOCAL* a5, LPVOID a6);
typedef HRESULT(__fastcall* __NgcFreeEnumState)(__int64 lpStatus);

__NgcDeleteContainerEx NgcDeleteContainerEx;
__NgcLocalFindCredential NgcLocalFindCredential;
__NgcLocalRemoveCredential NgcLocalRemoveCredential;
__NgcEnumUserIdKeys NgcEnumUserIdKeys;
__NgcFreeEnumState NgcFreeEnumState;

HRESULT myHError(DWORD LastError)
{
    DWORD HLastError;
    if (LastError >= 1)
    {
        HLastError = (WORD)LastError | 0x80070000;
        if (!(WORD)LastError)
            return 0x8000FFFFU;
    }
    else {
        //wprintf(L"S_FALSE == hr, nCode = (0x65F01CAu, 1).\n");
        HLastError = LastError;
    }
    return HLastError;
}

HRESULT myHLastError(void)
{
    DWORD LastError = GetLastError();
    return myHError(LastError);
}

void* __fastcall myAlloc(size_t _BytesSize, DWORD uFlags)
{
    void* _ptr;
    switch (uFlags) {
    case 1:
        _ptr = CoTaskMemAlloc(_BytesSize);
        break;
    case 2:
        _ptr = LocalAlloc(NULL, _BytesSize);
        break;
    case 4:
        _ptr = malloc(_BytesSize);
        break;
    default:
        _ptr = nullptr;
        break;
    }
    if (!_ptr) {
        SetLastError(0x8007000EU);
    }
    return _ptr;
}

void __fastcall myFree(void* Buffer, DWORD uFlags)
{
    if (!Buffer)
        return;

    switch (uFlags)
    {
    case 1:
        CoTaskMemFree(Buffer);
        break;
    case 2:
        LocalFree(Buffer);
        break;
    case 4:
        free(Buffer);
        break;
    }
}

HRESULT __fastcall myNCFreeObject(NCRYPT_HANDLE hObject)
{
    const SECURITY_STATUS status = NCryptFreeObject(hObject);
    //CSPrintErrorLineFileData2(0i64, 0xD401C4u, v1, 0);
    if (status > 0)
        return (WORD)status | 0x80070000U;
    return (UINT)status;
}

HRESULT storeGetUserSid(LPWSTR* lpSidStr) {
    HRESULT lastError;
    PSID* lpSid = nullptr;
    SIZE_T uBytes = 0;
    LPWSTR stringSid = nullptr;

    const BOOL status1 = GetTokenInformation(
        (HANDLE)0xFFFFFFFFFFFFFFFA, TokenUser, 0, 0, (PDWORD)&uBytes);
    lastError = myHLastError();

    if (status1 || lastError == 0x8007007AU || lastError == S_OK)
    {
        lpSid = (PSID*)LocalAlloc(0, (DWORD)uBytes);
        if (!lpSid)
        {
            lastError = 0x8009000EU;
            goto endFunc;
        }

        const BOOL status2 = GetTokenInformation(
            (HANDLE)0xFFFFFFFFFFFFFFFA, TokenUser, lpSid, (DWORD)uBytes, (PDWORD)&uBytes);
        lastError = myHLastError();

        if (status2 || (lastError == S_OK))
        {
            const BOOL status3 = ConvertSidToStringSidW(*lpSid, &stringSid);
            lastError = myHLastError();
            if (status3 || (lastError == S_OK))
            {
                *lpSidStr = stringSid;
                stringSid = nullptr;
                lastError = 0;
                goto endFunc;
            }
            lastError = 0x2C430139U;
        }
        else
        {
            lastError = 0x2C3D0139U;
        }
    }
    
endFunc:
    LocalFree(lpSid);
    LocalFree(stringSid);
    return lastError;
}

HRESULT storeDeleteAllNgcPregenData(void)
{
    LSTATUS status_v0; // eax
    LSTATUS status_v1; // ebx

    status_v0 = RegDeleteTreeW(HKEY_LOCAL_MACHINE, L"AIKCertEnroll");
    //CSPrintErrorLineFileData(L"AIKCertEnroll", 0x2BAD0139u, v0);
    status_v1 = RegDeleteTreeW(HKEY_LOCAL_MACHINE, L"PregenKeys");
    //CSPrintErrorLineFileData(L"PregenKeys", 0x2BB00139u, v1);

    if (myHError(status_v0) != S_OK) {
        return myHError(status_v0);
    }
    else {
        return myHError(status_v1);
    }
}

HRESULT __fastcall myCertNameToStr(
    PCERT_NAME_BLOB pName,
    DWORD dwStrType,
    PWCHAR* ppsz)
{
    DWORD csz = NULL;
    WCHAR* psz = nullptr;
    DWORD cbNeeded; 
    SECURITY_STATUS status;

    while (true)
    {
        cbNeeded = CertNameToStrW(1u, pName, dwStrType, psz, csz);
        csz = cbNeeded;
        if (cbNeeded == NULL)
        {
            status = 0x80070002U;
            //CSPrintErrorLineFile(0x75F01CAu, -2147024894);
            if (psz)
                LocalFree(psz);
            return status;
        }
        
        if (psz)
        {
            *ppsz = psz;
            return 0;
        }

        psz = (WCHAR*)LocalAlloc(0, 2 * (static_cast<SIZE_T>(cbNeeded) + 1));
        if (!psz)
        {
            status = 0x8007000EU;
            //CSPrintErrorLineFile(0x76B01CAu, -2147024882);
            return status;
        }
    }
}

HRESULT __fastcall myNCOpenKey(
    NCRYPT_PROV_HANDLE hProvider,
    NCRYPT_KEY_HANDLE* phKey,
    LPCWSTR pszKeyName,
    DWORD dwFlags)
{
    const SECURITY_STATUS status = 
        NCryptOpenKey(hProvider, phKey, pszKeyName, NULL, dwFlags);

    //CSPrintErrorLineFileData2(a3, 0x33901C4u, v6, -2146893811);
    if (status > 0)
        return (WORD)status | 0x80070000;

    return (UINT)status;
}

BOOL __fastcall myCryptExportPublicKeyInfo2(
    HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey,
    DWORD dwKeySpec,  // KeySpec = NULL
    PCERT_PUBLIC_KEY_INFO* lpInfo,
    DWORD* pcbInfo)

    /*
        // dwKeySpec --->
        // certenrolld_begin -- AT_*
        #define AT_KEYEXCHANGE          1
        #define AT_SIGNATURE            2
        // certenrolld_end
    */
{
    BOOL isSuccess;
    PCERT_PUBLIC_KEY_INFO keyInfo = nullptr;
    LPVOID lpInfoBuffer;
    *lpInfo = nullptr;
    *pcbInfo = NULL;
    while (true)
    {
        isSuccess = CryptExportPublicKeyInfoEx(hCryptProvOrNCryptKey, dwKeySpec, 
            1u, nullptr, 0, nullptr, keyInfo, pcbInfo);
        
        if (!isSuccess)
            break;

        if (!*pcbInfo)
        {
            SetLastError(0x8007000DU);
            isSuccess = FALSE;
            break;
        }

        if (keyInfo) {
            *lpInfo = keyInfo;
            return isSuccess;
        }

        lpInfoBuffer = myAlloc(*pcbInfo, 2);
        keyInfo = (PCERT_PUBLIC_KEY_INFO)lpInfoBuffer;

        if (!lpInfoBuffer) {
            *lpInfo = nullptr;
            return FALSE;
        }
    }

    if (keyInfo)
    {
        myFree(keyInfo, 2);
        *lpInfo = nullptr;
    }
    return isSuccess;
}



HRESULT __fastcall storeDeleteCertsByKey(
    NCRYPT_PROV_HANDLE hProvider,
    LPCWSTR pszKeyName,
    HCERTSTORE hCertStore)
{
    HRESULT status;
    PCCERT_CONTEXT i; 
    const CERT_CONTEXT* pCertContext = nullptr;
    //const unsigned __int16* ResourceString;
    const CERT_CONTEXT* pPrevCertContext = nullptr;
    WCHAR* lpsz = nullptr;
    void* pvFindPara1 = nullptr;
    void* pvFindPara2 = nullptr;
    HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey;
    PCERT_PUBLIC_KEY_INFO lpInfo = nullptr;
    hCryptProvOrNCryptKey = 0;
    DWORD pcbInfo = 0;
    
    status = myNCOpenKey(hProvider, &hCryptProvOrNCryptKey, pszKeyName, 0x40u);
    
    if (status > 0)
    {
        //CSPrintErrorLineFileData(a2, 0x2B080139u, v7);
    }
    else if (myCryptExportPublicKeyInfo2(hCryptProvOrNCryptKey, 0, &lpInfo, &pcbInfo))
    {
        pvFindPara2 = pvFindPara1;
        for (i = CertFindCertificateInStore(hCertStore, 1u, 0,
            0x60000u, pvFindPara1, 0);
            ;
            i = CertFindCertificateInStore(hCertStore, 1u, 0,
                0x60000u, pvFindPara2, pPrevCertContext))
        {
            pPrevCertContext = i;
            if (!i)
                break;
            HRESULT result = myCertNameToStr(&i->pCertInfo->Subject, 
                0x2000003u,(PWCHAR*)&lpsz);
            if (result > 0)
                //CSPrintErrorLineFile(0x2B290139u, v11);
                printf("Error: %lx (0x2B290139)\n", result);
            pCertContext = CertDuplicateCertificateContext(pPrevCertContext);
            CertDeleteCertificateFromStore(pCertContext);
            //ResourceString = myLoadResourceString(0x841u);
            //myConsolePrintf(ResourceString, hMem);
            LocalFree(lpsz);
            lpsz = nullptr;
        }
        status = 0;
    }
    else
    {
        status = myHLastError();
        //CSPrintErrorLineFile(0x2B120139u, v8);
        pvFindPara2 = pvFindPara1;
    }
    LocalFree(pvFindPara2);
    if (hCryptProvOrNCryptKey)
        myNCFreeObject(hCryptProvOrNCryptKey);
    return status;
}

HRESULT __fastcall myNCOpenStorageProvider(
    NCRYPT_PROV_HANDLE* phProvider, LPCWSTR pszProviderName, DWORD   dwFlags)
{
    SECURITY_STATUS status;

    status = NCryptOpenStorageProvider(phProvider, pszProviderName, dwFlags);

    //CSPrintErrorLineFileData2(a2, 0x2DA01C4u, v4, 0);
    if (status > 0)
        return (WORD)status | 0x80070000;
    return (UINT)status;
}

__int64 __fastcall storeDeleteAllNgcCerts(LPWSTR lpSidStr)
{
    const WCHAR String = L'\0';
    //const WCHAR* v1; // r12
    HCERTSTORE v2 = nullptr; // rdi
    HCERTSTORE v4 = nullptr; // rsi
    unsigned int v5; // eax
    //unsigned int v6; // edx
    unsigned int v7; // ebx
    //const WCHAR* v8; // rcx
    unsigned int v9; // eax
    //unsigned int v10; // r9d
    //__int64 v11; // rbx
    //const WCHAR* ResourceString; // rax
    int v13; // eax
    //unsigned int v14; // r9d
    int v15; // eax
    HLOCAL hMem = nullptr; // [rsp+68h] [rbp+38h] BYREF
    NCRYPT_PROV_HANDLE hProvider = NULL; // [rsp+70h] [rbp+40h] BYREF
    __int64 v19; // [rsp+78h] [rbp+48h] BYREF

    //v1 = L"MY";
    v19 = 0;
    
    v4 = CertOpenStore((LPCSTR)0xD, 1u, 
        NULL, 0x15200u, L"MY");
    if (!v4)
    {
        v5 = myHLastError();
        //v6 = 727318841;
    LABEL_3:
        v7 = v5;
        //v8 = v1;
    //LABEL_4:
        //CSPrintErrorLineFileData(v8, v6, v5);
        //goto LABEL_20;
    }
    //v1 = L"REQUEST";
    v2 = CertOpenStore((LPCSTR)0xD, 1u, 
        NULL, 0x15200u, L"REQUEST");
    if (!v2)
    {
        v5 = myHLastError();
        //v6 = 728105273;
        goto LABEL_3;
    }
    v5 = myNCOpenStorageProvider(&hProvider, 
        L"Microsoft Passport Key Storage Provider", 
        0x40u);
    v7 = v5;
    if (v5)
    {
        //v6 = 728367417;
        //v8 = L"Microsoft Passport Key Storage Provider";
        goto LABEL_20;
    }
    while (1)
    {
        v9 = NgcEnumUserIdKeys(&String, &String, &String, lpSidStr, &hMem, &v19);
        v7 = v9;
        if (v9 == -2146893782)
            break;
        if (v9)
        {
            //CSPrintErrorLineFile(0x2B7B0139u, v9);
            goto LABEL_20;
        }
        //if (g_fVerbose)
        //{
            //v11 = *((_QWORD*)hMem + 4);
            //ResourceString = myLoadResourceString(0x21Au);
            //myConsolePrintf(L"%ws %ws\n", ResourceString, v11);
       // }
        v13 = storeDeleteCertsByKey(hProvider, 
            *((const WCHAR**)hMem + 4), v4);
        if (v13)
            //CSPrintErrorLineFile(0x2B870139u, v13);
            ;
        v15 = storeDeleteCertsByKey(hProvider, 
            *((const WCHAR**)hMem + 4), v2);
        if (v15)
            //CSPrintErrorLineFile(0x2B8A0139u, v15);
        LocalFree(hMem);
        hMem = 0i64;
    }
    v7 = 0;
LABEL_20:
    LocalFree(hMem);
    if (v19)
        NgcFreeEnumState(v19);
    if (hProvider)
        myNCFreeObject(hProvider);
    if (v4)
        CertCloseStore(v4, 0);
    if (v2)
        CertCloseStore(v2, 0);
    return v7;
}

HRESULT __fastcall storeDeleteAllNgcContainerData(PSID* lpSid)
{
    UINT status;
    LONG lpStatus; 

    status = NgcLocalFindCredential(lpSid, &lpStatus);
    if (!status)
    {
        if (lpStatus && NgcLocalRemoveCredential)
        {
            status = NgcLocalRemoveCredential(lpSid, 3);
            if (!status)
            {

            }
        }
        else
        {
            status = NgcDeleteContainerEx(lpSid, 1);
            if (!status)
            {

            }
        }
    }
    return status;
}

BOOL InitializeNgcDispacher(void)
{

    const HMODULE h_ngclocal = LoadLibraryW(L"ngclocal.dll");
    const HMODULE h_cryptngc = LoadLibraryW(L"cryptngc.dll");

    if (h_ngclocal)
    {
        NgcLocalFindCredential = (__NgcLocalFindCredential)
            GetProcAddress(h_ngclocal, "NgcLocalFindCredential");

        if (!NgcLocalFindCredential)
        {

            return FALSE;
        }
        NgcLocalRemoveCredential = (__NgcLocalRemoveCredential)
            GetProcAddress(h_ngclocal, "NgcLocalRemoveCredential");
        if (!NgcLocalRemoveCredential)
        {

            return FALSE;
        }
    }
    else
    {

        return FALSE;
    }

    if (h_cryptngc)
    {
        NgcDeleteContainerEx = (__NgcDeleteContainerEx)
            GetProcAddress(h_cryptngc, "NgcDeleteContainerEx");

        if (!NgcDeleteContainerEx)
        {

            return FALSE;
        }

        NgcEnumUserIdKeys = (__NgcEnumUserIdKeys)
            GetProcAddress(h_cryptngc, "NgcEnumUserIdKeys");

        if (!NgcEnumUserIdKeys)
        {

            return FALSE;
        }

        NgcFreeEnumState = (__NgcFreeEnumState)
            GetProcAddress(h_cryptngc, "NgcFreeEnumState");

        if (!NgcFreeEnumState)
        {

            return FALSE;
        }
    }
    else
    {

        return FALSE;
    }


    return TRUE;
}

HRESULT __fastcall verbDeleteHelloContainer()
{
    HRESULT status; // eax
    //HRESULT v6; // ecx
    int v7; // eax
    int v8; // eax
    int v9; // ebx
    int v10; // eax
    //const unsigned __int16* ResourceString; // rax
    LPWSTR lpUserSid; // [rsp+20h] [rbp-18h] BYREF

    lpUserSid = 0;
    status = storeGetUserSid(&lpUserSid);
    if (status > 0)
    {
        //v6 = 0x2C5B0139U;
    }
    else
    {
        v7 = storeDeleteAllNgcCerts(lpUserSid);
        if (v7)
            ;//CSPrintErrorLineFile(0x2C600139u, v7);
        v8 = storeDeleteAllNgcPregenData();
        //if (v8)
            //CSPrintErrorLineFile(0x2C650139u, v8);
        v9 = RegDeleteTreeW(HKEY_CURRENT_USER, 
            L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WorkplaceJoin\\AADNGC");
        //CSPrintErrorLineFileData(L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WorkplaceJoin\\AADNGC", 0x2BBE0139u, v9);
        v10 = myHError(v9);
        if (v10)
            ;//CSPrintErrorLineFile(0x2C6A0139u, v10);
        status = storeDeleteAllNgcContainerData((PSID*)lpUserSid);
        if (status == 0)
        {
            //ResourceString = myLoadResourceString(0xC67u);
            //myConsolePrintf(L"\n%ws\n", ResourceString);
            goto LABEL_13;
        }
        //v6 = 745472313;
    }
    //CSPrintErrorLineFile(v6, UserSid);
LABEL_13:
    LocalFree(lpUserSid);
    return status;
}

int main()
{

    /*LPWSTR hMemSid;
    if (storeGetUserSid(&hMemSid) != S_OK || !hMemSid)
    {
        std::wcout << L"错误:获取当前用户 SID 失败。" << std::endl;
    }
    else
    {
        wprintf(L"User SID: %s\n", hMemSid);


    }
    LocalFree(hMemSid);*/
    
    if (!InitializeNgcDispacher())
    {

        return -1;
    }
    verbDeleteHelloContainer();


    return 0;
}

清除传统密码:

貌似只能 PE 模式或者 DOS 模式下破解?

参考文献:


文章出处链接:https://blog.csdn.net/qq_59075481/article/details/143081306

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涟幽516

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值