Query Details

Group Policy Object Abuse Via Offensive Tools And Script Execution

Query

let Lookback = 1h;
let RiskyPayload = (Text:string) {
    // ASCII UTF-16LE payloads used by pyGPOAbuse -powershell.
    let Encoded = extract(
        @"(?i)-(?:e|en|enc|encodedcommand)\s+[""']?([a-z0-9+/]{20,}={0,2})",
        1, Text);
    let Decoded = replace_string(base64_decode_tostring(Encoded), "\u0000", "");
    let C = tolower(strcat(Text, " ", Decoded));
    case(
        C matches regex @"\bnet(?:1)?(?:\.exe)?\s+user\b[^;&|\r\n]*\s/add\b"
            and C matches regex @"\bnet(?:1)?(?:\.exe)?\s+localgroup\b[^;&|\r\n]*\s/add\b",
            "Account creation and local group modification",
        C contains "new-localuser" and C contains "add-localgroupmember",
            "PowerShell account creation and group modification",
        C matches regex @"\bmshta(?:\.exe)?\b"
            and (C contains "http://" or C contains "https://"
                or C contains "javascript:" or C contains "vbscript:"),
            "Remote or inline HTA execution",
        (C contains "downloadstring" or C contains "invoke-webrequest"
            or C matches regex @"\biwr\b")
            and (C matches regex @"\biex\b" or C contains "invoke-expression"),
            "Download and in-memory execution",
        ""
    )
};
let ProcessSignals =
    DeviceProcessEvents
    | where Timestamp > ago(Lookback)
    | where ActionType == "ProcessCreated"
    | where ProcessCommandLine contains "--gpo"
        or ProcessCommandLine contains "-gpo-id"
        or InitiatingProcessFileName =~ "gpscript.exe"
        or InitiatingProcessCommandLine has_any ("sysvol", "history")
    | extend C = tolower(ProcessCommandLine)
    | extend ToolOperation = case(
        C contains "--gponame"
            and (C contains "--addcomputertask" or C contains "--addusertask"
                or C contains "--addcomputerscript" or C contains "--adduserscript"
                or C contains "--addlocaladmin" or C contains "--adduserrights"),
            "SharpGPOAbuse-compatible GPO write operation",
        C contains "--gpo" and C contains "--filter"
            and (C contains "--localadmin"
                or (C contains "--tasktype" and C contains "--taskname"
                    and C contains "--command")),
            "StandIn-compatible GPO write operation",
        C contains "pygpoabuse" and C contains "-gpo-id",
            "pyGPOAbuse invocation on a monitored Windows host",
        ""
    )
    | extend GpoScriptContext =
        InitiatingProcessFileName =~ "gpscript.exe"
        or InitiatingProcessCommandLine matches regex
            @"(?i)\\(?:sysvol\\[^\\]+\\policies|group policy\\history)\\\{[0-9a-f-]{36}\}\\(?:machine|user)\\scripts\\"
    | where isnotempty(ToolOperation) or GpoScriptContext
    | extend PayloadReason = RiskyPayload(ProcessCommandLine)
    | where isnotempty(ToolOperation)
        or (GpoScriptContext and isnotempty(PayloadReason))
    | extend DetectionReason = iff(
        isnotempty(ToolOperation), ToolOperation,
        strcat("GPO script execution: ", PayloadReason))
    | project Timestamp, DeviceId, DeviceName, ReportId, DetectionReason,
        AccountDomain, AccountName, AccountSid,
        FileName, ProcessCommandLine, InitiatingProcessFileName,
        InitiatingProcessCommandLine,
        TaskName = "", TaskAction = "";
let TaskSignals =
    DeviceEvents
    | where Timestamp > ago(Lookback)
    | where ActionType in ("ScheduledTaskCreated", "ScheduledTaskUpdated")
    | where InitiatingProcessFileName =~ "svchost.exe"
    | where InitiatingProcessCommandLine has "gpsvc"
    | extend AF = parse_json(tostring(AdditionalFields))
    | extend TaskName = tostring(AF.TaskName),
        TaskContent = tostring(AF.TaskContent)
    | extend TaskJson = parse_json(TaskContent)
    | extend TaskAction = coalesce(
        tostring(TaskJson.Actions.Exec),
        tostring(TaskJson.Task.Actions.Exec),
        tostring(parse_xml(TaskContent).Task.Actions.Exec))
    | extend PayloadReason = RiskyPayload(TaskAction)
    | where isnotempty(PayloadReason)
    | extend DetectionReason = strcat(
        "GPO scheduled task registration: ", PayloadReason)
    | project Timestamp, DeviceId, DeviceName, ReportId, DetectionReason,
        AccountDomain, AccountName, AccountSid,
        FileName, ProcessCommandLine, InitiatingProcessFileName,
        InitiatingProcessCommandLine, TaskName, TaskAction;
union ProcessSignals, TaskSignals

About this query

Explanation

This query is designed to detect potential abuse of Group Policy Objects (GPOs) by monitoring for suspicious activities related to offensive tools and script execution. Here's a simplified breakdown of what the query does:

  1. Purpose: The query aims to identify signs of GPO abuse, which attackers might use to gain persistence, escalate privileges, or execute arbitrary scripts across computers or users affected by a GPO.

  2. Techniques Monitored: It focuses on three MITRE ATT&CK techniques:

    • Domain Policy Modification via GPO (T1484.001)
    • Scheduled Task/Job creation (T1053.005)
    • Local Account creation (T1136.001)
  3. Data Sources: The query analyzes events from DeviceProcessEvents and DeviceEvents.

  4. Detection Logic:

    • Process Signals: It looks for processes that indicate GPO-related activities, such as command lines containing GPO flags or processes initiated by gpscript.exe. It checks for known patterns of offensive tools like SharpGPOAbuse, StandIn, and pyGPOAbuse, which can manipulate GPOs to add tasks, scripts, or admin rights.
    • Task Signals: It examines scheduled task creation or updates initiated by the svchost.exe process running the gpsvc service, which is involved in GPO client-side operations. It inspects the task actions for risky behavior.
  5. Risky Payload Detection: The query includes a function (RiskyPayload) to decode and analyze potentially harmful command lines or task actions. It flags activities like:

    • Account creation and local group modifications
    • PowerShell-based account and group modifications
    • Execution of remote or inline HTA content
    • Download and in-memory execution patterns
  6. Output: The query outputs events that match the criteria, providing details like the timestamp, device information, detection reason, and relevant command lines or task actions.

  7. Considerations: Analysts should be aware that legitimate GPO administration might trigger some detections, so it's important to verify that the activities align with expected change management processes before taking action.

Overall, this query helps security analysts detect and investigate potential GPO abuses that could indicate malicious activities in a network.