[ 
https://issues.apache.org/jira/browse/METRON-675?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15840531#comment-15840531
 ] 

ASF GitHub Bot commented on METRON-675:
---------------------------------------

Github user cestella commented on the issue:

    https://github.com/apache/incubator-metron/pull/426
  
    Testing Instructions beyond the normal smoke test (i.e. letting data
    flow through to the indices and checking them).
    
    ## Preliminaries
    
    It is helpful to install the elasticsearch head plugin:
    * `/usr/share/elasticsearch/bin/plugin install mobz/elasticsearch-head`
    
    Also, set an environment variable to indicate `METRON_HOME`:
    * `export METRON_HOME=/usr/metron/0.3.0` 
    
    ## Adjust configs to Bro
    We will adjust the bro topology to have a couple of threat triage rules:
    * Edit `$METRON_HOME/config/zookeeper/enrichment/bro.json` as follows:
    ```
    {
      "enrichment" : {
        "fieldMap": {
          "geo": ["ip_dst_addr", "ip_src_addr"],
          "host": ["host"]
        }
      },
      "threatIntel": {
        "fieldMap": {
          "hbaseThreatIntel": ["ip_src_addr", "ip_dst_addr"],
          "stellar" : {
              "config" : {
                 "is_alert" : "ip_dst_port == 80 or ip_dst_port == 5353"
                         }
                      }
        },
        "fieldToTypeMap": {
          "ip_src_addr" : ["malicious_ip"],
          "ip_dst_addr" : ["malicious_ip"]
        },
        "triageConfig" : {
           "riskLevelRules" : [
                  {
                     "name" : "web",
                     "comment" : "Bump risk if web connection",
                     "rule" : "ip_dst_port == 80",
                     "score" : 10
                  },
                  {
                     "name" : "dns",
                     "comment" : "Bump risk if dns connection",
                     "rule" : "ip_dst_port == 5353",
                     "score" : 20
                  }
                              ],
           "aggregator" : "MAX"
                         }
      }
    }
    ```
    
    This should create 2 rules:
    * set the triage level to 20 if the destination port is a DNS port
    * set the triage level to 10 if the destination port is a web port
    
    Ensure via the elasticsearch head plugin that the following is true:
    * All bro messages with `is_alert == true` and `ip_dst_port == 5353` have a 
`threat:triage:level` of 20
    * All bro messages with `is_alert == true` and `threat:triage:level == 20` 
have a `ip_dst_port` of 20
    * All bro messages with `is_alert == true` and `ip_dst_port == 80` have a 
`threat:triage:level` of 10
    * All bro messages with `is_alert == true` and `threat:triage:level == 10` 
