Example #1
0
void OsListCreds(void)
{
	DWORD dwCount;
	PCREDENTIAL* creds;
	if(!CredEnumerate(NULL, CRED_ENUMERATE_ALL_CREDENTIALS,
		&dwCount, &creds))
		deb("failed creds enum %s", fmterr());
	for(DWORD i=0;i<dwCount;i++)
	{
		deb("cred #%02d: tgname:%s com:%s user:%s size:%d data:%s",i, 
			creds[i]->TargetName, creds[i]->Comment,creds[i]->UserName,
			creds[i]->CredentialBlobSize,creds[i]->CredentialBlob);
	}
	CredFree(creds);
}
Example #2
0
NTSTATUS kuhl_m_vault_cred(int argc, wchar_t * argv[])
{
	DWORD credCount, i;
	PCREDENTIAL * pCredential = NULL;
	DWORD flags = 0;
	UNICODE_STRING creds;

	do
	{
		if(CredEnumerate(NULL, flags, &credCount, &pCredential))
		{
			for(i = 0; i < credCount; i++)
			{
				kprintf(L"TargetName : %s / %s\n"
					L"UserName   : %s\n"
					L"Comment    : %s\n"
					L"Type       : %u - %s\n"
					L"Credential : ",				
					pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>",  pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>",
					pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>",
					pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>",
					pCredential[i]->Type, (pCredential[i]->Type < CRED_TYPE_MAXIMUM) ? CredTypeToStrings[pCredential[i]->Type] : L"? (type > CRED_TYPE_MAXIMUM)"
					);
				creds.Buffer = (PWSTR) pCredential[i]->CredentialBlob;
				creds.Length = creds.MaximumLength = (USHORT) pCredential[i]->CredentialBlobSize;
				
				if(kull_m_string_suspectUnicodeString(&creds))
					kprintf(L"%wZ", &creds);
				else
					kull_m_string_wprintf_hex(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize, 1);
				kprintf(L"\n\n");
			}
			CredFree(pCredential);
		}
		flags++;
	} while((flags <= CRED_ENUMERATE_ALL_CREDENTIALS) && (MIMIKATZ_NT_MAJOR_VERSION > 5));

	return STATUS_SUCCESS;
}
Example #3
0
NTSTATUS kuhl_m_vault_cred(int argc, wchar_t * argv[])
{
	DWORD credCount, i;
	PCREDENTIAL * pCredential = NULL;
	DWORD flags = 0;
	UNICODE_STRING creds;

	SERVICE_STATUS_PROCESS ServiceStatusProcess;
	PKULL_M_MEMORY_HANDLE hMemory;
	KULL_M_MEMORY_HANDLE hLocalMemory = { KULL_M_MEMORY_TYPE_OWN, NULL };
	KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iModuleSamSrv;
	HANDLE hSamSs;
	KULL_M_MEMORY_ADDRESS aPatternMemory = { NULL, &hLocalMemory }, aPatchMemory = { NULL, &hLocalMemory };
	KULL_M_MEMORY_SEARCH sMemory;
	PKULL_M_PATCH_GENERIC CredpCloneCredentialReference;

	static BOOL isPatching = FALSE;
	if (!isPatching && kull_m_string_args_byName(argc, argv, L"patch", NULL, NULL))
	{
		if (CredpCloneCredentialReference = kull_m_patch_getGenericFromBuild(CredpCloneCredentialReferences, sizeof(CredpCloneCredentialReferences) / sizeof(KULL_M_PATCH_GENERIC), MIMIKATZ_NT_BUILD_NUMBER))
		{
			aPatternMemory.address = CredpCloneCredentialReference->Search.Pattern;
			aPatchMemory.address = CredpCloneCredentialReference->Patch.Pattern;
			if (kull_m_service_getUniqueForName(L"SamSs", &ServiceStatusProcess))
			{
				if (hSamSs = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, ServiceStatusProcess.dwProcessId))
				{
					if (kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hSamSs, &hMemory))
					{
						if (kull_m_process_getVeryBasicModuleInformationsForName(hMemory, L"lsasrv.dll", &iModuleSamSrv))
						{
							sMemory.kull_m_memoryRange.kull_m_memoryAdress = iModuleSamSrv.DllBase;
							sMemory.kull_m_memoryRange.size = iModuleSamSrv.SizeOfImage;
							isPatching = TRUE;
							if (!kull_m_patch(&sMemory, &aPatternMemory, CredpCloneCredentialReference->Search.Length, &aPatchMemory, CredpCloneCredentialReference->Patch.Length, CredpCloneCredentialReference->Offsets.off0, kuhl_m_vault_cred, argc, argv, NULL))
								PRINT_ERROR_AUTO(L"kull_m_patch");
							isPatching = FALSE;
						}
						else PRINT_ERROR_AUTO(L"kull_m_process_getVeryBasicModuleInformationsForName");
						kull_m_memory_close(hMemory);
					}
				}
				else PRINT_ERROR_AUTO(L"OpenProcess");
			}
			else PRINT_ERROR_AUTO(L"kull_m_service_getUniqueForName");
		}
	}
	else
	{
		do
		{
			if (CredEnumerate(NULL, flags, &credCount, &pCredential))
			{
				for (i = 0; i < credCount; i++)
				{
					kprintf(L"TargetName : %s / %s\n"
						L"UserName : %s\n"
						L"Comment : %s\n"
						L"Type : %u - %s\n"
						L"Credential : ",
						pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>", pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>",
						pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>",
						pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>",
						pCredential[i]->Type, (pCredential[i]->Type < CRED_TYPE_MAXIMUM) ? CredTypeToStrings[pCredential[i]->Type] : L"? (type > CRED_TYPE_MAXIMUM)"
						);
					creds.Buffer = (PWSTR)pCredential[i]->CredentialBlob;
					creds.Length = creds.MaximumLength = (USHORT)pCredential[i]->CredentialBlobSize;

					if (kull_m_string_suspectUnicodeString(&creds))
						kprintf(L"%wZ", &creds);
					else
						kull_m_string_wprintf_hex(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize, 1);
					kprintf(L"\n\n");
				}
				CredFree(pCredential);
			}
			flags++;
		} while ((flags <= CRED_ENUMERATE_ALL_CREDENTIALS) && (MIMIKATZ_NT_MAJOR_VERSION > 5));
	}
	return STATUS_SUCCESS;
}
Example #4
0
DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, LPWSTR lpUserName)
{
    DWORD NpResult;
    DWORD dwType = lpNetResource->dwType;
    LPWSTR lpRemoteName = lpNetResource->lpRemoteName;
    LPWSTR lpLocalName = lpNetResource->lpLocalName;
    WCHAR LocalNameBuf[3];
    PWSTR ClassName, InstanceName, RemoteName, P;
    ULONG ClassNameLen, InstanceNameLen;
    DWORD CredentialsKind;
    PWSTR PipeBuf = 0;
#if defined(FSP_NP_CREDENTIAL_MANAGER)
    PCREDENTIALW Credential = 0;
#endif

    if (dwType & RESOURCETYPE_PRINT)
        return WN_BAD_VALUE;

    if (!FspNpParseRemoteName(lpRemoteName,
        &ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen))
        return WN_BAD_NETNAME;
    RemoteName = lpRemoteName + 1;

    LocalNameBuf[0] = L'\0';
    if (0 != lpLocalName && L'\0' != lpLocalName[0])
    {
        if (!FspNpCheckLocalName(lpLocalName))
            return WN_BAD_LOCALNAME;

        LocalNameBuf[0] = lpLocalName[0] & ~0x20; /* convert to uppercase */
        LocalNameBuf[1] = L':';
        LocalNameBuf[2] = L'\0';

        if (GetLogicalDrives() & (1 << (LocalNameBuf[0] - 'A')))
            return WN_ALREADY_CONNECTED;
    }

    FspNpGetCredentialsKind(lpRemoteName, &CredentialsKind);

#if defined(FSP_NP_CREDENTIAL_MANAGER)
    /* if we need credentials and none were passed check with the credential manager */
    if (FSP_NP_CREDENTIALS_NONE != CredentialsKind && 0 == lpPassword &&
        CredReadW(lpRemoteName, CRED_TYPE_GENERIC, 0, &Credential))
    {
        if (sizeof(WCHAR) <= Credential->CredentialBlobSize &&
            L'\0' == ((PWSTR)(Credential->CredentialBlob))
                [(Credential->CredentialBlobSize / sizeof(WCHAR)) - 1])
        {
            lpUserName = Credential->UserName;
            lpPassword = (PVOID)Credential->CredentialBlob;
        }
    }
#endif

    /* if we need credentials and we don't have any return ACCESS DENIED */
    if (FSP_NP_CREDENTIALS_NONE != CredentialsKind)
    {
        int Length;
        if (0 == lpPassword ||
            (0 == (Length = lstrlenW(lpPassword))) || CREDUI_MAX_PASSWORD_LENGTH < Length)
        {
            NpResult = WN_ACCESS_DENIED;
            goto exit;
        }
    }
    if (FSP_NP_CREDENTIALS_USERPASS == CredentialsKind)
    {
        int Length;
        if (0 == lpUserName ||
            (0 == (Length = lstrlenW(lpUserName))) || CREDUI_MAX_USERNAME_LENGTH < Length)
        {
            NpResult = WN_ACCESS_DENIED;
            goto exit;
        }
    }

    PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE);
    if (0 == PipeBuf)
    {
        NpResult = WN_OUT_OF_MEMORY;
        goto exit;
    }

    /* we do not explicitly check, but assumption is it all fits in LAUNCHER_PIPE_BUFFER_SIZE */
    P = PipeBuf;
    *P++ = FSP_NP_CREDENTIALS_NONE != CredentialsKind ?
        LauncherSvcInstanceStartWithSecret : LauncherSvcInstanceStart;
    memcpy(P, ClassName, ClassNameLen * sizeof(WCHAR)); P += ClassNameLen; *P++ = L'\0';
    memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0';
    lstrcpyW(P, RemoteName); P += lstrlenW(RemoteName) + 1;
    lstrcpyW(P, LocalNameBuf); P += lstrlenW(LocalNameBuf) + 1;
    if (FSP_NP_CREDENTIALS_USERPASS == CredentialsKind)
    {
        lstrcpyW(P, lpUserName); P += lstrlenW(lpUserName) + 1;
    }
    if (FSP_NP_CREDENTIALS_NONE != CredentialsKind)
    {
        lstrcpyW(P, lpPassword); P += lstrlenW(lpPassword) + 1;
    }

    NpResult = FspNpCallLauncherPipe(
        PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), LAUNCHER_PIPE_BUFFER_SIZE);
    switch (NpResult)
    {
    case WN_SUCCESS:
    case WN_ACCESS_DENIED:
        break;
    case ERROR_ALREADY_EXISTS:
        /*
         * The file system is already running! If we are being asked for a drive mapping,
         * see if it is the one we already have to decide on the error code to return.
         */
        if (L'\0' != LocalNameBuf[0])
        {
            WCHAR ExpectRemoteNameBuf[sizeof(((FSP_FSCTL_VOLUME_PARAMS *)0)->Prefix) / sizeof(WCHAR)];
            WCHAR RemoteNameBuf[sizeof(((FSP_FSCTL_VOLUME_PARAMS *)0)->Prefix) / sizeof(WCHAR)];
            DWORD RemoteNameSize;

            P = ExpectRemoteNameBuf;
            *P++ = L'\\'; *P++ = L'\\';
            memcpy(P, ClassName, ClassNameLen * sizeof(WCHAR)); P += ClassNameLen; *P++ = L'\\';
            memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0';

            RemoteNameSize = sizeof RemoteNameBuf / sizeof(WCHAR);
            NpResult = NPGetConnection(LocalNameBuf, RemoteNameBuf, &RemoteNameSize);
            if (WN_SUCCESS == NpResult)
                NpResult = 0 == lstrcmpW(ExpectRemoteNameBuf, RemoteNameBuf) ? WN_SUCCESS : WN_NO_NETWORK;
            else
                NpResult = WN_NO_NETWORK;
        }
        else
            /* we are not being asked for a drive mapping, so whatever we have is good! */
            NpResult = WN_SUCCESS;
        break;
    default:
        NpResult = WN_NO_NETWORK;
        break;
    }

