Windows/TestHarnesses/T1078.003_ValidAccounts/LogonUser.ps1
if (-not ('AtomicTestHarnesses_T1078_003.ProcessNativeMethods' -as [Type])) { $TypeDef = @' using System; using System.Runtime.InteropServices; namespace AtomicTestHarnesses_T1078_003 { [Flags] public enum LOGON_TYPE { LOGON32_LOGON_INTERACTIVE = 2, LOGON32_LOGON_NETWORK = 3, LOGON32_LOGON_BATCH = 4, LOGON32_LOGON_SERVICE = 5, LOGON32_LOGON_UNLOCK = 7, LOGON32_LOGON_NETWORK_CLEARTEXT = 8, LOGON32_LOGON_NEW_CREDENTIALS = 9 } [Flags] public enum LOGON_PROVIDER { LOGON32_PROVIDER_DEFAULT = 0, LOGON32_PROVIDER_WINNT35 = 1, LOGON32_PROVIDER_WINNT40 = 2, LOGON32_PROVIDER_WINNT50 = 3 } [Flags] public enum TOKEN_INFORMATION_CLASS { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics, TokenRestrictedSids, TokenSessionId, TokenGroupsAndPrivileges, TokenSessionReference, TokenSandBoxInert, TokenAuditPolicy, TokenOrigin, TokenElevationType, TokenLinkedToken, TokenElevation, TokenHasRestrictions, TokenAccessInformation, TokenVirtualizationAllowed, TokenVirtualizationEnabled, TokenIntegrityLevel, TokenUIAccess, TokenMandatoryPolicy, TokenLogonSid, MaxTokenInfoClass } [StructLayout(LayoutKind.Sequential)] public struct LUID { public UInt32 LowPart; public Int32 HighPart; } [Flags] public enum TokenAccess { STANDARD_RIGHTS_REQUIRED = 0x000F0000, STANDARD_RIGHTS_READ = 0x00020000, TOKEN_ASSIGN_PRIMARY = 0x0001, TOKEN_DUPLICATE = 0x0002, TOKEN_IMPERSONATE = 0x0004, TOKEN_QUERY = 0x0008, TOKEN_QUERY_SOURCE = 0x0010, TOKEN_ADJUST_PRIVILEGES = 0x0020, TOKEN_ADJUST_GROUPS = 0x0040, TOKEN_ADJUST_DEFAULT = 0x0080, TOKEN_ADJUST_SESSIONID = 0x0100, TOKEN_IMPERSONATEUSER = (TOKEN_DUPLICATE | TOKEN_QUERY), TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY), TOKEN_QUERY_ALL = (TOKEN_QUERY | TOKEN_QUERY_SOURCE), TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID) } [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct TOKEN_STATISTICS { public LUID TokenId; public LUID AuthenticationId; public long ExpirationTime; public uint TokenType; public uint ImpersonationLevel; public uint DynamicCharged; public uint DynamicAvailable; public uint GroupCount; public uint PrivilegeCount; public LUID ModifiedId; } public class ProcessNativeMethods { [DllImport("advapi32.dll", SetLastError=true)] public static extern bool LogonUser( string lpszUsername, string lpszDomain, string lpszPassword, LOGON_TYPE dwLogonType, LOGON_PROVIDER dwLogonProvider, ref IntPtr phToken ); [DllImport("kernel32.dll", SetLastError=true)] public static extern bool CloseHandle( IntPtr hHandle); [DllImport("advapi32.dll", SetLastError=true)] public static extern bool GetTokenInformation( IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, ref uint ReturnLength); [DllImport("advapi32.dll", SetLastError=true)] public static extern bool OpenProcessToken( IntPtr ProcessHandle, uint DesiredAccess, ref IntPtr TokenHandle); } } '@ Add-Type -TypeDefinition $TypeDef } function Invoke-ATHLogonUser { <# .SYNOPSIS Test runner for logon events. Technique ID: T1078.003 (Valid Accounts: Local Accounts) .DESCRIPTION Invoke-ATHLogonUser was designed to simulate user logons on a local host. .PARAMETER Credential Specifies the credential the user wants to pass through to the LogonUser API. .PARAMETER LogonType Specifies the LogonType the user wants to use to logon the target user. .PARAMETER TestGuid Optionally, specify a test GUID value to use to override the generated test GUID behavior. .OUTPUTS PSObject Outputs an object consisting of relevant execution details. The following object properties may be populated: * TechniqueID - Specifies the relevant MITRE ATT&CK Technique ID. * TestSuccess - Will be set to True if it was determined that the technique executed successfully. * TestGuid - Specifies the test GUID that was used for the test. * TestCommand - Specifies the command-line arguments used to perform the test. * SourceUser - Specifies the user that initated the logon. * TargetUser - Specifies the user account that was logged on. * LogonType - Specifies the type of logon that was performed. * LogonTypeId - Specifies the ID of the LogonType. * LogonId - Integer value of the logon session ID. .EXAMPLE $cred = Get-Credential Invoke-ATHLogonUser -Credential $cred .EXAMPLE $cred = Get-Credential Invoke-ATHTokenImpersonation -Credential $cred -LogonType LOGON32_LOGON_INTERACTIVE Logs in a user with legitimate credentials under an Interactive Logon (Type 2). #> [CmdletBinding()] param ( [Parameter()] [string] [ValidateSet('LOGON32_LOGON_INTERACTIVE', 'LOGON32_LOGON_NETWORK', 'LOGON32_LOGON_BATCH', 'LOGON32_LOGON_SERVICE','LOGON32_LOGON_UNLOCK', 'LOGON32_LOGON_NETWORK_CLEARTEXT', 'LOGON32_LOGON_NEW_CREDENTIALS')] $LogonType = 'LOGON32_LOGON_INTERACTIVE', [Parameter()] [System.Management.Automation.PSCredential] $Credential, [Guid] $TestGuid = (New-Guid) ) if (-not ($PSBoundParameters.ContainsKey('Credential'))) { Write-Error "Function not supported unless credentials are passed through" return } $split = $Credential.UserName.Split("\") if ($split.Count -eq 2){ $Domain = $split[0] $AccountName = $split[1] } else { $AccountName = $split[0] } $SourceUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name $hToken = [IntPtr]::Zero if ($LogonType -eq 'LOGON32_LOGON_NEW_CREDENTIALS') { $LogonProvider = 'LOGON32_PROVIDER_WINNT50' } else{ $LogonProvider = 'LOGON32_PROVIDER_DEFAULT' } $LogonCreds = [System.Net.NetworkCredential]::new("", $Credential.Password).Password $Logon = [AtomicTestHarnesses_T1078_003.ProcessNativeMethods]::LogonUser( $AccountName, $Domain, $LogonCreds, $LogonType, $LogonProvider, [ref]$hToken );$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() if($Logon -eq 0) { Write-Error $LastError $TestSuccess = $false return } $TestSuccess = $true $TokenLength = 0 $TokenPtr = [IntPtr]::Zero $Result = [AtomicTestHarnesses_T1078_003.ProcessNativeMethods]::GetTokenInformation( $hToken, [AtomicTestHarnesses_T1078_003.TOKEN_INFORMATION_CLASS]::TokenStatistics, $TokenPtr, $TokenLength, [Ref] $TokenLength );$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() [IntPtr]$TokenPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($TokenLength) $Result = [AtomicTestHarnesses_T1078_003.ProcessNativeMethods]::GetTokenInformation( $hToken, [AtomicTestHarnesses_T1078_003.TOKEN_INFORMATION_CLASS]::TokenStatistics, $TokenPtr, $TokenLength, [Ref] $TokenLength );$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() if($Result -eq 0){ Write-Error $LastError return } $TokenStatistics = [System.Runtime.InteropServices.Marshal]::PtrToStructure($TokenPtr, [System.Type][AtomicTestHarnesses_T1078_003.TOKEN_STATISTICS]) $Global:foo = $TokenStatistics $LogonId = $TokenStatistics.AuthenticationId.LowPart #CleanUp $null = [AtomicTestHarnesses_T1078_003.ProcessNativeMethods]::CloseHandle($hToken) switch ($LogonType) { LOGON32_LOGON_INTERACTIVE { $LogonTypeId = 2 } LOGON32_LOGON_NETWORK { $LogonTypeId = 3 } LOGON32_LOGON_BATCH { $LogonTypeId = 4 } LOGON32_LOGON_SERVICE { $LogonTypeId = 5 } LOGON32_LOGON_UNLOCK { $LogonTypeId = 7 } LOGON32_LOGON_NETWORK_CLEARTEXT { $LogonTypeId = 8 } LOGON32_LOGON_NEW_CREDENTIALS { $LogonTypeId = 9 } } #Running Command Information: $TestCommand = $MyInvocation [PSCustomObject] @{ TechniqueID = 'T1078.003' TestSuccess = $TestSuccess TestGuid = $TestGuid TestCommand = $TestCommand.Line SourceUser = $SourceUser TargetUser = $AccountName LogonType = $LogonType LogonTypeId = $LogonTypeId LogonId = $LogonId } } |