Skip to main content
Question

How to seperate 2 IPS in a YARA-L rule

  • July 9, 2026
  • 3 replies
  • 25 views

Khushboo14
Forum|alt.badge.img+2

I want to create a rule where the prinicpal ip should not be a private ip. However, we see that the principal ip is containing 2 comma separated values (ipv4, ipv6). I want to split these values so that we can use a data table to store the private ip range range and compare one of the IP from the data table. How can i do that

3 replies

cmorris
Staff
Forum|alt.badge.img+13
  • Staff
  • July 9, 2026

You could try the following, which should return the first ipv4 address found in principal.ip.

$ipv4 = re.capture($e.principal.ip, `([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})`)

 

In a rule:

rule non_private_ip {
  meta:
    author = "SecOps"
    severity = "Medium"

  events:
    $e.metadata.event_type = "NETWORK_CONNECTION"
    
    $ipv4 = re.capture($e.principal.ip, `([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})`)

    $ipv4 != ""

    not $ipv4 in %data_table.ips

  condition:
    $e
}

 


Khushboo14
Forum|alt.badge.img+2
  • Author
  • New Member
  • July 9, 2026

i have tried this but it is giving an error “validating intermediate representation: placeholder variable ipv4 is not assigned to an event field line: 20 column: 6-10”

 

 

  events:

   

   (($event.metadata.log_type = "CISCO_SWITCH"  or $event.metadata.log_type = "CISCO_ROUTER" or $event.metadata.log_type = "F5_BIGIP_LTM" or $event.metadata.log_type = "PAN_PANORAMA")

    and $event.metadata.event_type = "USER_LOGIN"

    and $event.security_result.action = "ALLOW" )

 

    $ipv4 = re.capture($event.principal.ip, `([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})`)

 

    and not $ipv4 in cidr %Private_IPs.private_ips

    //and $event.principal.ip != ""

 

    //AND not ($event.principal.user.userid = /-a/ or $event.target.user.userid = /-a/)

 

    or

 

    ($event.metadata.log_type = "PAN_PANORAMA" and

    not $event.principal.ip in %VA_Scanner_IPs.vulnerability_scanners_ip  and

    $event.metadata.product_event_type = "SYSTEM" and

    $event.security_result.detection_fields["subtype"] = "auth" and

    $event.additional.fields["eventid"] = "auth-success" )

    not $ipv4 in CIDR %Private_IPs.private_ips

   

    $user1 = $event.principal.user.userid

 

match:

    $user1 over 24h

 

  outcome:

   

    $user = count_distinct($event.target.user.userid)

    $logtype = count_distinct($event.metadata.log_type)

    $ipaddress = count_distinct($ipv4)


 

  condition:

    $event

}

 


hliu
Forum|alt.badge.img+5
  • Bronze 2
  • July 9, 2026

not sure which is your line: 20, making it difficult to troubleshoot from the community perspective but here’s few tips in case it helps


1) beware the OR / AND precedence. You might want to use parentheses to be sure on getting the desired datasets:
(dataset1 AND ...) OR (dataset2 AND ...)


2) net.ip_in_range_cidr()  could also help to check if an ip is private or public:

to filter for private ip only:

(net.ip_in_range_cidr($ip, "10.0.0.0/8") OR net.ip_in_range_cidr($ip, "192.168.0.0/16") OR net.ip_in_range_cidr($ip, "172.16.0.0/12") OR net.ip_in_range_cidr($ip, "127.0.0.0/8") OR net.ip_in_range_cidr($ip, "fc00::/7") OR net.ip_in_range_cidr($ip, "::1"))


to filter for public ip only:

NOT (net.ip_in_range_cidr($ip, "10.0.0.0/8") OR net.ip_in_range_cidr($ip, "192.168.0.0/16") OR net.ip_in_range_cidr($ip, "172.16.0.0/12") OR net.ip_in_range_cidr($ip, "127.0.0.0/8") OR net.ip_in_range_cidr($ip, "fc00::/7") OR net.ip_in_range_cidr($ip, "::1"))



3) principal.ip is a repeated field, modified expressions (any, all) and $placeholders play an important role on them because of the implicit UNNEST operation on the array, to flatten or clone the events on the fly.