Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Issue] Shell commands don't use impersonated tokens #45

Open
attl4s opened this issue Aug 27, 2019 · 12 comments
Open

[Issue] Shell commands don't use impersonated tokens #45

attl4s opened this issue Aug 27, 2019 · 12 comments
Labels
bug Something isn't working high-priority

Comments

@attl4s
Copy link

attl4s commented Aug 27, 2019

Hi Ryan :)

I've been playing around these days with Covenant and I've realized that MakeToken's functionality may not be working as intended.

1 - Token applied wrongly on ShellCmd actions?

The new token created with MakeToken seems is not working with Shellcmd. However, with powershell it does:

netonly

2 - Logon Types not working on low-priv users?

When using MakeToken with a low-priv user, only the logon type LOGON32_LOGON_NEW_CREDENTIALS seems to work. If another one is used, let's say LOGON32_LOGON_INTERACTIVE, the session breaks.

interactivelogonfailing

  • As you can see, if I run MakeToken with LOGON32_LOGON_NEW_CREDENTIALS, it says that the token has been made and impersonated correctly.
  • But when I try to do the same with LOGON32_LOGON_INTERACTIVE, the session breaks.

However, when doing this same process with an admin user, it succeeds:
interactivelogoncorrect

I've seen that MakeToken is using

  • LogonUserA to create a token with a logon session associated.
  • ImpersonateLoggedOnUser to apply that token to the primary thread of our process.

As Microsoft remarks, admin should not be needed (https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-impersonateloggedonuser):

All impersonate functions, including ImpersonateLoggedOnUser allow the requested impersonation if one of the following is true:
...
A process (or another process in the caller's logon session) created the token using explicit credentials through LogonUser or LsaLogonUser function.
...

Many thanks!!

@attl4s attl4s changed the title MakeToken with a low-priv user Issues with MakeToken Aug 27, 2019
@cobbr
Copy link
Owner

cobbr commented Aug 27, 2019

Hi @attl4s! I'm not really sure what's going on, I'm not able to reproduce either of those issues.
Screen Shot 2019-08-27 at 9 49 12 AM
Screen Shot 2019-08-27 at 9 48 00 AM

Can you re-test and verify you are still seeing these behaviors? If so, can you provide your OS version?

@attl4s
Copy link
Author

attl4s commented Aug 27, 2019

How curious

Here's where Covenant is running (git clonned today)

.NET Core SDK (reflecting any global.json):
Version: 2.2.300
Commit: 73efd5bd87

Runtime Environment:
OS Name: debian
OS Version: 9
OS Platform: Linux
RID: debian.9-x64
Base Path: /usr/share/dotnet/sdk/2.2.300/

Host (useful for support):
Version: 2.2.5
Commit: 0a3c9209c0

.NET Core SDKs installed:
2.2.300 [/usr/share/dotnet/sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.2.5 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.2.5 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.2.5 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

The testing VM (Fileserver01) was a Microsoft Windows Server 2019 Standard with no GUI.

I have tried it again in another Microsoft Windows Server 2019 Standard (Sqlserver01) with graphical interface and there somehow it works.

working

For the shellcmd , I keep having the same problem on Sqlserver01
shellcmd

Later I will try on a Windows 10 machine to see if something changes.

Thank you!

@attl4s
Copy link
Author

attl4s commented Sep 1, 2019

Hi again Ryan!

Microsoft Windows 10 Enterprise (Evaluation)

  • The LOGON32_LOGON_INTERACTIVE seems to work properly here as well.
  • But Shellcmd fails for me again

newcredagain

I'm gonna keep digging to see if I can get something straight because this doesn't really make sense hahaha. It would be nice if a third person could test and post these things here.

Thank you

@cobbr
Copy link
Owner

cobbr commented Sep 1, 2019

That's so strange. Which version of Windows 10 are you using? (i.e. build number)

@attl4s
Copy link
Author

attl4s commented Sep 1, 2019

Host Name: WS04
OS Name: Microsoft Windows 10 Enterprise Evaluation
OS Version: 10.0.18362 N/A Build 18362
OS Manufacturer: Microsoft Corporation

@cobbr
Copy link
Owner

cobbr commented Sep 17, 2019

Ok, finally looked into this a little bit, and think I have confirmed that MakeToken -> ShellCmd is a bug. The System.Diagnostics.Process namespace (used by ShellCmd) does not use the impersonated token as expected.

I'll have to do some thinking about how to handle this. Thanks again for the heads up @attl4s

@cobbr cobbr added bug Something isn't working high-priority labels Sep 17, 2019
@cobbr cobbr changed the title Issues with MakeToken [Bug] Shell commands don't use impersonated tokens Sep 17, 2019
@cobbr cobbr changed the title [Bug] Shell commands don't use impersonated tokens [Issue] Shell commands don't use impersonated tokens Sep 18, 2019
@cobbr
Copy link
Owner

cobbr commented Sep 29, 2019

@attl4s This is more of a workaround than a solution. But I've added ShellRunAs and ShellCmdRunAs tasks that accept Username and Password parameters, that will run a command as the specified user.

This is a built-in feature of the System.Diagnostics.Process class. For now, these tasks still won't use a previously impersonated token from the ImpersonateToken task.

@cobbr
Copy link
Owner

cobbr commented Jun 19, 2020

Ok, sorry it's taken so long, but I have now added a CreateProcessWithToken command that will start a new process using a previously impersonated token from the MakeToken, ImpersonateUser, or ImpersonateProcess commands.

I think CreateProcessWIthToken + ShellRunAs + ShellCmdRunAs are going to have to be the solutions to this issue, there's no way to get the shell task to use an impersonated token without totally changing how it works.

Let me know if this solution is sufficient @attl4s!

@attl4s
Copy link
Author

attl4s commented Jun 19, 2020

AWESOME!

I'll take a look tomorrow and let you know. Thank you Ryan!!

@attl4s
Copy link
Author

attl4s commented Jun 20, 2020

Hi again!

I've been trying the new CreateProcessWithToken and these are the results:

Working like a charm in high integrity contexts:

image

Failing in medium integrity contexts:

image

AFAIK this is the intended behaviour of CreateProcessWithTokenW:

The process that calls CreateProcessWithTokenW must have the SE_IMPERSONATE_NAME privilege. If this function fails with ERROR_PRIVILEGE_NOT_HELD (1314), use the CreateProcessAsUser or CreateProcessWithLogonW function instead. Typically, the process that calls

So considering the situation, I think this is indeed the best solution.

Sum up:

  1. If you don't need shellcmd
    1.1. As almost every other task in Covenant is executed within the current process, MakeToken should work just fine.
  2. If you need shellcmd
    2.1. High integrity context?: use CreateProcessWithToken as if it was shellcmd (or ShellRunAs / ShellCmdRunAs).
    2.2. Medium integrity context?: use ShellRunAs / ShellCmdRunAs

Thanks again! if everything is OK, feel free to close this issue

@cobbr
Copy link
Owner

cobbr commented Aug 26, 2020

Thanks @attl4s, thanks for the heads up. I might look into the CreateProcessAsUser api in medium integrity contexts: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasusera

@attl4s
Copy link
Author

attl4s commented Aug 26, 2020

Souds like the perfect solution! I didn't notice the hToken within that call :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working high-priority
Projects
None yet
Development

No branches or pull requests

2 participants