Detection Rule Development: Disable Windows Event and Security Logs
How I took a issue created by another github user and added value to the original query and helped mold it into a new detection rule.
Original Query
process where event.module == "powershell" and
process.args : ( "powershell.exe", "Set-Service", "EventLog", "Disabled")
Example Data
{
"_id": "89933b5f64737a55c666fd1a7155b02c533e65e040dddfb611d83e563afa6796",
"_index": ".siem-signals-siemplify-000002",
"_score": "1",
"_type": "_doc",
"@timestamp": "2021-03-31T04:43:10.154Z",
"agent": {
"ephemeral_id": "af1d7136-94f2-42bd-8ac6-c0c320381735",
"hostname": "DESKTOP-AL49UOF",
"id": "41e48758-8b2b-474a-bd22-b0d6356025e2",
"name": "DESKTOP-AL49UOF",
"type": "filebeat",
"version": "7.12.0"
},
"data_stream": {
"dataset": "windows.powershell",
"namespace": "default",
"type": "logs"
},
"ecs": {
"version": "1.8.0"
},
"elastic_agent": {
"id": "ebe1c190-9026-11eb-97b7-670157a7fe8c",
"version": "7.12.0"
},
"event": {
"action": "Provider Lifecycle",
"category": "process",
"code": "600",
"created": "2021-03-31T04:42:07.705Z",
"dataset": "windows.powershell",
"ingested": "2021-03-31T04:42:12.329Z",
"kind": "signal",
"module": "powershell",
"provider": "PowerShell",
"sequence": "5",
"type": "info"
},
"host": {
"architecture": "x86_64",
"hostname": "DESKTOP-AL49UOF",
"id": "8c87c48e-9f44-4504-abe1-2a4428adaa71",
"ip": "2603:8001:bf00:f9c0::12c8,2603:8001:bf00:f9c0:e816:7a3a:71e2:3702,2603:8001:bf00:f9c0:7d5e:a714:f6a6:c52f,fe80::e816:7a3a:71e2:3702,192.168.1.132,2001:0:34f1:8072:3802:3b0e:3f57:fe7b,fe80::3802:3b0e:3f57:fe7b",
"mac": "08:00:27:03:19:05,00:00:00:00:00:00:00:e0",
"name": "DESKTOP-AL49UOF",
"os": {
"build": "15063.1387",
"family": "windows",
"kernel": "10.0.15063.1387 (WinBuild.160101.0800)",
"name": "Windows 10 Pro",
"platform": "windows",
"type": "windows",
"version": "10.0"
}
},
"input": {
"type": "winlog"
},
"log": {
"level": "information"
},
"message": "Provider \"Environment\" is Started. \n\nDetails: \n\tProviderName=Environment\n\tNewProviderState=Started\n\n\tSequenceNumber=5\n\n\tHostName=ConsoleHost\n\tHostVersion=5.1.15063.1387\n\tHostId=c4373ed5-2fbc-405c-bcde-f5c370a32546\n\tHostApplication=powershell.exe -ExecutionPolicy Bypass -C Set-Service EventLog -StartupType Disabled\n\n\tEngineVersion=\n\tRunspaceId=\n\tPipelineId=\n\tCommandName=\n\tCommandType=\n\tScriptName=\n\tCommandPath=\n\tCommandLine=",
"powershell": {
"process": {
"executable_version": "5.1.15063.1387"
},
"provider": {
"name": "Environment",
"new_state": "Started"
}
},
"process": {
"args": "powershell.exe,-ExecutionPolicy,Bypass,-C,Set-Service,EventLog,-StartupType,Disabled",
"args_count": "8",
"command_line": "powershell.exe -ExecutionPolicy Bypass -C Set-Service EventLog -StartupType Disabled",
"entity_id": "c4373ed5-2fbc-405c-bcde-f5c370a32546",
"title": "ConsoleHost"
},
"signal": {
"_meta": {
"version": "25"
},
"ancestors": "{\"id\":\"uyyWhngBHIiL0gIkyYbp\",\"type\":\"event\",\"index\":\".ds-logs-windows.powershell-default-2021.03.29-000001\",\"depth\":0}",
"depth": "1",
"original_event": {
"action": "Provider Lifecycle",
"category": "process",
"code": "600",
"created": "2021-03-31T04:42:07.705Z",
"dataset": "windows.powershell",
"ingested": "2021-03-31T04:42:12.329199354Z",
"kind": "event",
"module": "powershell",
"provider": "PowerShell",
"sequence": "5",
"type": "info"
},
"original_time": "2021-03-31T04:42:06.367Z",
"parent": {
"depth": "0",
"id": "uyyWhngBHIiL0gIkyYbp",
"index": ".ds-logs-windows.powershell-default-2021.03.29-000001",
"type": "event"
},
"parents": "{\"id\":\"uyyWhngBHIiL0gIkyYbp\",\"type\":\"event\",\"index\":\".ds-logs-windows.powershell-default-2021.03.29-000001\",\"depth\":0}",
"rule": {
"actions": "",
"author": "ipninichuck",
"created_at": "2021-03-31T04:38:02.741Z",
"created_by": "ipninichuck",
"description": "Windows Event Log has been set to not start-up on reboot. This is often done by an attacker to evade any future detections.",
"enabled": "true",
"exceptions_list": "",
"false_positives": "",
"filters": "",
"from": "now-360s",
"id": "e0a77120-91da-11eb-97b7-670157a7fe8c",
"immutable": "false",
"index": "logs-*,winlogbeat-*",
"interval": "5m",
"language": "eql",
"license": "",
"max_signals": "100",
"meta": {
"from": "1m",
"kibana_siem_app_url": "https://denoir-stack.kb.us-west1.gcp.cloud.es.io:9243/s/siemplify/app/security"
},
"name": "Windows Event Log Disabled",
"output_index": ".siem-signals-siemplify",
"query": "process where event.module == \"powershell\" and\nprocess.args : ( \"powershell.exe\", \"Set-Service\", \"EventLog\", \"Disabled\")\n",
"references": "",
"risk_score": "73",
"risk_score_mapping": "",
"rule_id": "bebc93c7-c122-4223-9257-c0084b53aa24",
"severity": "high",
"severity_mapping": "",
"tags": "Hosts ,Windows,threat detection ,Defense Evasion",
"threat": "{\"framework\":\"MITRE ATT&CK\",\"tactic\":{\"id\":\"TA0005\",\"reference\":\"https://attack.mitre.org/tactics/TA0005\",\"name\":\"Defense Evasion\"},\"technique\":[{\"id\":\"T1562\",\"reference\":\"https://attack.mitre.org/techniques/T1562\",\"name\":\"Impair Defenses\",\"subtechnique\":[{\"id\":\"T1562.002\",\"reference\":\"https://attack.mitre.org/techniques/T1562/002\",\"name\":\"Disable Windows Event Logging\"}]}]}",
"to": "now",
"type": "eql",
"updated_at": "2021-03-31T04:38:10.703Z",
"updated_by": "ipninichuck",
"version": "1"
},
"status": "open"
},
"winlog": {
"api": "wineventlog",
"channel": "Windows PowerShell",
"computer_name": "DESKTOP-AL49UOF",
"event_id": "600",
"keywords": "Classic",
"opcode": "Info",
"provider_name": "PowerShell",
"record_id": "41",
"task": "Provider Lifecycle"
}
}
</details>
I came across this Tweet that gave me an idea of how to expand the query above and add potential value to the detection query and hopefully get added to the Detection Rule repo.
And if you look at the tweet you would see logman
, which is not something talked about that often.
logman stop EventLog-System -ets
And this command with winlogbeat-*
index would look like the following:
winlog.event_data.CommandLine.keyword:*logman\ stop\ EventLog\-System*
First Attempt
So my first attempt at improving the rule, I quickly came up with the following query.
process where event.module == "cmd" and process.args : ( "cmd.exe", "EventLog-System", "EventLog", "stop", "logman" )
But I soon realize that this would be extremely noisy as is and needed to think a little about how to improve more upon the current version.
Second Attempt
process where event.type in ("start", "process_started") and
process.name:"cmd.exe" and process.args in ("EventLog-System",
"EventLog",
"stop",
"logman") or
process.name:("powershell.exe", "powershell_ise.exe") and
process.args in ("Set-Service", "EventLog", "Disabled")
Feedback
So after getting some feedback from Elastic Security Researchers, I realized that the detection rule would be too noisy as is and would require exceptions. And first change I need to make, was to add process.pe.original_file_name
to account for renames and to add pwsh.exe
. And second, I needed to have the rule look for activity from uncommon parents and/or create a sequence to help with the noise. And third, the rule query as is would alert just if logman
or EventLog
is mentioned. So I needed to make changes that the query would only trigger when they are disabled or stopped.
Third Attempt
process where event.type in ("start", "process_started") and
((process.name:"cmd.exe" or process.pe.original_file_name == "cmd.exe") and
process.args in ("EventLog-System", "EventLog", "stop","logman")) or
((process.name:"pwsh.exe" or
process.pe.original_file_name == "pwsh.exe") and
process.args in ("Set-Service", "EventLog", "Disabled")) or
((process.name:"powershell.exe" or
process.pe.original_file_name == "powershell.exe") and
process.args in ("Set-Service", "EventLog", "Disabled")) or
((process.name:"powershell_ise.exe" or
process.pe.original_file_name == "powershell_ise.exe") and
process.args in ("Set-Service", "EventLog", "Disabled"))
Feedback
After getting some feedback on this attempt, I learned that process.args
is fine, but with in
or :
that it will alert on any of them, so cmd /c logman create..
would alert just because we are looking for process.args in ("EventLog-System", "EventLog", "stop","logman")
instead of looking for process.args : logman and process.args : stop
Fourth Attempt
process where event.type in ("start", "process_started") and
((process.name:"cmd.exe" or
process.pe.original_file_name == "cmd.exe") and
process.args : ("EventLog-System", "EventLog", "stop","logman","delete") and
not process.args : ("create","query","update","import","export")) or
((process.name:"pwsh.exe" or
process.pe.original_file_name == "pwsh.exe") and
process.args : ("Set-Service", "EventLog", "Disabled")) or
((process.name:"powershell.exe" or
process.pe.original_file_name == "powershell.exe") and
process.args : ("Set-Service", "EventLog", "Disabled")) or
((process.name:"powershell_ise.exe" or
process.pe.original_file_name == "powershell_ise.exe") and
process.args : ("Set-Service", "EventLog", "Disabled"))
Feedback
Got some additional feedback that the current query would return unrelated events cmd.exe /c delete file.txt
and need to adjust to account for this. And got some extra help from the following article.
Fifth and Could Be Final Attempt
And the following query is the current version and could be my final attempt if it's approved and merged into the detection rules repo.
process where event.type in ("start", "process_started") and
((process.name:"logman.exe" or process.pe.original_file_name == "Logman.exe") and
process.args : "EventLog-*" and process.args : ("stop", "delete")) or
((process.name : ("pwsh.exe", "powershell.exe", "powershell_ise.exe") or
process.pe.original_file_name in
("pwsh.exe", "powershell.exe", "powershell_ise.exe")) and
process.args : "Set-Service" and
process.args: "EventLog" and
process.args : "Disabled") or
((process.name:"auditpol.exe" or process.pe.original_file_name == "AUDITPOL.EXE") and
process.args : "/success:disable")
UPATED: 2021-28-JULY
6th and Final
process where event.type in ("start", "process_started") and
((process.name:"logman.exe" or process.pe.original_file_name == "Logman.exe") and
process.args : "EventLog-*" and process.args : ("stop", "delete")) or
((process.name : ("pwsh.exe", "powershell.exe", "powershell_ise.exe") or process.pe.original_file_name in
("pwsh.exe", "powershell.exe", "powershell_ise.exe")) and
process.args : "Set-Service" and process.args: "EventLog" and process.args : "Disabled") or
((process.name:"auditpol.exe" or process.pe.original_file_name == "AUDITPOL.EXE") and process.args : "/success:disable")
You can view the final rule here