have a `ip_dst_port` of 10
    
    ### Test Case: Stellar Management Functions
    * Upload the management functions via `scp 
metron-platform/metron-management/target/metron-management-0.3.0.jar 
root@node1:/usr/metron/0.3.0/lib`
    * Create a file with the following contents named `~/script.stellar`
    ```
    # First we get the squid enrichment config from zookeeper.
    # If it is not there, which it is not by default, a suitable default
    # config will be specified.
    squid_enrichment_config := CONFIG_GET('ENRICHMENT', 'squid')
    # We should not have any threat triage rules
    THREAT_TRIAGE_PRINT(squid_enrichment_config)
    # Just for illustration, we can create a threat alert if the country of the 
domain registered
    # is non-US, then we can make an alert.  To do that, we need to create an 
is_alert field on the message.
    #
    # I know that maps get folded into the message, so that whois_info 
enrichment is going to create a few fields:
    #  * domain mapped to whois_info.domain
    #  * registrar mapped to whois_info.registrar
    #  * home_country mapped to whois_info.home_country
    #  * owner mapped to whois_info.owner
    whois_info.home_country := 'US'
    # Now with this, we can create a rule or two to triage these alerts.
    # This means associating a rule as described by a stellar expression that 
returns true or false with a score
    # Also associated with this ruleset is an aggregation function, the default 
of which is MAX.
    # Now we can make a couple rules:
    #  * If the message is an alert and from a non-us whois source, we can set 
the level to 10
    #  * If the message is an alert and non-local, we can set the level to 20
    #  * If the message is an alert and both non-local and non-us, then we can 
set the level to 50
    # If multiple rules hit, then we should take the max (default behavior)
    non_us := whois_info.home_country != 'US'
    is_local := IN_SUBNET( if IS_IP(ip_src_addr) then ip_src_addr else NULL, 
'192.168.0.0/21')
    is_both := whois_info.home_country != 'US' && IN_SUBNET( if 
IS_IP(ip_src_addr) then ip_src_addr else NULL, '192.168.0.0/21')
    rules := [ { 'name' : 'is non-us', 'rule' : SHELL_GET_EXPRESSION('non_us'), 
'score' : 10 } , { 'name' : 'is local', 'rule' : 
SHELL_GET_EXPRESSION('is_local'), 'score' : 20 } , { 'name' : 'both non-us and 
local', 'comment' : 'union of both rules.',  'rule' : 
SHELL_GET_EXPRESSION('is_both'), 'score' : 50 } ]
    # Now that we have our rules staged, we can add them to our config.
    squid_enrichment_config_new := THREAT_TRIAGE_ADD( 
squid_enrichment_config_new, rules )
    # Pretty Print the rules
    THREAT_TRIAGE_PRINT(squid_enrichment_config_new)
    # Now just print the raw config to make sure it jives
    squid_enrichment_config_new
    # Now that we have admired it, we can remove the rules
    squid_enrichment_config_new := THREAT_TRIAGE_REMOVE( 
squid_enrichment_config_new, [ SHELL_GET_EXPRESSION('non_us') , 
SHELL_GET_EXPRESSION('is_local') , SHELL_GET_EXPRESSION('is_both') ] )
    THREAT_TRIAGE_PRINT(squid_enrichment_config_new)
    ```
    * Execute the script via `cat script.stellar | 
/usr/metron/0.3.0/bin/stellar -z node1 -na` You should see the following output:
    ```
    Stellar, Go!
    Please note that functions are loading lazily in the background and will be 
unavailable until loaded fully.
    {es.clustername=metron, es.ip=node1, es.port=9300, 
es.date.format=yyyy.MM.dd.HH}
    [Stellar]>>> # First we get the squid enrichment config from zookeeper.
    [Stellar]>>> # If it is not there, which it is not by default, a suitable 
default
    [Stellar]>>> # config will be specified.
    [Stellar]>>> squid_enrichment_config := CONFIG_GET('ENRICHMENT', 'squid')
    Functions loaded, you may refer to functions now...
    [Stellar]>>> # We should not have any threat triage rules
    [Stellar]>>> THREAT_TRIAGE_PRINT(squid_enrichment_config)
    ╔══════╤═════════╤═════════════╤═══════╗
    ║ Name │ Comment │ Triage Rule │ Score ║
    ╠══════╧═════════╧═════════════╧═══════╣
    ║ (empty)                              ║
    ╚══════════════════════════════════════╝
    
    [Stellar]>>> # Just for illustration, we can create a threat alert if the 
country of the domain registered
    [Stellar]>>> # is non-US, then we can make an alert.  To do that, we need 
to create an is_alert field on the message.
    [Stellar]>>> #
    [Stellar]>>> # I know that maps get folded into the message, so that 
whois_info enrichment is going to create a few fields:
    [Stellar]>>> #  * domain mapped to whois_info.domain
    [Stellar]>>> #  * registrar mapped to whois_info.registrar
    [Stellar]>>> #  * home_country mapped to whois_info.home_country
    [Stellar]>>> #  * owner mapped to whois_info.owner
    [Stellar]>>> whois_info.home_country := 'US'
    [Stellar]>>> # Now with this, we can create a rule or two to triage these 
alerts.
    [Stellar]>>> # This means associating a rule as described by a stellar 
expression that returns true or false with a score
    [Stellar]>>> # Also associated with this ruleset is an aggregation 
function, the default of which is MAX.
    [Stellar]>>> # Now we can make a couple rules:
    [Stellar]>>> #  * If the message is an alert and from a non-us whois 
source, we can set the level to 10
    [Stellar]>>> #  * If the message is an alert and non-local, we can set the 
level to 20
    [Stellar]>>> #  * If the message is an alert and both non-local and non-us, 
then we can set the level to 50
    [Stellar]>>> # If multiple rules hit, then we should take the max (default 
behavior)
    [Stellar]>>> non_us := whois_info.home_country != 'US'
    [Stellar]>>> is_local := IN_SUBNET( if IS_IP(ip_src_addr) then ip_src_addr 
else NULL, '192.168.0.0/21')
    [Stellar]>>> is_both := whois_info.home_country != 'US' && IN_SUBNET( if 
IS_IP(ip_src_addr) then ip_src_addr else NULL, '192.168.0.0/21')
    [Stellar]>>> rules := [ { 'name' : 'is non-us', 'rule' : 
SHELL_GET_EXPRESSION('non_us'), 'score' : 10 } , { 'name' : 'is local', 'rule' 
: SHELL_GET_EXPRESSION('is_local '), 'score' : 20 } , { 'name' : 'both non-us 
and local', 'comment' : 'union of both rules.',  'rule' : 
SHELL_GET_EXPRESSION('is_both'), 'score' : 50 } ]
    [Stellar]>>> # Now that we have our rules staged, we can add them to our 
config.
    [Stellar]>>> squid_enrichment_config_new := THREAT_TRIAGE_ADD( 
squid_enrichment_config_new, rules )
    [Stellar]>>> # Pretty Print the rules
    [Stellar]>>> THREAT_TRIAGE_PRINT(squid_enrichment_config_new)
    
╔═══════════════════════╤══════════════════════╤═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╤═══════╗
    ║ Name                  │ Comment              │ Triage Rule                
                                                                                
       │ Score ║
    
╠═══════════════════════╪══════════════════════╪═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╪═══════╣
    ║ is non-us             │                      │ whois_info.home_country != 
'US'                                                                            
       │ 10    ║
    
╟───────────────────────┼──────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼───────╢
    ║ is local              │                      │ IN_SUBNET( if 
IS_IP(ip_src_addr) then ip_src_addr else NULL, '192.168.0.0/21')                
                    │ 20    ║
    
╟───────────────────────┼──────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼───────╢
    ║ both non-us and local │ union of both rules. │ whois_info.home_country != 
'US' && IN_SUBNET( if IS_IP(ip_src_addr) then ip_src_addr else NULL, 
'192.168.0.0/21') │ 50    ║
    
╚═══════════════════════╧══════════════════════╧═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╧═══════╝
    
    
    Aggregation: MAX
    [Stellar]>>> # Now just print the raw config to make sure it jives
    [Stellar]>>> squid_enrichment_config_new
    {
      "enrichment" : {
        "fieldMap" : { },
        "fieldToTypeMap" : { },
        "config" : { }
      },
      "threatIntel" : {
        "fieldMap" : { },
        "fieldToTypeMap" : { },
        "config" : { },
        "triageConfig" : {
          "riskLevelRules" : [ {
            "name" : "is non-us",
            "rule" : "whois_info.home_country != 'US'",
            "score" : 10.0
          }, {
            "name" : "is local",
            "rule" : "IN_SUBNET( if IS_IP(ip_src_addr) then ip_src_addr else 
NULL, '192.168.0.0/21')",
            "score" : 20.0
          }, {
            "name" : "both non-us and local",
            "comment" : "union of both rules.",
            "rule" : "whois_info.home_country != 'US' && IN_SUBNET( if 
IS_IP(ip_src_addr) then ip_src_addr else NULL, '192.168.0.0/21')",
            "score" : 50.0
          } ],
          "aggregator" : "MAX",
          "aggregationConfig" : { }
        }
      },
      "configuration" : { }
    }
    [Stellar]>>> # Now that we have admired it, we can remove the rules
    [Stellar]>>> squid_enrichment_config_new := THREAT_TRIAGE_REMOVE( 
squid_enrichment_config_new, [ SHELL_GET_EXPRESSION('non_us') , 
SHELL_GET_EXPRESSION('is_local') , SHE LL_GET_EXPRESSION('is_both') ] )
    [Stellar]>>> THREAT_TRIAGE_PRINT(squid_enrichment_config_new)
    ╔══════╤═════════╤═════════════╤═══════╗
    ║ Name │ Comment │ Triage Rule │ Score ║
    ╠══════╧═════════╧═════════════╧═══════╣
    ║ (empty)                              ║
    ╚══════════════════════════════════════╝
    
    ```



> Make Threat Triage rules able to be assigned names and comments
> ---------------------------------------------------------------
>
>                 Key: METRON-675
>                 URL: https://issues.apache.org/jira/browse/METRON-675
>             Project: Metron
>          Issue Type: Improvement
>            Reporter: Casey Stella
>            Assignee: Casey Stella
>
> There may be many, many threat triage rules.  To help organize these, we 
> should make them slightly more complex than a simple key/value as we have it 
> now.  We should add optional name and optional comment fields.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to