# Get-WinEvent -LogName Microsoft-Windows-PowerShell/Operational | where {($_.ID -eq "4104" -and ($_.message -match "ScriptBlockText.*.*WaitForSingleObject" -or $_.message -match "ScriptBlockText.*.*QueueUserApc" -or $_.message -match "ScriptBlockText.*.*RtlCreateUserThread" -or $_.message -match "ScriptBlockText.*.*OpenProcess" -or $_.message -match "ScriptBlockText.*.*VirtualAlloc" -or $_.message -match "ScriptBlockText.*.*VirtualFree" -or $_.message -match "ScriptBlockText.*.*WriteProcessMemory" -or $_.message -match "ScriptBlockText.*.*CreateUserThread" -or $_.message -match "ScriptBlockText.*.*CloseHandle" -or $_.message -match "ScriptBlockText.*.*GetDelegateForFunctionPointer" -or $_.message -match "ScriptBlockText.*.*CreateThread" -or $_.message -match "ScriptBlockText.*.*memcpy" -or $_.message -match "ScriptBlockText.*.*LoadLibrary" -or $_.message -match "ScriptBlockText.*.*GetModuleHandle" -or $_.message -match "ScriptBlockText.*.*GetProcAddress" -or $_.message -match "ScriptBlockText.*.*VirtualProtect" -or $_.message -match "ScriptBlockText.*.*FreeLibrary" -or $_.message -match "ScriptBlockText.*.*ReadProcessMemory" -or $_.message -match "ScriptBlockText.*.*CreateRemoteThread" -or $_.message -match "ScriptBlockText.*.*AdjustTokenPrivileges" -or $_.message -match "ScriptBlockText.*.*WriteByte" -or $_.message -match "ScriptBlockText.*.*WriteInt32" -or $_.message -match "ScriptBlockText.*.*OpenThreadToken" -or $_.message -match "ScriptBlockText.*.*PtrToString" -or $_.message -match "ScriptBlockText.*.*FreeHGlobal" -or $_.message -match "ScriptBlockText.*.*ZeroFreeGlobalAllocUnicode" -or $_.message -match "ScriptBlockText.*.*OpenProcessToken" -or $_.message -match "ScriptBlockText.*.*GetTokenInformation" -or $_.message -match "ScriptBlockText.*.*SetThreadToken" -or $_.message -match "ScriptBlockText.*.*ImpersonateLoggedOnUser" -or $_.message -match "ScriptBlockText.*.*RevertToSelf" -or $_.message -match "ScriptBlockText.*.*GetLogonSessionData" -or $_.message -match "ScriptBlockText.*.*CreateProcessWithToken" -or $_.message -match "ScriptBlockText.*.*DuplicateTokenEx" -or $_.message -match "ScriptBlockText.*.*OpenWindowStation" -or $_.message -match "ScriptBlockText.*.*OpenDesktop" -or $_.message -match "ScriptBlockText.*.*MiniDumpWriteDump" -or $_.message -match "ScriptBlockText.*.*AddSecurityPackage" -or $_.message -match "ScriptBlockText.*.*EnumerateSecurityPackages" -or $_.message -match "ScriptBlockText.*.*GetProcessHandle" -or $_.message -match "ScriptBlockText.*.*DangerousGetHandle" -or $_.message -match "ScriptBlockText.*.*kernel32" -or $_.message -match "ScriptBlockText.*.*Advapi32" -or $_.message -match "ScriptBlockText.*.*msvcrt" -or $_.message -match "ScriptBlockText.*.*ntdll" -or $_.message -match "ScriptBlockText.*.*user32" -or $_.message -match "ScriptBlockText.*.*secur32")) } | select TimeCreated,Id,RecordId,ProcessId,MachineName,Message

