Skip to main content

Hey,

 

I'm writing a detection rule which I'm struggling with the syntax and not sure about the variable section i put in.

 

 

intro:

The rule is suppose to combine 2 events:

Event 1: is to detect when a security group was open to any-any rule (0.0.0.0) - which we have a working rule on that already.

Event 2: detect when this security group is closed to 0.0.0.0 comunication - we have a lambda function that closes this automatically.

So basically, we want to monitor if the lambda is not working - then pop up a detection alert.

but when working on the the rule, I come acrros this error which is related to the placeholder:

parsing: error with token: ":"
invalid operator in events predicate
line: 15 

This is the rule:

rule ttp_aws_security_group_open_to_world { meta: rule_name = "AWS Security Group Open to World" description = "Detects when an AWS Security Group is open to the world (0.0.0.0/0 or ::/0) and then revoked within 5 minutes." severity = "High" tactic = "TA0005" // Defense Evasion technique = "T1562.001" // Impair Process Control: Network Firewall platform = "AWS" references = "https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AuthorizeSecurityGroupIngress.html, https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RevokeSecurityGroupIngress.html" tags = "cloud, aws, security_group, misconfiguration, ephemeral, network_exposure, cloudtrail" events: // Event 1: Detect when a security group ingress rule is opened to the world // This is the first event variable $open_event: $open_event.metadata.vendor_name = "AMAZON" $open_event.metadata.product_name = "AWS CloudTrail" $open_event.metadata.product_event_type = "AuthorizeSecurityGroupIngress" // Corrected: Check for 'any-any' IPv4 or IPv6 CIDR blocks using standard UDM field ( $open_event.network.vpc.firewall.rule.source_ip_addresses = "0.0.0.0/0" or $open_event.network.vpc.firewall.rule.source_ip_addresses = "::/0" ) // Note: security_result.action is not typically populated for API calls like AuthorizeSecurityGroupIngress // and is removed to prevent false negatives. // Capture key fields for precise correlation and outcome: $open_event.target.resource.resource_id // The Security Group ID (e.g., sg-0abcdef1234567890) $open_event.network.vpc.firewall.rule.ip_protocol // The protocol (e.g., "tcp", "udp", "-1") $open_event.network.vpc.firewall.rule.target_port // The target port or range $open_event.network.vpc.firewall.rule.source_ip_addresses // The specific CIDR (0.0.0.0/0 or ::/0) $open_event.additional.fields["recipientAccountId"] // Account ID // Event 2: Detect when the same security group ingress rule is revoked // This is the second event variable $close_event: $close_event.metadata.vendor_name = "AMAZON" $close_event.metadata.product_name = "AWS CloudTrail" $close_event.metadata.product_event_type = "RevokeSecurityGroupIngress" // Corrected: Check for the revocation of 'any-any' IPv4 or IPv6 CIDR blocks ( $close_event.network.vpc.firewall.rule.source_ip_addresses = "0.0.0.0/0" or $close_event.network.vpc.firewall.rule.source_ip_addresses = "::/0" ) // Note: security_result.action is not typically populated for API calls like RevokeSecurityGroupIngress // and is removed. // Capture the same correlation fields as the $open_event: $close_event.target.resource.resource_id $close_event.network.vpc.firewall.rule.ip_protocol $close_event.network.vpc.firewall.rule.target_port $close_event.network.vpc.firewall.rule.source_ip_addresses $close_event.additional.fields["recipientAccountId"] condition: // Both events must occur for the rule to trigger. $open_event and $close_event and // Crucial correlation: Ensure both events refer to the *exact same* ingress rule. // We correlate on the Security Group ID, the protocol, the target port, and the specific CIDR. $open_event.target.resource.resource_id = $close_event.target.resource.resource_id and $open_event.network.vpc.firewall.rule.ip_protocol = $close_event.network.vpc.firewall.rule.ip_protocol and $open_event.network.vpc.firewall.rule.target_port = $close_event.network.vpc.firewall.rule.target_port and // Ensure the same "any-any" CIDR was opened and then revoked (handles both IPv4 and IPv6) ( ($open_event.network.vpc.firewall.rule.source_ip_addresses = "0.0.0.0/0" and $close_event.network.vpc.firewall.rule.source_ip_addresses = "0.0.0.0/0") or ($open_event.network.vpc.firewall.rule.source_ip_addresses = "::/0" and $close_event.network.vpc.firewall.rule.source_ip_addresses = "::/0") ) and // Time window: The $close_event must occur within 5 minutes (300 seconds) of the $open_event. // The `by` clause ensures that the correlation is performed per unique combination of the specified fields. $open_event and $close_event by $open_event.target.resource.resource_id, $open_event.network.vpc.firewall.rule.ip_protocol, $open_event.network.vpc.firewall.rule.target_port, $open_event.network.vpc.firewall.rule.source_ip_addresses match_within 5m on $open_event.metadata.event_timestamp.seconds outcome: $risk_score = max(35) $vendor_name = "AMAZON" $product_name = "AWS CloudTrail" // Count distinct IDs from both open and close events $event_count = count_distinct($open_event.metadata.id, $close_event.metadata.id) // Collect distinct user agents from both events $user_agents = array_distinct($open_event.network.http.user_agent, $close_event.network.http.user_agent) // Collect distinct network organization names from both events $network_org_names = array_distinct($open_event.principal.ip_geo_artifact.network.organization_name, $close_event.principal.ip_geo_artifact.network.organization_name) // Collect distinct principal IPs from both events $principal_ips = array_distinct($open_event.principal.ip, $close_event.principal.ip) // Collect distinct recipient account IDs from both events $recipient_account_ids = array_distinct($open_event.additional.fields["recipientAccountId"], $close_event.additional.fields["recipientAccountId"]) // Collect distinct principal users from both events $principal_users = array_distinct($open_event.principal.user.userid, $close_event.principal.user.userid) // Collect distinct cloud regions from both events $cloud_regions = array_distinct($open_event.principal.location.name, $close_event.principal.location.name) // Collect distinct target resource IDs (Security Group IDs) from both events $target_resource_ids = array_distinct($open_event.target.resource.resource_id, $close_event.target.resource.resource_id) // Specific details about the opened rule: $opened_ports = array_distinct($open_event.network.vpc.firewall.rule.target_port) $opened_protocols = array_distinct($open_event.network.vpc.firewall.rule.ip_protocol) $opened_cidrs = array_distinct($open_event.network.vpc.firewall.rule.source_ip_addresses) }
 

 

Would appreciate  any advice .

Thanks

The error you are seeing is a syntax error caused by using the colon (:) symbol on line #23 and #54. You’ll also need to specify a variable name for each of the capture fields you put on lines 40-48 and lines 71-75. For each of the variables you define, you’ll need to fix those associated references in the condition section.

Hope this helps!


Reply