Access violation on Server 2012R2 during UAC with custom credential provider - winapi

I have a custom credential provider and the credential implements IConnectableCredentialProviderCredential. It is written using Visual C++ 2019 and ATL. It works on Server 2016/2019 and Windows 10/11, if I use it on Server 2012R2, then the UI crashes during UAC--trying to elevate a non-admin user to use an Administrator PowerShell session for example.
I attached a remote debugger and the debugger intercepts the exception consistently as: Exception thrown at 0x00007FFE9E627EC3 (authui.dll) in consent.exe: 0xC0000005: Access violation reading location 0x0000000000000008.
I had some logging/debugging code and I could see that the system never calls my Connect() or GetSerialization() method on the credential when it crashes. My logging showed the username and password getting set, but then after keying the Enter key or clicking on OK, the process crashes without ever asking the credential to serialize its credentials. The logging showed that the last call into my credential provider was to ICredentialProviderCredential::SetStringValue() which was corresponding to entering the password before keying the Enter key.
Since it was throwing an access violation, I assumed that I must be passing bad data back to the system when it was calling the ICredentialProvder::GetFieldDescriptorAt() or possibly the ICredentialProviderCredential::GetStringValue() or some other CredentialProvider::Get...() function. I've gone over the methods with fine tooth comb as well as all other methods and have found nothing. For the GetStringValue() implementation, I am calling SHStrDupW() like in the SDK examples, and for GetFieldDescriptorAt() I am calling the same functions as the SDK examples. In fact, I copied the SDK code.
I decided to distill my credential provider down to a minimal reproducible example. That minimal example is at https://github.com/willcoxson/CredDemo
If anyone could see where I might be passing bad data back in one of the methods, I'd sure be grateful.

IConnectableCredentialProviderCredential have sense only for CPUS_LOGONcase. so for other scenarion your QueryInterface must return E_NOINTERFACE when system ask for IConnectableCredentialProviderCredential
in your concrete case we have CPUS_CREDUI scenario. inside function
void CGetSerializationJob::Do(CREDENTIAL_PROVIDER_THREAD_JOB_CONTEXT const &) system query you for IConnectableCredentialProviderCredential ("9387928b-ac75-4bf9-8ab2-2b93c4a55290" )
and if you return this interface - run next code
system try access some object by pointer - CPLAPCallback::_pSingleton
but pointer is 0. crash exactly at yellow line ( 0xC0000005: Access violation reading location 0x0000000000000008. )

Related

How to request full access when sign in using near-js

I've got a problem with signing in using near-js. I just call wallet.requestSignIn and it works but always I see that application request Limited access. There is nothing about Limited and Full access in documentation so I just guess that I should do something to request Full access
In order to keep your wallet secure, a web app signing in to NEAR should not request full access keys.
Instead you ask for an access key to the smart contract your web app is going to use, and you can also specify which method names on the contract that should be allowed calling ( see the methodNames property of the SigninOptions )

Stop Auto Logon after failure - Custom Credential Provider Windows

I've taken up Widows Samples on Credential Providers and have built one using them as a reference. I'm able to log in seamlessly, wither by giving username and password manually. I've set
CustomCredential::SetSelected (__out BOOL* pbAutoLogon) {
*pbAutoLogon = TRUE; // FALSE;
return S_OK;
}
Now, AutoLogon, when the Tile is selected, is happening seamlessly.
As a test case, I changed the password, and as expected the Login fails. After failure, an error message appears and when I click OK ( this is the only option ), the credentials are resubmitted for a retry. How do can we stop this behavior? Which method gets called after the authentication failure?
I've handled ReportResult() but that did not help.
Thanks in advance.
It's been a while - but I believe GetSerialization() is called to return serialized credentials to LogonUI. You need to implement this as well. The credential provider samples I think have working code for KERB_INTERACTIVE_UNLOCK_LOGON.
You can also change *pbAutoLogon conditionally in SetSelected() - I do this in my credential provider depending on certain results.
ReportResult() would be called after GetSerialization returns its result to LogonUI. Inside ReportResult() you could do things like clear the password box (which is done in the samples code.)
If you're not returning serialized credentials in GetSerialization then I think you might get the kind of error you listed in your original post. In the credential samples KerbInteractiveUnlockLogonPack() is called in GetSerialization() and this is what 'logs' the user in effectively.
The error seems specific - 'the user has not been granted the requested logon type' so maybe it has something to do with the rights of the user you're testing with.
If you are using remote desktop, make sure your users are members of the right groups to be able to login (https://support.jumpdesktop.com/hc/en-us/articles/216424183-General-RDP-You-must-be-granted-the-Allow-log-on-through-the-Terminal-or-Remote-Desktop-Services-Right-) or if it is a regular user that it is allowed interactive login.
Also - SetSelected() Gets called when your credential provider is clicked on - I'm not sure if it gets called after every logon attempt or not (my guess is that it doesn't.) In my credential provider I am using a custom logon dialog that I show using SetSelected().

CreateProcessAsUser failing with 1349 :The type of the token is inappropriate for its attempted use