function Add-Rule {

    $ruleName = "powershell_accessing_win_api";
    $detectRule = {
        
        function Search-DetectableEvents {
            param (
                $event
            )
            
            $ruleName = "powershell_accessing_win_api";
            $detectedMessage = " Detecting use WinAPI Functions in PowerShell";
            $result = $event | where { ($_.ID -eq "4104" -and ($_.message -match "ScriptBlockText.*.*WaitForSingleObject" -or $_.message -match "ScriptBlockText.*.*QueueUserApc" -or $_.message -match "ScriptBlockText.*.*RtlCreateUserThread" -or $_.message -match "ScriptBlockText.*.*OpenProcess" -or $_.message -match "ScriptBlockText.*.*VirtualAlloc" -or $_.message -match "ScriptBlockText.*.*VirtualFree" -or $_.message -match "ScriptBlockText.*.*WriteProcessMemory" -or $_.message -match "ScriptBlockText.*.*CreateUserThread" -or $_.message -match "ScriptBlockText.*.*CloseHandle" -or $_.message -match "ScriptBlockText.*.*GetDelegateForFunctionPointer" -or $_.message -match "ScriptBlockText.*.*CreateThread" -or $_.message -match "ScriptBlockText.*.*memcpy" -or $_.message -match "ScriptBlockText.*.*LoadLibrary" -or $_.message -match "ScriptBlockText.*.*GetModuleHandle" -or $_.message -match "ScriptBlockText.*.*GetProcAddress" -or $_.message -match "ScriptBlockText.*.*VirtualProtect" -or $_.message -match "ScriptBlockText.*.*FreeLibrary" -or $_.message -match "ScriptBlockText.*.*ReadProcessMemory" -or $_.message -match "ScriptBlockText.*.*CreateRemoteThread" -or $_.message -match "ScriptBlockText.*.*AdjustTokenPrivileges" -or $_.message -match "ScriptBlockText.*.*WriteByte" -or $_.message -match "ScriptBlockText.*.*WriteInt32" -or $_.message -match "ScriptBlockText.*.*OpenThreadToken" -or $_.message -match "ScriptBlockText.*.*PtrToString" -or $_.message -match "ScriptBlockText.*.*FreeHGlobal" -or $_.message -match "ScriptBlockText.*.*ZeroFreeGlobalAllocUnicode" -or $_.message -match "ScriptBlockText.*.*OpenProcessToken" -or $_.message -match "ScriptBlockText.*.*GetTokenInformation" -or $_.message -match "ScriptBlockText.*.*SetThreadToken" -or $_.message -match "ScriptBlockText.*.*ImpersonateLoggedOnUser" -or $_.message -match "ScriptBlockText.*.*RevertToSelf" -or $_.message -match "ScriptBlockText.*.*GetLogonSessionData" -or $_.message -match "ScriptBlockText.*.*CreateProcessWithToken" -or $_.message -match "ScriptBlockText.*.*DuplicateTokenEx" -or $_.message -match "ScriptBlockText.*.*OpenWindowStation" -or $_.message -match "ScriptBlockText.*.*OpenDesktop" -or $_.message -match "ScriptBlockText.*.*MiniDumpWriteDump" -or $_.message -match "ScriptBlockText.*.*AddSecurityPackage" -or $_.message -match "ScriptBlockText.*.*EnumerateSecurityPackages" -or $_.message -match "ScriptBlockText.*.*GetProcessHandle" -or $_.message -match "ScriptBlockText.*.*DangerousGetHandle" -or $_.message -match "ScriptBlockText.*.*kernel32" -or $_.message -match "ScriptBlockText.*.*Advapi32" -or $_.message -match "ScriptBlockText.*.*msvcrt" -or $_.message -match "ScriptBlockText.*.*ntdll" -or $_.message -match "ScriptBlockText.*.*user32" -or $_.message -match "ScriptBlockText.*.*secur32")) } | select TimeCreated, Id, RecordId, ProcessId, MachineName, Message;
            if ($result -and $result.Count -ne 0) {
                Write-Output ""; 
                Write-Output "Detected! RuleName:$ruleName";
                Write-Output $detectedMessage;
                Write-Output $result;
                Write-Output ""; 
            }
        };
        . Search-DetectableEvents $args;
    };
    if (! $ruleStack[$ruleName]) {
        $ruleStack.Add($ruleName, $detectRule);
    }
    else {
        Write-Host "Rule Import Error"  -Foreground Yellow;
    }
}