-
Notifications
You must be signed in to change notification settings - Fork 8
car to stix
flow = search Flow:Message
smb_events = filter flow where (dest_port == "445" and protocol == "smb")
smb_events.file_name = smb_events.proto_info.file_name
output smb_write
[network-traffic:dst_port = 445 AND network-traffic:protocols[*] = 'microsoft-ds']
[network-traffic:dst_port = 445 AND network-traffic:protocols[*] = 'smb2']
- CAR Pseudocode is a clobbered copypasta of the SMB Write analytic
- Don't know if we want to include 'smb2' as a potential protocol or not.
process = search Process:Create
cmd = filter process where (exe == "cmd.exe")
output cmd
[process:name = 'cmd.exe']
[process:create:name = 'cmd.exe']
or
[process:name = 'cmd.exe' and process:action = 'create']
or
create:[process:name = 'cmd.exe]
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
- These are some possible ways of expressing "create" events.
users_list = search UserSession:Login
users_grouped = group users_list by hostname
users_grouped = from users_grouped select min(time) as earliest_time, max(time) as latest_time count(user) as user_count
multiple_logins = filter users_grouped where (latest_time - earliest_time <= 1 hour and user_count > 1)
output multiple_logins
login:[user-account] AS INITIAL FOLLOWEDBY login:[user-account:user_id != $INITIAL:user_id] WITHIN 3600 SECONDS
- Requires actions of course
- Requires variable substitution so you can indicate that one action compares to another in a certain way
- Requires the concept of the pattern being evaluated on a single host, which seems like an attribute of the login event
- Requires generic object w/o selection based on properties (selection is done via variable substitution)
- Kind of implicitly means "on same host"
- Requires that Object Paths must be allowed to appear on the right side of a Comparison Operator. Currently the spec says that the right side must be a constant.
processes = search Process:Create
reg = filter processes where (exe == "reg.exe" and parent_exe == "cmd.exe")
cmd = filter processes where (exe == "cmd.exe" and parent_exe != "explorer.exe"")
reg_and_cmd = join (reg, cmd) where (reg.ppid == cmd.pid and reg.hostname == cmd.hostname)
output reg_and_cmd
processes = search Process:Create
reg_processes = filter processes where (
exe == "reg.exe" and parent_exe == "cmd.exe" and
(command_line == "*add*" OR command_line == "*delete*" OR command_line == "*copy*" OR command_line == "*restore*" OR command_line == "*load*" OR command_line == "*import*")
)
reg_processes_counted = count(hostname) as host_count group reg_processes by command_line
reg_processes_sorted = sort by host_count
output reg_processes_sorted
[process:name = 'reg.exe' AND process:parent_ref.name = 'cmd.exe' AND process:parent_ref.parent_ref.name != 'explorer.exe']
[process:name = 'reg.exe' AND process:parent_ref.name = 'cmd.exe' AND (process:command_line MATCHES 'add' OR process:command_line MATCHES 'delete' OR process:command_line MATCHES 'copy' OR process:command_line MATCHES 'restore' OR process:command_line MATCHES 'load' OR process:command_line MATCHES 'import')]
create:[process:name = 'reg.exe' AND process:parent_ref.name = 'cmd.exe' AND process:parent_ref.parent_ref.name != 'explorer.exe']
create:[process:name = 'reg.exe' AND process:parent_ref.name = 'cmd.exe' AND (process:command_line MATCHES 'add' OR process:command_line MATCHES 'delete' OR process:command_line MATCHES 'copy' OR process:command_line MATCHES 'restore' OR process:command_line MATCHES 'load' OR process:command_line MATCHES 'import')]
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
- The STIX relationship model here actually simplifies a lot of the pseudocode by directly typing the processes together
- It doesn't have the ability to do a count across hosts though and sort by the most common. That type of data arrangement (putting the most matches first) is probably out of scope for STIX?
processes = search Process:Create
reg_processes = filter processes where (exe == "arp.exe" or exe == "at.exe" or exe == "attrib.exe"
or exe == "cscript.exe" or exe == "dsquery.exe" or exe == "hostname.exe"
or exe == "ipconfig.exe" or exe == "mimikatz.exe" or exe == "nbstat.exe"
or exe == "net.exe" or exe == "netsh.exe" or exe == "nslookup.exe"
or exe == "ping.exe" or exe == "quser.exe" or exe == "qwinsta.exe"
or exe == "reg.exe" or exe == "runas.exe" or exe == "sc.exe"
or exe == "schtasks.exe" or exe == "ssh.exe" or exe == "systeminfo.exe"
or exe == "taskkill.exe" or exe == "telnet.exe" or exe == tracert.exe"
or exe == "wscript.exe" or exe == "xcopy.exe")
reg_grouped = group reg by hostname, ppid where(max time between two events is 30 minutes)
output reg_grouped
[process:name = "arp.exe" OR process:name = "at.exe" OR process:name = "attrib.exe" OR process:name = "cscript.exe" OR process:name = "dsquery.exe" OR process:name = "hostname.exe" OR process:name = "ipconfig.exe" OR process:name = "mimikatz.exe" OR process:name = "nbstat.exe" OR process:name = "net.exe" OR process:name = "netsh.exe" OR process:name = "nslookup.exe" OR process:name = "ping.exe" OR process:name = "quser.exe" OR process:name = "qwinsta.exe" OR process:name = "reg.exe" OR process:name = "runas.exe" OR process:name = "sc.exe" OR process:name = "schtasks.exe" OR process:name = "ssh.exe" OR process:name = "systeminfo.exe" OR process:name = "taskkill.exe" OR process:name = "telnet.exe" OR process:name = tracert.exe" OR process:name = "wscript.exe" OR process:name = "xcopy.exe"] REPEATS 2 TIMES WITHIN 1800 SECONDS
(create:[process:name = "arp.exe" OR process:name = "at.exe" OR process:name = "attrib.exe" OR process:name = "cscript.exe" OR process:name = "dsquery.exe" OR process:name = "hostname.exe" OR process:name = "ipconfig.exe" OR process:name = "mimikatz.exe" OR process:name = "nbstat.exe" OR process:name = "net.exe" OR process:name = "netsh.exe" OR process:name = "nslookup.exe" OR process:name = "ping.exe" OR process:name = "quser.exe" OR process:name = "qwinsta.exe" OR process:name = "reg.exe" OR process:name = "runas.exe" OR process:name = "sc.exe" OR process:name = "schtasks.exe" OR process:name = "ssh.exe" OR process:name = "systeminfo.exe" OR process:name = "taskkill.exe" OR process:name = "telnet.exe" OR process:name = tracert.exe" OR process:name = "wscript.exe" OR process:name = "xcopy.exe"] AS PROCESS
FOLLOWEDBY
create:[(process:name = "arp.exe" OR process:name = "at.exe" OR process:name = "attrib.exe" OR process:name = "cscript.exe" OR process:name = "dsquery.exe" OR process:name = "hostname.exe" OR process:name = "ipconfig.exe" OR process:name = "mimikatz.exe" OR process:name = "nbstat.exe" OR process:name = "net.exe" OR process:name = "netsh.exe" OR process:name = "nslookup.exe" OR process:name = "ping.exe" OR process:name = "quser.exe" OR process:name = "qwinsta.exe" OR process:name = "reg.exe" OR process:name = "runas.exe" OR process:name = "sc.exe" OR process:name = "schtasks.exe" OR process:name = "ssh.exe" OR process:name = "systeminfo.exe" OR process:name = "taskkill.exe" OR process:name = "telnet.exe" OR process:name = tracert.exe" OR process:name = "wscript.exe" OR process:name = "xcopy.exe") AND process:parent_ref.pid = PROCESS:parent_ref.pid])
WITHIN 1800 SECONDS
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
- Requires variable substitution so you can indicate that one action compares to another in a certain way
processes = search Process:Create
suspicious_locations = filter process where (
image_path == "*:\RECYCLER\*" or
image_path == "*:\SystemVolumeInformation\*" or
image_path == "%windir%\Tasks\*" or
image_path == "%systemroot%\debug\*"
)
output suspicious_locations
[process:binary_ref.parent_directory_ref.path MATCHES ':\RECYCLER' OR process:binary_ref.parent_directory_ref.path MATCHES ':\SystemVolumeInformation']
create:[process:binary_ref.parent_directory_ref.path MATCHES ':\RECYCLER' OR process:binary_ref.parent_directory_ref.path MATCHES ':\SystemVolumeInformation' OR process:binary_ref.parent_directory_ref.path MATCHES '%windir%\Tasks' OR process:binary_ref.parent_directory_ref.path MATCHES '%systemroot%\debug']
- Somewhat requires actions for the process create
- The pattern contains some endpoint-specific configuration (windir and systemroot). Perhaps those could be defined in the standard? Or do you need some kind of more generic capability to reference environment-specific configuration in the patterns?
- I had some trouble writing the match patterns against directories
flow = search Flow:Message
smb_write = filter flow where (dest_port == "445" and protocol == "smb.write")
smb_write.file_name = smb_write.proto_info.file_name
output smb_write
[network-traffic:dst_port = 445 AND network-traffic:protocols[*] = 'smb2' AND
network-traffic:extensions.smb2-ext.command = 'write']
- We have no insight into the details of the SMB packets in the spec, although a custom smb-ext2 could be created even in STIX 2.0.
- Don't know if we want to include 'smb2' as a potential protocol or not.
process = search Process:Create
at = filter process where (exe == "at.exe")
output at
[process:name = 'at.exe']
create:[process:name = 'at.exe']
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
process = search Process:Create
flow = search Flow:Message
smb_write = filter flow where (dest_port == "445" and protocol == "smb.write")
smb_write.file_name = smb_write.proto_info.file_name
remote_start = join (smb_write, process) where (
smb_write.hostname == process.hostname and
smb_write.file_path == process.image_path
(smb_write.time < process.time)
)
output remote_start
create:[process] AS PROCESS PRECEDEDBY [network-traffic:dst_port = 445 AND network-traffic:protocols[*] = 'microsoft-ds' AND network-traffic:extensions.'smb-extension'.file_name = concat(PROCESS:binary_ref.parent_directory_ref.path, '\', PROCESS:binary_ref.name)]
- Doesn't really require actions. Network flows just...are.
- Requires a SMB extension to network traffic object
- Required some ability to join strings. The Cyber Observable file object doesn't actually have the path in it so you need to combine the path with the name. Path separator may play an issue too, not sure.
- I added PRECEDEDBY to correspond to FOLLOWEDBY to get the variable matching in the right order (left side contains the thing you want to match, right side contains what to match against)
- Kind of implicitly means "on same host as destination". Tricky for a two-host object like network-traffic.
flow_start = search Flow:Start
flow_end = search Flow:End
rdp_start = filter flow_start where (port == "3389")
rdp_end = filter flow_start where (port == "3389")
rdp = group flow_start, flow_end by src_ip, src_port, dest_ip, dest_port
output rdp
[network-traffic.dst_port = 3389]
or
[network-traffic.dst_port = 3389 OR network-traffic.src_port = 3389]
- Network flows in STIX are not split into separate "start" and "end" events.
processes = search Process:Create
rar_argument = filter processes where (command_line == "* a *")
output rar_argument
[process:command_line MATCHES ' a ']
create:[process:command_line MATCHES ' a ']
- I'm not sure if the 'a' needs a '.*' before and after.
process = search Process:Create
schtasks = filter process where (exe == "schtasks.exe")
output schtasks
[process:name = 'schtasks.exe']
create:[process:name = 'schtasks.exe']
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
flow = search Flow:Message
smb_setup = filter flow where (dest_port == 445 and protocol == smb.setup)
smb_setup.user = smb_write.proto_info.user_name
smb_setup.target_host = smb_write.proto_info.hostname
output smb_write
[network-traffic:dst_port = 445 AND network-traffic:protocols[*] = 'microsoft-ds']
[network-traffic:dst_port = 445 AND network-traffic:protocols[*] = 'smb2' AND
network-traffic:extensions.smb2-ext.command = 'session-setup']
- We have no insight into the details of the SMB packets in the spec, although a custom smb-ext2 could be created even in STIX 2.0.
- Don't know if we want to include 'smb2' as a potential protocol or not.
processes = search Process:Create
services = filter processes where (parent_image_path == "C:\Windows\System32\services.exe")
historic_services = filter services (where timestamp < now - 1 day AND timestamp > now - 1 day)
current_services = filter services (where timestamp >= now - 1 day)
new_services = historic_services - current_services
output new_services
create:[process:name NOT IN [create:[process] START now-1].name] STOP now-1
- The CAR pseudocode is nonsensical because it says the
historic_services
must be both>
and<
now - 1 day
. I assume the second requirement (after theAND
forhistoric_services
is a mistake. - Needs nested queries and some way to dereference a field from a list of observations
- Are
START
andSTOP
required to be together?
remote_thread = search Thread:RemoteCreate
remote_thread = filter (start_function == "LoadLibraryA" or start_function == "LoadLibraryW")
remote_thread = filter (src_image_path != "C:\Path\To\TrustedProgram.exe")
output remote_thread
remote_create:[(thread:start_function = 'LoadLibraryA' OR thread:start_function = 'LoadLibraryW') AND thread:src_image_path NOT IN ("C:\Path\To\TrustedProgram.exe")]
- We have no insight into threads at all.
legitimate_installers = ["C:\windows\system32\msiexec.exe", "C:\windows\syswow64\msiexec.exe", ...]
file_change = search File:Create,Modify
process = search Process:Create
service_process = filter processes where (parent_exe == "services.exe")
modified_service = join (search, filter) where (
file_change.time < service_process.time and
file_change.file_path == service_process.image_path
)
modified_service = filter modified_service where (modified_service.file_change.image_path not in legitimate_installers)
output modified_service
flow = search Flow:Message
smb_write = filter flow where (dest_port == "445" and protocol == "smb.write_pipe")
smb_write.pipe_name = smb_write.proto_info.pipe_name
output smb_write
[ network-traffic:dst_port = 445 AND network-traffic:protocols[*] = 'smb2'
AND
network-traffic:extensions.smb2-ext.command = 'write'
AND
network-traffic:extensions.smb2-ext.file_name MATCHES '^\\\\\.\\pipe\\' ]
- We have no insight into the details of the SMB packets in the spec, although a custom smb-ext2 could be created even in STIX 2.0.
- Don't know if we want to include 'smb2' as a potential protocol or not.
- SMB2 has a unified
WRITE
command for named pipes and regular files.
process = search Process:Create
flow = search Flow:Start
service = filter process where (parent_exe == "services.exe")
remote_start = join (flow, service ) where (
flow.hostname == service.hostname and
flow.pid == service.pid and
(flow.time < service.time < flow.time + 1 second)
)
output remote_start
([network-traffic] AS FLOW FOLLOWEDBY [process:parent_ref.name = 'services.exe' AND process:parent_ref.pid = FLOW:dst_process_ref.pid]) WITHIN 1 SECOND
or
([network-traffic:dst_process_ref.name = 'services.exe'] AS FLOW FOLLOWEDBY [process:parent_ref.pid = FLOW:dst_process_ref.parent_ref.pid]) WITHIN 1 SECOND
- The CAR Pseudocode is wrong to --- it should compare the flow
pid
to the parentpid
, not the servicepid
- Requires variable substitution so you can indicate that one action compares to another in a certain way
- Requires the concept of the pattern being evaluated on a single host
- One possibility requires generic object w/o selection based on properties (selection is done via variable substitution)
- Requires a way to link pids to flows
process = search Process:Create
rundll32 = filter process where (exe == "rundll32.exe")
output rundll32
[process:name = 'rundll32.exe']
create:[process:name = 'rundll32.exe']
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
process = search Process:Create
powershell = filter process where (exe == "powershell.exe" AND parent_exe != "explorer.exe" )
output powershell
[process:name = 'powershell.exe' AND process:parent_ref.name != 'explorer.exe']
create:[process:name = 'powershell.exe' AND process:parent_ref.name != 'explorer.exe']
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
flows = search Flow:Start
rpc_mapper = filter flows where (dest_port == 135)
rpc_endpoint = filter flows where (dest_port >= 49152 and src_port >= 49152)
rpc = join rpc_mapper, rpc_endpoint where (
(rpc_mapper.time < rpc_endpoint.time < rpc_mapper.time + 2 seconds) and
(rpc_mapper.src_ip == rpc_endpoint.src_ip and rpc_mapper.dest_ip == rpc_endpoint.dest_ip)
)
output rpc
([network-traffic:dst_port = 135] AS MAPPER FOLLOWEDBY [network-traffic:dst_port >= 49152 AND network-traffic:src_port >= 49152 AND network-traffic:src_ref.value = MAPPER:src_ref.value AND network-traffic:dst_ref.value = MAPPER:dst_ref.value]) WITHIN 2 SECONDS
- Requires variable substitution so you can indicate that one action compares to another in a certain way
process = search Process:Create
cmd = filter process where (exe == "cmd.exe" and parent_exe == "services.exe")
output cmd
[process:name = 'cmd.exe' AND process:parent_ref.name = 'services.exe']
create:[process:name = 'cmd.exe' AND process:parent_ref.name = 'services.exe']
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
process = search Process:Create
services = filter processes where (parent_exe == "services.exe")
unquoted_services = filter services where (command_line != "\"*" and command_line == "* *")
intercepted_service = filter unquoted_service where (image_path != "* *" and exe not in command_line)
output intercepted_service
[process:parent_ref.name = 'services.exe' AND process:command_line NOT MATCHES '^"' AND process:command_line MATCHES ' ' AND process:binary_ref.name NOT MATCHES ' ' process:binary_ref.parent_directory_ref.path NOT MATCHES ' ' AND image_path MATCHES '^[^ ]*$']
create:[process:parent_ref.name = 'services.exe' AND process:command_line NOT MATCHES '^"' AND process:command_line MATCHES ' ' AND process:binary_ref.name NOT MATCHES ' ' process:binary_ref.parent_directory_ref.path NOT MATCHES ' ' AND process:binary_ref.name NOT IN process:command_line]
- Requires that Object Paths must be allowed to appear on the right side of a Comparison Operator. Currently the spec says that the right side must be a constant.
- STIX 2.0 pattern can capture everything except the
exe not in command_line
- Add an
path
or something to the file type, it's ridiculously complicated to write comparisons to a file path. - This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
processes = search Process:Create
cmd = filter processes where (exe == "cmd.exe")
cmd = from cmd select parent_exe
historic_cmd = filter cmd (where timestamp < now - 1 day AND timestamp > now - 1 day)
current_cmd = filter cmd (where timestamp >= now - 1 day)
new_cmd = historic_cmd - current_cmd
output new_cmd
create:[process:parent_ref:name = 'cmd.exe' AND process:name NOT IN [create:[process:parent_ref:name = 'cmd.exe'] START now-1].name] STOP now-1
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
process = search Process:Create
debuggers = filter process where (command_line match "$.* .*(sethc|utilman|osk|narrator|magnify)\.exe")
output debuggers
[process:command_line MATCH '^.* .*(sethc|utilman|osk|narrator|magnify)\.exe']
create:[process:command_line MATCH '^.* .*(sethc|utilman|osk|narrator|magnify)\.exe']
- CAR Pseudocode has an error: the $ should be a ^
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
process = search Process:Create
wsmprovhost = filter process where (exe == "wsmprovhost.exe" and parent_exe == "svchost.exe")
[process:name = 'wsmprovhost.exe' AND process:parent_ref.name = 'svchost.exe']
create:[process:name = 'wsmprovhost.exe' AND process:parent_ref.name = 'svchost.exe']
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
flows = search Flow:Message
winreg = filter flows where (dest_port == 445 and proto_info.pipe == "WINREG")
winreg_modify = filter flows where (proto_info.function == "Create*" or proto_info.function == "SetValue*")
output winreg_modify
[ network-traffic:dst_port = 445 AND network-traffic:protocols[*] = 'smb2'
AND
network-traffic:extensions.smb2-ext.command = 'write'
AND
network-traffic:extensions.smb2-ext.file_name MATCHES '^\\\\\.\\pipe\\winreg' ]
- CAR Pseudocode is kind of weird because it is specifying API-level information with a flow, which doesn't make sense to me, unless you have a special parser for the data going to the winreg pipe
- I just noticed that the way we do smb2-ext MAY BE problematic since it requires each message to have be it's own network-traffic object
flow = search Flow:Start
winrm = filter flow where (dest_port == 5985)
winrm_s = filter flow where (dest_port == 5986)
output winrm, winrm_s
[network-traffic:dst_port IN (5985, 5986)]
flows = search Flow:Message
wmi_flow = filter flows where (dest_port == 135 and proto_info.rpc_interface == "IRemUnknown2")
output wmi_flow
[network-traffic:dst_port = 135 AND network-traffic:protocols[*] = 'rpc' AND network-traffic:extensions.rpc-ext.interface = 'IRemUnknown2']
- Don't know what the RPC traffic looks like, so I'm just making some guesses about what the pattern should look like.
processes = search Process:Create
winlogon_cmd = filter processes where (parent_exe == "winlogon.exe" and exe == "cmd.exe")
output winlogon_cmd
[process:parent_ref.name = 'winlogon.exe' and process:name = 'cmd.exe']
create:[process:parent_ref.name = 'winlogon.exe' and process:name = 'cmd.exe']
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
processes = search Process:Create
wmi_children = filter processes where (parent_exe == "wmiprvse.exe")
flows = search Flow:Message
wmi_flow = filter flows where (src_port >= 49152 and dest_port >= 49152 and proto_info.rpc_interface == "IRemUnknown2")
remote_wmi_process = join wmi_children, wmi_flow where (
wmi_flow.time < wmi_children.time < wmi_flow.time + 1sec and
wmi_flow.hostname == wmi_children.hostname
)
output remote_wmi_process
[network-traffic:src_port >= 49152 AND network-traffic:dst_port >= 49152 AND network-traffic:protocols[*] = 'rpc' AND network-traffic:extensions.rpc-ext.interface = 'IRemUnknown2' AND network-traffic:dst_process_ref.pid IN [process:parent_ref.name = 'wmiprvse.exe']:pid]
- Do we need some sort of join feature?
- Need the ability to perform subqueries
- Need some ability to select a field from the result of a subquery
flows = search Flow:Message
at_proto = filter flows where (dest_port == 445 and proto_info.pipe == "ATSVC")
at_create = filter flows where (proto_info.function == "JobAdd")
output at_create
[network-traffic:dst_port = 445 AND network-traffic:protocols[*] = 'smb2'
AND
network-traffic:extensions.smb2-ext.command = 'write'
AND
network-traffic:extensions.smb2-ext.file_name MATCHES '^\\\\\.\\pipe\\atsvc']
or
[network-traffic:protocols[*] = 'atsvc' AND network-traffic:atsvc-ext.function = 'JobAdd']
- Not sure if we want to have an atsvc-ext
flows = search Flow:Message
schtasks_rpc = filter flows where (
src_port >= 49152 and dest_port >= 49152 and
proto_info.rpc_interface == "ITaskSchedulerService"
)
output schtasks_rpc
[network-traffic:src_port >= 49152 AND network-traffic:dst_port >= 49152 AND network-traffic:protocols[*] = 'rpc' AND network-traffic:extensions.rpc-ext.interface = 'ITaskSchedulerService']
- Don't know what the RPC traffic looks like, so I'm just making some guesses about what the pattern should look like.
input target_host
input event_time
all_boots = search SystemLogs:BootUp where (hostname == target_host and time < event_time)
boot_time = max(all_boots.time)
user_logins = search UserSession:Login
host_logins = filter user_logins where (hostname == target_host and boot_time < time < event_time)
compromised_accounts = unique(user_logins.user)
output users
- Do we need aggregation operations like
max
?
process = search Process:Create
info_command = filter process where (
exe == "hostname.exe" or
exe == "ipconfig.exe" or
exe == "net.exe" or
exe == "quser.exe" or
exe == "qwinsta.exe" or
exe == "sc" and (command_line match " query" or command_line match " qc")) or
exe == "systeminfo.exe" or
exe == "tasklist.exe" or
exe == "whoami.exe"
)
output info_command
[process:name = 'hostname.exe' OR process:name = 'ipconfig.exe' OR process:name = 'net.exe' OR process:name = 'quser.exe' OR process:name = 'qwinsta.exe' ORprocess:name = 'sc' AND (process:command_line MATCH ' query' OR process:command_line match ' qc')) ORprocess:name = 'systeminfo.exe' OR process:name = 'tasklist.exe' OR process:name = 'whoami.exe']
create:[process:name = 'hostname.exe' OR process:name = 'ipconfig.exe' OR process:name = 'net.exe' OR process:name = 'quser.exe' OR process:name = 'qwinsta.exe' ORprocess:name = 'sc' AND (process:command_line MATCH ' query' OR process:command_line match ' qc')) ORprocess:name = 'systeminfo.exe' OR process:name = 'tasklist.exe' OR process:name = 'whoami.exe']
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
processes = search Process:Create
wmic = filter processes where (exe == "wmic.exe" and command_line == "* process call create *" and command_line == "* /node:*")
output wmic
[process:name = 'wmic.exe' AND process:command_line MATCHES ' process call create ' AND process:command_line MATCHES ' \/node:'
create:[process:name = 'wmic.exe' AND process:command_line MATCHES ' process call create ' AND process:command_line MATCHES ' \/node:'
- This searches for "process", not "process is created". In this case that's probably fine, but other actions wouldn't work
- Would probably require the concept of process:create
- I wasn't sure whether process "name" was the name of the executable or not. If not it could be a reference to a file object
([log_name] == "System" and [event_code] in [1100, 1102]) or
([log_name] == "Security" and [event_code] == 104)
[(event:log_name = 'System' AND event:event_code IN (1100, 1102)) OR (event:log_name = 'Security' AND event:event_code = 104)]
- Requires new
event
object type
log_name == "System" AND
event_code == "7036"
param1 in ["Windows Defender", "Windows Firewall"] AND
param2 == "stopped"
[event:log_name = 'System' AND event:event_code = 7036 AND event:param1 IN ('Windows Defender', 'Windows Firewall') AND event:param2 = 'stopped']
- Requires new
event
object type
EventCode == 4624 and [target_user_name] != "ANONYMOUS LOGON" and
[authentication_package_name] == "NTLM"
[event:event_code = 4624 AND event:extensions.logon_success.target_user_name != 'ANONYMOUS LOGON' AND event:extensions.logon_success.authentication_package_name = 'NTLM']
- Requires new
event
object type andlogon_success
extension.
[EventCode] == 4624 and
[AuthenticationPackageName] == 'Negotiate' and
[Severity] == "Information" and
[LogonType] == 10
[event:event_code = 4624 AND event:extensions.logon_success.authentication_package_name = 'Negotiate' AND event:level = 'Information' AND event:extensions.logon_success.logon_type = 10]
- Requires new
event
object type andlogon_success
extension.