# # File: main.zeek # Created: 20180701 # Updated: 20201009 # # Copyright 2018 The MITRE Corporation. All Rights Reserved. # Approved for public release. Distribution unlimited. Case number 18-3868. # @if ((Version::info$major == 2) && (Version::info$minor <= 5)) # Use this syntax for Bro v2.5.x and below @load policy/protocols/smb @else # Use this syntax for Bro v2.6.x and above @load base/protocols/smb @endif @load base/protocols/dce-rpc @load base/frameworks/files @load base/frameworks/notice @load base/frameworks/sumstats module BZAR; export { # NOTICE - Raise Notices for these ATT&CK Tactics & Categories redef enum Notice::Type += { ATTACK::Credential_Access, ATTACK::Defense_Evasion, ATTACK::Discovery, ATTACK::Execution, ATTACK::Impact, ATTACK::Lateral_Movement, ATTACK::Lateral_Movement_and_Execution, ATTACK::Lateral_Movement_Extracted_File, ATTACK::Lateral_Movement_Multiple_Attempts, ATTACK::Persistence, }; # Full descriptive name of each ATT&CK Technique # Used in BZAR Reporting const attack_info : table[string] of string = { ["t1003.006"] = "T1003.006 OS Credential Dumping: DCSync", ["t1547.004"] = "T1547.004 Boot or Logon Autostart Execution: Winlogon Helper DLL", ["t1547.010"] = "T1547.010 Boot or Logon Autostart Execution: Port Monitors", ["t1016"] = "T1016 System Network Configuration Discovery", ["t1018"] = "T1018 Remote System Discovery", ["t1033"] = "T1033 System Owner/User Discovery", ["t1569.002"] = "T1569.002 System Services: Service Execution", ["t1047"] = "T1047 WMI", ["t1049"] = "T1049 System Network Connections Discovery", ["t1053.002"] = "T1053.002 Scheduled Task/Job: At", ["t1053.005"] = "T1053.005 Scheduled Task/Job: Scheduled Task", ["t1069"] = "T1069 Permission Groups Discovery", ["t1070.001"] = "T1070.001 Indicator Removal on Host: Clear Windows Event Logs", ["t1021.002"] = "T1021.002 Remote Services: SMB/Windows Admin Shares", ["t1082"] = "T1082 System Information Discovery", ["t1083"] = "T1083 File and Directory Discovery", ["t1087"] = "T1087 Account Discovery", ["t1570"] = "T1570 Lateral Tool Transfer", ["t1124"] = "T1124 System Time Discovery", ["t1135"] = "T1135 Network Share Discovery", ["t1529"] = "T1529 System Shutdown/Reboot", } &redef; type EndpointWhitelist : record { # Specify IP Addresses to ignore orig_addrs : set[addr] &optional; resp_addrs : set[addr] &optional; # Specify IP Subnets to ignore orig_subnets : set[subnet] &optional; resp_subnets : set[subnet] &optional; # Specify Host Names to ignore orig_names : set[string] &optional; resp_names : set[string] &optional; } &redef; } #end export # # Helper Functions # function whitelist_test( orig_h : addr, resp_h : addr, w : BZAR::EndpointWhitelist ) : bool { local match : bool = F; # # Check if Endpoint IP Addrs are Associated with Whitelist # if ( w?$orig_addrs && (orig_h in w$orig_addrs) ) { match = T; } else if ( w?$resp_addrs && (resp_h in w$resp_addrs) ) { match = T; } else if ( w?$orig_subnets && (orig_h in w$orig_subnets) ) { match = T; } else if ( w?$resp_subnets && (resp_h in w$resp_subnets) ) { match = T; } else if ( w?$orig_names ) { @if ( Version::number >= 50000 ) when [w, orig_h, match] ( (local n1 = lookup_addr(orig_h)) && (n1 in w$orig_names) ) { @else when ( (local n1 = lookup_addr(orig_h)) && (n1 in w$orig_names) ) { @endif match = T; } timeout BZAR::whitelist_dns_timeout { match = F; } } else if ( w?$resp_names ) { @if ( Version::number >= 50000 ) when [w, resp_h, match] ( (local n2 = lookup_addr(resp_h)) && (n2 in w$resp_names) ) { @else when ( (local n2 = lookup_addr(resp_h)) && (n2 in w$resp_names) ) { @endif match = T; } timeout BZAR::whitelist_dns_timeout { match = F; } } return match; } function sort_func( a : double, b : double ) : int { if ( a < b) return -1; else return 1; } # # BZAR Initialization # @if ( Version::info$major >= 3 ) # Use this syntax for Zeek v3.x.x and above event zeek_init() { @else # Use this syntax for Bro v2.x.x and below event bro_init() { @endif # 1- SumStats Analytics for ATT&CK Lateral Movement and Execution # # Description: # Use SumStats to raise a Bro/Zeek Notice event if an SMB Lateral Movement # indicator (e.g., SMB File Write to a Windows Admin File Share: ADMIN$ or # C$ only) is observed together with a DCE-RPC Execution indicator against # the same (targeted) host, within a specified period of time. # # Relevant ATT&CK Technique(s): # T1021.002 Remote Services: SMB/Windows Admin Shares (file shares only, not # named pipes) && T1570 Lateral Tool Transfer && (T1569.002 System Services: # Service Execution|| T1047 WMI || T1053.002 Scheduled Task/Job: At || # T1053.005 Scheduled Task/Job: Scheduled Task) # # Relevant Indicator(s) Detected by Bro/Zeek: # (a) smb1_write_andx_response::c$smb_state$path contains ADMIN$ or C$ # (b) smb2_write_request::c$smb_state$path contains ADMIN$ or C$** # (c) dce_rpc_response::c$dce_rpc$endpoint + c$dce_rpc$operation contains # any of the following: # BZAR::t1569_002_rpc_strings # BZAR::t1047_rpc_strings # BZAR::t1053_002_rpc_strings # BZAR::t1053_005_rpc_strings # # **NOTE: Preference would be to detect 'smb2_write_response' # event (instead of 'smb2_write_request'), because it # would confirm the file was actually written to the # remote destination. Unfortuantely, Bro/Zeek does # not have an event for that SMB message-type yet. # # Globals (defined in bzar_config_options.zeek): # bzar1_epoch # bzar1_limit local bzar1 = SumStats::Reducer( $stream="attack_lm_ex", $apply=set(SumStats::SUM, SumStats::MAX, SumStats::MIN) ); SumStats::create([ $name = "attack_lm_ex_notice", $reducers = set(bzar1), $epoch = bzar1_epoch, $threshold = bzar1_limit, $threshold_val (key:SumStats::Key, result:SumStats::Result) = { return result["attack_lm_ex"]$sum; }, $threshold_crossed(key:SumStats::Key, result:SumStats::Result) = { local r = result["attack_lm_ex"]; # Ensure at least one RPC_EXEC was observed and # at least one SMB_WRITE was observed if ( r$max == 1000 && r$min == 1 ) { local s = fmt("Detected activity against host %s, total score %.0f within timeframe %s", key$host, r$sum, bzar1_epoch); # Raise Notice NOTICE([$note=ATTACK::Lateral_Movement_and_Execution, $msg=s] ); } } ]); # 2- SumStats Analytics for ATTACK Lateral Movement (Multiple Attempts) # # Description: # Use SumStats to raise a Bro/Zeek Notice event if multiple SMB Lateral # Movement indicators (e.g., multiple attempts to connect to a Windows Admin # File Share: ADMIN$ or C$ only) are observed originating from the same host, # regardless of write-attempts and regardless of whether or not any connection # is successful --just connection attempts-- within a specified period of time. # # Relevant ATT&CK Technique(s): # T1021.002 SMB/Windows Admin Shares (file shares only, not named pipes) # # Relevant Indicator(s) Detected by Bro/Zeek: # (a) smb1_tree_connect_andx_request::c$smb_state$path contains ADMIN$ or C$ # (b) smb2_tree_connect_request::c$smb_state$path contains ADMIN$ or C$ # # Globals (defined in bzar_config_options.zeek): # bzar2_epoch # bzar2_limit local bzar2 = SumStats::Reducer( $stream="attack_lm_multiple_t1021_002", $apply=set(SumStats::SUM) ); SumStats::create([ $name = "attack_t1021_002_notice", $reducers = set(bzar2), $epoch = bzar2_epoch, $threshold_series = sort(bzar2_limit, sort_func), $threshold_val (key:SumStats::Key, result:SumStats::Result) = { return result["attack_lm_multiple_t1021_002"]$sum; }, $threshold_crossed(key:SumStats::Key, result:SumStats::Result) = { local s = fmt("Detected T1021.002 Admin File Share activity from host %s, total attempts %.0f within timeframe %s", key$host, result["attack_lm_multiple_t1021_002"]$sum, bzar2_epoch); # Raise Notice NOTICE([$note=ATTACK::Lateral_Movement_Multiple_Attempts, $msg=s] ); } ]); # 3- SumStats Analytics for ATTACK Discovery # # Description: # Use SumStats to raise a Bro/Zeek Notice event if multiple instances of # DCE-RPC Discovery indicators are observed originating from the same host, # within a specified period of time. # # Relevant ATT&CK Technique(s): # T1016 System Network Configuration Discovery # T1018 Remote System Discovery # T1033 System Owner/User Discovery # T1069 Permission Groups Discovery # T1082 System Information Discovery # T1083 File & Directory Discovery # T1087 Account Discovery # T1124 System Time Discovery # T1135 Network Share Discovery # # Relevant Indicator(s) Detected by Bro/Zeek: # (a) dce_rpc_response::c$dce_rpc$endpoint + c$dce_rpc$operation contains # any of the following: # BZAR::t1016_rpc_strings # BZAR::t1018_rpc_strings # BZAR::t1033_rpc_strings # BZAR::t1069_rpc_strings # BZAR::t1082_rpc_strings # BZAR::t1083_rpc_strings # BZAR::t1087_rpc_strings # BZAR::t1124_rpc_strings # BZAR::t1135_rpc_strings # # Globals (defined in bzar_config_options.zeek): # bzar3_epoch # bzar3_limit local bzar3 = SumStats::Reducer( $stream="attack_discovery", $apply=set(SumStats::SUM) ); SumStats::create([ $name = "attack_discovery_notice", $reducers = set(bzar3), $epoch = bzar3_epoch, $threshold_series = sort(bzar3_limit, sort_func), $threshold_val (key:SumStats::Key, result:SumStats::Result) = { return result["attack_discovery"]$sum; }, $threshold_crossed(key:SumStats::Key, result:SumStats::Result) = { local s = fmt("Detected activity from host %s, total attempts %.0f within timeframe %s", key$host, result["attack_discovery"]$sum, bzar3_epoch); # Raise Notice NOTICE([$note=ATTACK::Discovery, $msg=s] ); } ]); } #end main.zeek