Creating a token using OpenThreadToken() and then passing it to CreateProcessAsUser is failing with:
1349:The type of the token is inappropriate for its attempted use.
It is successful on one machine but failing on other win2008r2.
The DesiredAccess that is passed to OpenThreadToken is:
TOKEN_QUERY|TOKEN_IMPERSONATE|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY
exist 2 TOKEN_TYPE - TokenPrimary and TokenImpersonation . CreateProcessAsUser accept only TokenPrimary. from another side, thread if have token - always have TokenImpersonation token type. so token returned by OpenThreadToken is TokenImpersonation you need call DuplicateTokenEx(.., TokenPrimary, ); and pass this new token to CreateProcessAsUser
--- EDIT ---
really begin from Windows 7 we can use and TokenImpersonation as parameter to CreateProcessAsUser although in MSDN written about primary token. but in xp/2003 used another code for CreateProcessAsUser - direct called NtSetInformationProcess(,ProcessAccessToken,); -> PspSetPrimaryToken -> PspAssignPrimaryToken -> STATUS_BAD_TOKEN_TYPE
The target thread is impersonating at the time of the call, so you're getting the wrong token. Using OpenProcessToken() instead of OpenThreadToken() should resolve the problem. If for some reason you only have the thread ID and not the process ID, GetProcessIdOfThread() will bridge the gap.
Alternatively, if you had some reason for wanting to use the impersonation token you would have to use DuplicateTokenEx() to convert it into a primary token. But this is unlikely to be what you want to do, because it introduces a race condition, since you would typically have no way to know when the target thread is impersonating the right user. Also, it will not work at all if the thread turns out to be impersonating at the anonymous level.
(This race condition is probably also why it seems to be working on some machines but not others, although it might also be that the impersonation takes place only on certain Windows versions.)

In ASP.NET is there an event fired on a Windows Authentication log in failure? (Logging the details of a Windows Authentication failure)

I am building a .NET 4.0, ASP.NET MVC 3 intranet application that runs on IIS 7.5 in integrated mode. Windows Authentication is used to govern access to the website. The Windows Authentication module is enabled and all other auth modules are disabled.
Currently when a user provides improper credentials, the Windows Authentication module correctly rejects the credentials and re-displays a login prompt. It does so 3 times, after which a standard .NET 401 Unauthorized Access page is shown. This is expected and desirable.
My goal: I would like to be able to log the details of the failed authentication attempt to my own custom event log. Particularly, to capture the user name that was used in the log in attempt. (I'll accept that capturing the password is not likely to be possible for security reasons.)
Is my goal possible?
I have already built a working an IHttpModule module and added it as an event handler to the WindowsAuthenticationModule, like this:
myWindowsAuthenticationModule.Authenticate += WindowsAuthentication_Authenticate;
But my code does not get called in the case of a failed log in attempt, presumably because WindowsAuthenticationModule has already decided that the log in is failed and so there is no point calling my module. My module does get called after a successful log in attempt, and so I am certain that my event handler is properly set up.
To the best of my knowledge, the WindowsAuthenticationModule does not expose an event that is fired when authentication fails, so that option is out.
Any ideas? Or am I barking up a tree that has no solution?
I was looking at the same issue, and looks like there is no events for windows authentication, even that Authenticate event is common for forms and windows.
But I found a solution to this!
http://www.codeproject.com/Articles/11202/Redirecting-to-custom-401-page-when-quot-Access-de
UPDATE
From original article
protected void Application_EndRequest(Object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (context.Response.Status.Substring(0,3).Equals("401"))
{
if(User.Identity.IsAuthenticated)
{
// this means user is authenticated, but 401 still returned
// which means no access to page or whatever you are trying to access?
}
}
}
UPDATE2
I also found out that this solution doesn't work in all cases. I was testing in different environments, so was working for me, but not for others.
By default IIS will not even run this piece of code and just return it's own error page, what you want to do is tell IIS to let app handle errors.
<httpErrors existingResponse="PassThrough">
</httpErrors>
Now, with that said, IIS won't return any more of custom errors and you will need to handle them in application, ie. not only 401, but 403, 405, etc

AJAX Call to MVC Controller that Calls a WebService

We are working on an internal MVC3 app that purely uses Windows Authentication. There's a view that does an AJAX call to a controller action that does some processing before calling a web service. The problem we are running into is that if Anonymous access is turned off (as in Windows Authentication is on), calling the service from the controller actions results in a 401: Unauthorized error.
We have run into a problem of the double hop issue where credentials aren't passed correctly from server to server when calling a service within a service. I'm wondering if the AJAX call is somewhat mimicing the same behavior and not transmitting the correct Windows credentials to the controller which then doesn't pass the correct credentials to the web service.
I've seen some posts that shows how to pass a username and password along with the jQuery call but nothing mentions, an effective way, to bring along Windows Authentication with it.
Has anyone run into a similar issue? We would rather not leave Anonymous access on the web service as it is somewhat sensitive data that we would like to control access to.
Do you have identity impersonation turned on as described in this question:
How to get Windows user name when identity impersonate="true" in asp.net?
A colleague did some research over the weekend and determined it may have something to do with Kerberos authentication setup on the server as well as the jQuery call. In order to get around it, we just refactored the web service into a library that the application just references. We made it a web service initially as we thought in the future this data would need to be accessed from other applications. Running into this issue, we will most likely make it into a NuGet package.
Thanks for the comments.

Resources