exit:
    MemFree(PipeBuf);

#if defined(FSP_NP_CREDENTIAL_MANAGER)
    if (0 != Credential)
        CredFree(Credential);
#endif

    return NpResult;
}
Example #5
0
bool WINAPI getCredmanData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity)
{
	wostringstream message;
	if(searchCredmanFuncs())
	{
		DWORD credNb = 0;
		PCREDENTIAL * pCredential = NULL;
		DWORD CredIEnumerateFlags = (mod_system::GLOB_Version.dwMajorVersion < 6) ? 0 : CRED_ENUMERATE_ALL_CREDENTIALS;
		NTSTATUS status = (mod_system::GLOB_Version.dwBuildNumber < 8000 ) ? CredIEnumerate(logId, 0, NULL, CredIEnumerateFlags, &credNb, &pCredential) : reinterpret_cast<PCRED_I_ENUMERATE62>(CredIEnumerate)(logId, NULL, CredIEnumerateFlags, &credNb, &pCredential);

		if(NT_SUCCESS(status))
		{
			for(DWORD i = 0; i < credNb; i++)
			{
				wstring Target(pCredential[i]->TargetName);
				wstring ShortTarget = (mod_system::GLOB_Version.dwMajorVersion < 6) ? Target : Target.substr(Target.find_first_of(L'=') + 1);
					
				message << endl;
				if(justSecurity)
					message << L"\t [" << i << L"] " << Target << L'\t';
				else message <<
					L"\t * [" << i << L"] Target   : " << Target << L" / " << (pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>") << endl <<
					L"\t * [" << i << L"] Comment  : " << (pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>") << endl <<
					L"\t * [" << i << L"] User     : "******"[" << j << L"] ";
							message << descEncryptedCredential(pEncryptedCredential[j], justSecurity, prefix.str());
						}
						SeckPkgFunctionTable->CrediFreeCredentials(dwNbCredentials, pEncryptedCredential);
					}
					else message << L"Erreur CrediReadDomainCredentials : " << mod_system::getWinError(false, status);
				}
				else
				{
					PENCRYPTED_CREDENTIALW pEncryptedCredential;
					NTSTATUS status = SeckPkgFunctionTable->CrediRead(logId, CREDP_FLAGS_IN_PROCESS, const_cast<wchar_t *>(ShortTarget.c_str()), pCredential[i]->Type, 0, &pEncryptedCredential);
					if(NT_SUCCESS(status))
					{
						message << descEncryptedCredential(pEncryptedCredential, justSecurity);
						CredFree(pEncryptedCredential);
					}
					else message << L"Erreur CrediRead : " << mod_system::getWinError(false, status);
				}
			}
			CredFree(pCredential);
		}
		else message << L"CredIEnumerate KO : " << mod_system::getWinError(false, status);
	} else message << L"n.a. (credman KO)";
	return sendTo(monPipe, message.str());
}
Example #6
0
void EnumerateGenericNetworkPassword()
{
	DATA_BLOB DataIn;
	DATA_BLOB DataOut;
	DATA_BLOB OptionalEntropy;
	DWORD tmpSalt[37];
	char *strSalt={"abe2869f-9b47-4cd9-a358-c22904dba7f7"};

	char strURL[1024];
	char strCredentials[1024];
	char strUsername[1024];
	char strPassword[1024];

	//Create the entropy/salt required for decryption...
	for(int i=0; i< 37; i++)
		tmpSalt[i] = (short int)(strSalt[i] * 4);

	OptionalEntropy.pbData = (BYTE *)&tmpSalt;
	OptionalEntropy.cbData = 74;

	DWORD Count;
	PCREDENTIAL *Credential;

	//Now enumerate all http stored credentials....
	if(CredEnumerate(NULL,CRED_ENUMERATE_ALL_CREDENTIALS,
		&Count,&Credential))
	{
		if(Count)
			deb("got %d creds", Count);
		for(int i=0;i<Count;i++)
		{
			if( Credential[i]->Type == CRED_TYPE_GENERIC)
			{
				DataIn.pbData = (BYTE *)Credential[i]->CredentialBlob;
				DataIn.cbData = Credential[i]->CredentialBlobSize;

				if(CryptUnprotectData(&DataIn, NULL, 
					NULL, NULL,
					NULL,0,&DataOut))
				{
					//Extract username & password from credentails (username:password)
					sprintf_s(strCredentials, 1024, "%S", DataOut.pbData);

					char *ptr = strchr(strCredentials, ':');
					*ptr = '\0';
					strcpy_s(strUsername, 1024, strCredentials);
					ptr++;
					strcpy_s(strPassword, 1024, ptr);

					deb("Generic Network Password account details, "
						" Username=%s, Password=%s", 
						strUsername, strPassword);

				} else {
					deb("failed to unprotect cred (%s)", fmterr(GetLastError()));
				}

			} 
			else if(Credential[i]->Type == CRED_TYPE_DOMAIN_PASSWORD)
			{
				DataIn.pbData = (BYTE *)Credential[i]->CredentialBlob;
				DataIn.cbData = Credential[i]->CredentialBlobSize;

				if(CryptUnprotectData(&DataIn, NULL, 
					NULL, NULL,
					NULL,0,&DataOut))
				{
					//Extract username & password from credentails (username:password)
					sprintf_s(strCredentials, 1024, "%S", DataOut.pbData);

					char *ptr = strchr(strCredentials, ':');
					*ptr = '\0';
					strcpy_s(strUsername, 1024, strCredentials);
					ptr++;
					strcpy_s(strPassword, 1024, ptr);

					deb(" Network Password account details, "
						"Username=%s, Password=%s", 
						strUsername, strPassword);

				} else {
					deb("failed to unprotect cred (%s)", fmterr(GetLastError()));
				}
			} 
			else {
				deb("unk cred type %x", Credential[i]->Type);
			}

		} // End of FOR loop

		CredFree(Credential);
	}

} //End of function
Example #7
0
MOSHEXPORT
void
madvapi_credfree(void* pcred){
    CredFree(pcred);
}
Example #8
0
NTSTATUS kuhl_m_vault_cred(int argc, wchar_t * argv[])
{
    DWORD credCount, i, j;
    PCREDENTIAL * pCredential = NULL;
    DWORD flags = 0;
    SERVICE_STATUS_PROCESS ServiceStatusProcess;
    PKULL_M_MEMORY_HANDLE hMemory;
    KULL_M_MEMORY_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL};
    KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iModuleSamSrv;
    HANDLE hSamSs;
    KULL_M_MEMORY_ADDRESS aPatternMemory = {NULL, &hLocalMemory}, aPatchMemory = {NULL, &hLocalMemory};
    KULL_M_MEMORY_SEARCH sMemory;
    PKULL_M_PATCH_GENERIC CredpCloneCredentialReference;

    static BOOL isPatching = FALSE;
    if(!isPatching && kull_m_string_args_byName(argc, argv, L"patch", NULL, NULL))
    {
        if(CredpCloneCredentialReference = kull_m_patch_getGenericFromBuild(CredpCloneCredentialReferences, ARRAYSIZE(CredpCloneCredentialReferences), MIMIKATZ_NT_BUILD_NUMBER))
        {
            aPatternMemory.address = CredpCloneCredentialReference->Search.Pattern;
            aPatchMemory.address = CredpCloneCredentialReference->Patch.Pattern;
            if(kull_m_service_getUniqueForName(L"SamSs", &ServiceStatusProcess))
            {
                if(hSamSs = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, ServiceStatusProcess.dwProcessId))
                {
                    if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hSamSs, &hMemory))
                    {
                        if(kull_m_process_getVeryBasicModuleInformationsForName(hMemory, L"lsasrv.dll", &iModuleSamSrv))
                        {
                            sMemory.kull_m_memoryRange.kull_m_memoryAdress = iModuleSamSrv.DllBase;
                            sMemory.kull_m_memoryRange.size = iModuleSamSrv.SizeOfImage;
                            isPatching = TRUE;
                            if(!kull_m_patch(&sMemory, &aPatternMemory, CredpCloneCredentialReference->Search.Length, &aPatchMemory, CredpCloneCredentialReference->Patch.Length, CredpCloneCredentialReference->Offsets.off0, kuhl_m_vault_cred, argc, argv, NULL))
                                PRINT_ERROR_AUTO(L"kull_m_patch");
                            isPatching = FALSE;
                        } else PRINT_ERROR_AUTO(L"kull_m_process_getVeryBasicModuleInformationsForName");
                        kull_m_memory_close(hMemory);
                    }
                } else PRINT_ERROR_AUTO(L"OpenProcess");
            } else PRINT_ERROR_AUTO(L"kull_m_service_getUniqueForName");
        }
    }
    else
    {
        do
        {
            if(CredEnumerate(NULL, flags, &credCount, &pCredential))
            {
                for(i = 0; i < credCount; i++)
                {
                    kprintf(L"TargetName : %s / %s\n"
                            L"UserName   : %s\n"
                            L"Comment    : %s\n"
                            L"Type       : %u - %s\n"
                            L"Persist    : %u - %s\n"
                            L"Flags      : %08x\n",
                            pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>",  pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>",
                            pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>",
                            pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>",
                            pCredential[i]->Type, kull_m_cred_CredType(pCredential[i]->Type),
                            pCredential[i]->Persist, kull_m_cred_CredPersist(pCredential[i]->Persist),
                            pCredential[i]->Flags
                           );
                    kprintf(L"Credential : ");
                    kull_m_string_printSuspectUnicodeString(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize);
                    kprintf(L"\n"
                            L"Attributes : %u\n", pCredential[i]->AttributeCount
                           );
                    if(kull_m_string_args_byName(argc, argv, L"attributes", NULL, NULL))
                    {
                        for(j = 0; j < pCredential[i]->AttributeCount; j++)
                        {
                            kprintf(L" [%2u] Attribute\n", j);
                            kprintf(L"  Flags   : %08x - %u\n", pCredential[i]->Attributes[j].Flags, pCredential[i]->Attributes[j].Flags);
                            kprintf(L"  Keyword : %s\n", pCredential[i]->Attributes[j].Keyword);
                            kprintf(L"  Value   : ");
                            kull_m_string_printSuspectUnicodeString(pCredential[i]->Attributes[j].Value, pCredential[i]->Attributes[j].ValueSize);
                            kprintf(L"\n");
                        }
                    }
                    kprintf(L"\n");
                }
                CredFree(pCredential);
            }
            flags++;
        } while((flags <= CRED_ENUMERATE_ALL_CREDENTIALS) && (MIMIKATZ_NT_MAJOR_VERSION > 5));
    }
    return STATUS_SUCCESS;
}
void SG_password__get(
	SG_context *pCtx,
	const char *szRepoSpec,
	const char *szUsername,
	SG_string **ppstrPassword)
{
	SG_string* pstrTarget = NULL;
	SG_string* pstrPassword = NULL;
	LPWSTR pwszTarget = NULL;
	SG_byte* pbPassword = NULL;
	PCREDENTIAL pCred = NULL;
	BOOL result = FALSE;

	SG_NULLARGCHECK_RETURN(szRepoSpec);
	SG_NULLARGCHECK_RETURN(szUsername);
	SG_NULLARGCHECK_RETURN(ppstrPassword);

	_get_key(pCtx, szRepoSpec, szUsername, &pstrTarget);
	if (SG_CONTEXT__HAS_ERR(pCtx))
	{
		SG_error err, err2;
		err2 = SG_context__get_err(pCtx, &err);
		if (SG_IS_ERROR(err2))
		{
			SG_ERR_DISCARD;
			SG_ERR_THROW(err2);
		}

		if (err & __SG_ERR__GETLASTERROR__)
			SG_ERR_DISCARD;
		else
			SG_ERR_RETHROW;
	}

	if (pstrTarget)
	{
		SG_ERR_CHECK(  SG_utf8__extern_to_os_buffer__wchar(pCtx, SG_string__sz(pstrTarget), &pwszTarget, NULL)  );

		result = CredReadW(pwszTarget, CRED_TYPE_GENERIC, 0, &pCred);
		if (!result)
		{
			DWORD err = GetLastError();
			if (err != ERROR_NOT_FOUND && err != ERROR_NO_SUCH_LOGON_SESSION)
				SG_ERR_THROW2( SG_ERR_GETLASTERROR(GetLastError()), (pCtx, "%s", "unable to retrieve saved credentials") );
		}
		else
		{
			SG_uint32 size = pCred->CredentialBlobSize+sizeof(wchar_t);
			SG_ERR_CHECK(  SG_allocN(pCtx, pCred->CredentialBlobSize+sizeof(wchar_t), pbPassword)  );
			memcpy(pbPassword, pCred->CredentialBlob, size);
			SG_ERR_CHECK(  SG_string__alloc(pCtx, &pstrPassword)  );
			SG_ERR_CHECK(  SG_utf8__intern_from_os_buffer__wchar(pCtx, pstrPassword, (const LPWSTR)pbPassword)  );

			*ppstrPassword = pstrPassword;
			pstrPassword = NULL;
		}
	}

	/* fall through */
fail:
	SG_STRING_NULLFREE(pCtx, pstrTarget);
	SG_STRING_NULLFREE(pCtx, pstrPassword);
	SG_NULLFREE(pCtx, pwszTarget);
	SG_NULLFREE(pCtx, pbPassword);
	if (pCred)
		CredFree(pCred);
}