In this article I will introduce a new script, Inject-LogonCredentials, that uses PowerShell (specifically, the Invoke-ReflectivePEInjection script) to inject credentials in memory.
I’ll start with a brief review of the current commonly used methods of using stolen credentials.
- Doing a RunAs with a users credential. The downside of a RunAs is that it creates an “Explicit Credential Logon” event in the Windows event logs (event id 4648). As you can see in the picture below, this event shows the account being logged in with (testuser), and the account initiating the new logon (joe). It also shows the process that called the logon API. Incident responders commonly look for this event as an indicator of lateral movement, so it should be avoided.
- Injecting credentials directly in to LSASS. This technique, used by Windows Credential Editor, involves injecting a DLL in to LSASS and modifying its memory to add your credentials. Unfortunately, if LSASS is set to be a protected process in Windows 8.1 this technique fails because only specially signed processes can manipulate protected processes. While it is true that tools such as Mimikatz can disable protected processes, I do not want to load a kernel driver (which is what Mimikatz does) every time I pivot.
- Implementing your own authentication protocols. Examples include the NTLM module in Metasploit, which can perform NTLM authentication without relying on Windows authentication. This has the benefit of staying out of the logs (since it does not rely on Windows authentication libraries). Unfortunately it limits you to using Metasploit modules that use the Metasploit NTLM module. This module only supports NTLM, and not Kerberos. One new feature of Windows 8.1 allows user accounts to be banned from using NTLM, which will prevent this module from functioning.
As noted, doing a RunAs throws a suspicious event log because it allows an incident responder to see that some random user is logging in with domain admin credentials (or other privileged credentials). Instead of simply doing a RunAs, I will do the following:
- Create a DLL that:
- Opens a named pipe and reads a domain/username/password combination.
- Read a logon type from the named pipe (current supported types are Interactive, RemoteInteractive, and NetworkCleartext).
- Calls LsaLogonUser to create a logon with the credentials it was supplied, and as the logon type supplied.
- Impersonates the token returned by LsaLogonUser with its current thread, which allows the token to be kidnapped by Invoke-TokenManipulation.
- Reflectively inject this DLL in to winlogon.exe using Invoke-ReflectivePEInjection.
- Supply the DLL with the username/password to create a logon for by using a named pipe.
- Call LsaLogonUser with the supplied credentials and logon type within winlogon.exe.
The differences between this script and a normal RunAs are:
- Process calling the logon API will show up as Winlogon.exe.
- User initiating the logon is SYSTEM, not a random user account.
- You can specify the logon type. For example, you can make LSASS think the account is connecting via RDP, which might be normal. You can also make LSASS think the account is a local logon (someone physically using the computer).
As you can see, everything that was suspicious in the 4648 event log is gone. But how do you use these credentials now that they are in memory?
Once you run the script, you can use Invoke-TokenManipulation (or incognito if you are using Metasploit) to kidnap the token of the new logon. You can use this impersonated token to pivot off box using things such as SMB, WMI, and PowerShell remoting.
Here’s an example:
Inject-LogonCredentials –DomainName demo –UserName administrator –Password Password1 –ExistingWinLogon
Invoke-TokenManipulation –CreateProcess “c:\windows\system32\windowspowershell\v1.0\powershell.exe” -UserName “demo\administrator”
It’s worth mentioning that the script currently has two modes:
- ExistingWinLogon: Injects the DLL in to an already running winlogon process. The DLL will never be unloaded from this process so there is forensic evidence that is left behind if someone does analysis on the winlogon process.
- NewWinLogon: Creates a new winlogon process, running as SYSTEM, using token kidnapping. Injects the logon DLL in to this new winlogon process. Once you are done, you can kill the process. This allows you to delete the process and wipe away DLL injection evidence, but Windows will log that PowerShell.exe created winlogon, which would look strange if anyone notices.
Hopefully this has helped illustrate how Invoke-ReflectivePEInjection can be used to do awesome things.You can find the script at: https://github.com/clymb3r/PowerShell/tree/master/Inject-LogonCredentials
As usual, it will also be added to PowerSploit.