Soar Security Orchestration

LogZilla documentation for Soar Security Orchestration

SOAR Security Orchestration

Security Orchestration, Automation, and Response (SOAR) capabilities detect sophisticated attack patterns that span multiple events, systems, and time periods. LogZilla's pre-processing extracts security fields, while SEC handles complex correlation logic. SEC generates synthetic events back to LogZilla, where triggers perform intelligent automated responses.

Prerequisites: Ensure Event Correlation is enabled and forwarder reloading is available as shown in the Event Correlation Overview.

Geographic Anomaly Detection

Impossible Travel Detection

Detect when the same user logs in from geographically distant locations within an impossible timeframe.

Required Apps and Configuration

Required Apps:

  • linux__pam app (for PAM User Tracking and PAM Remote Host user tags)
  • geoip app (for SrcIP Country, SrcIP City, SrcIP State user tags)

IP Address Mapping Rule

The GeoIP app requires SrcIP user tags, but PAM creates PAM Remote Host. Create a mapping rule:

File: /etc/logzilla/rules/enabled/601-pam-mapping.lua

lua
-- Map PAM Remote Host to SrcIP for GeoIP processing
function process(event)
    if event.user_tags["PAM Remote Host"] then
        event.user_tags["SrcIP"] = event.user_tags["PAM Remote Host"]
    end
end

LogZilla Forwarder Configuration

yaml
# /etc/logzilla/forwarder.d/geographic-security.yaml
type: sec
sec_name: geographic-security
rules:
  - match:
      - field: program
        op: "eq"
        value: ["sshd", "rdp", "vpn", "web_auth"]
      - field: message
        op: "=~"
        value: "(Accepted password|session opened|login successful)"
    rewrite:
      message: "AUTH_SUCCESS $MESSAGE"

SEC Rule: Impossible Travel Detection

File: /etc/logzilla/sec/geographic-security/rules/impossible-travel.sec

text
# Detect impossible travel - same user from different countries within 1 hour
type=Single
ptype=SubStr
pattern=AUTH_SUCCESS
desc=Checking for impossible travel
action=eval %username $ENV{EVENT_USER_TAGS_PAM_USER_TRACKING}; \
       eval %new_country $ENV{EVENT_USER_TAGS_SRCIP_COUNTRY}; \
       eval %new_ip $ENV{EVENT_USER_TAGS_SRCIP}; \
       eval %old_country (context("USER_LOGIN_%username", "country")); \
       eval %old_ip (context("USER_LOGIN_%username", "ip")); \
       if ((%new_country ne %old_country) && (%old_country ne "")) { \
           shellcmd (logger -t SEC-SECURITY -p local0.alert \
           "IMPOSSIBLE_TRAVEL user=\"%username\" old_ip=\"%old_ip\" old_country=\"%old_country\" new_ip=\"%new_ip\" new_country=\"%new_country\""); \
       }; \
       setcontext USER_LOGIN_%username 3600 (country %new_country, ip %new_ip)

Processing Chain

The complete geographic correlation works through this processing chain:

  1. PAM Rule (600-linux-pam.lua) extracts authentication data:

    • Creates PAM User Tracking (username)
    • Creates PAM Remote Host (source IP)
  2. Mapping Rule (601-pam-mapping.lua) prepares for GeoIP:

    • Copies PAM Remote HostSrcIP
  3. GeoIP Rule (999-add-geodata.lua) adds geographic data:

    • Creates SrcIP Country, SrcIP City, SrcIP State
  4. Forwarder sends enriched event to SEC with all user tags appended

  5. SEC Rule parses user tags from message and detects impossible travel

LogZilla Trigger: Impossible Travel Response

yaml
# Trigger responds to SEC-generated impossible travel events
name: "Impossible Travel Incident Response"
filter:
  - field: program
    op: eq
    value: SEC-SECURITY
  - field: message
    op: "=~"
    value: "IMPOSSIBLE_TRAVEL"
actions:
  send_email: true
  send_email_template: |
    Subject: SECURITY ALERT: Impossible Travel Detected
    
    User: {{event:ut:username}}
    Locations: {{event:ut:details}}
    
    This indicates potential credential compromise.
  exec_script: true
  script_path: "/usr/local/bin/impossible-travel-response.sh"
  issue_notification: true

Intelligent Response Script

bash
#!/bin/bash
# /usr/local/bin/impossible-travel-response.sh
# Called by SEC shellcmd - receives data via command-line arguments

USERNAME="$1"
DETAILS="$2"

# Query HR system for user travel status
TRAVEL_STATUS=$(curl -s "https://hr-api.company.com/travel-status/$USERNAME")

# Query threat intelligence for IP reputation  
# Note: IP would need to be extracted from DETAILS or passed as separate argument
IP_REPUTATION=$(curl -s "https://threat-intel.company.com/ip-reputation/$(echo $DETAILS | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')")

# Make intelligent decision based on context
if [[ "$TRAVEL_STATUS" == "approved_travel" ]]; then
    # User has approved travel - lower priority
    logger -t SECURITY-RESPONSE "Impossible travel for $USERNAME - approved travel detected"
    # Create low-priority ticket
    curl -X POST "https://servicedesk.company.com/api/tickets" \
         -d "priority=low&subject=Travel Login Verification&user=$USERNAME"
elif [[ "$IP_REPUTATION" == "malicious" ]]; then
    # High-risk scenario - immediate response
    logger -t SECURITY-RESPONSE "Impossible travel for $USERNAME - malicious IP detected"
    # Disable account immediately
    curl -X POST "https://identity.company.com/api/disable-account" -d "username=$USERNAME"
    # Create high-priority incident
    curl -X POST "https://servicedesk.company.com/api/incidents" \
         -d "priority=critical&subject=Account Compromise&user=$USERNAME&details=$DETAILS"
    # Alert SOC team
    curl -X POST "https://slack.company.com/api/webhooks/soc-alerts" \
         -d "text=CRITICAL: Account compromise detected for $USERNAME"
else
    # Standard response - investigate
    logger -t SECURITY-RESPONSE "Impossible travel for $USERNAME - investigation required"
    # Temporarily restrict account
    curl -X POST "https://identity.company.com/api/restrict-account" -d "username=$USERNAME"
    # Create medium-priority ticket
    curl -X POST "https://servicedesk.company.com/api/tickets" \
         -d "priority=medium&subject=Impossible Travel Investigation&user=$USERNAME"
fi

Lateral Movement Detection

Cross-System Access Correlation

Detect lateral movement by correlating edge system logins with internal network access.

SEC Rule: Lateral Movement Correlation

text
# Create context for edge system logins
type=Single
ptype=SubStr
pattern=AUTH_SUCCESS
context=($ENV{EVENT_HOST} =~ /^(web|dmz|edge|vpn)/)
desc=Edge system access by $ENV{EVENT_USER_TAGS_PAM_USER_TRACKING}
action=eval %username $ENV{EVENT_USER_TAGS_PAM_USER_TRACKING}; \
       eval %edge_host $ENV{EVENT_HOST}; \
       eval %src_ip $ENV{EVENT_USER_TAGS_PAM_REMOTE_HOST}; \
       create EDGE_ACCESS_%username_%edge_host 3600; \
       shellcmd (logger -t SEC-AUDIT "EDGE_LOGIN user=\"%username\" host=\"%edge_host\" src_ip=\"%src_ip\"")

# Detect internal network access from edge systems
type=Single
ptype=SubStr
pattern=NETWORK_CONNECTION
context=(EDGE_ACCESS_$ENV{EVENT_USER_TAGS_PAM_USER_TRACKING}_$ENV{EVENT_USER_TAGS_SRCIP}) && \
        ($ENV{EVENT_USER_TAGS_DSTIP} =~ /^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)/)
desc=Potential lateral movement detected
action=eval %username $ENV{EVENT_USER_TAGS_PAM_USER_TRACKING}; \
       eval %src_host $ENV{EVENT_HOST}; \
       eval %dst_ip $ENV{EVENT_USER_TAGS_DSTIP}; \
       eval %dst_port $ENV{EVENT_USER_TAGS_DSTPORT}; \
       shellcmd (logger -t SEC-SECURITY -p local0.crit \
       "LATERAL_MOVEMENT user=%username src_host=%src_host dst_ip=%dst_ip dst_port=%dst_port")

LogZilla Trigger: Lateral Movement Response

yaml
name: "Lateral Movement Incident Response"
filter:
  - field: program
    op: eq
    value: SEC-SECURITY
  - field: message
    op: "=~"
    value: "LATERAL_MOVEMENT"
actions:
  exec_script: true
  script_path: "/usr/local/bin/lateral-movement-response.sh"
  issue_notification: true
  send_webhook: true
  send_webhook_template: |
    {
      "alert_type": "lateral_movement",
      "user": "{{event:ut:username}}",
      "source_host": "{{event:ut:src_host}}",
      "destination": "{{event:ut:dst_ip}}:{{event:ut:dst_port}}",
      "severity": "critical"
    }

Advanced Persistent Threat (APT) Detection

Multi-Stage APT Correlation

Detect sophisticated attack campaigns across multiple stages and systems.

SEC Rule: APT Campaign Detection

text
# Stage 1: Initial compromise indicators
type=Single
ptype=SubStr
pattern=SUSPICIOUS_OUTBOUND
context=($ENV{EVENT_USER_TAGS_DESTINATION} =~ /suspicious_domain|known_c2/)
desc=Potential C2 communication detected
action=eval %host $ENV{EVENT_HOST}; \
       eval %dst $ENV{EVENT_USER_TAGS_DESTINATION}; \
       create APT_INDICATOR_%host 86400; \
       shellcmd (logger -t SEC-APT "APT_STAGE1 host=\"%host\" destination=\"%dst\"")

# Stage 2: Credential harvesting
type=Single
ptype=SubStr
pattern=PROCESS_CREATION
context=(APT_INDICATOR_$ENV{EVENT_HOST}) && \
        ($ENV{EVENT_USER_TAGS_PROCESS_NAME} =~ /(mimikatz|lsass|procdump)/)
desc=Credential harvesting detected on compromised host
action=eval %host $ENV{EVENT_HOST}; \
       eval %process $ENV{EVENT_USER_TAGS_PROCESS_NAME}; \
       shellcmd (logger -t SEC-APT "APT_STAGE2 host=\"%host\" process=\"%process\"")

# Stage 3: Data exfiltration
type=Single
ptype=SubStr
pattern=LARGE_DATA_TRANSFER
context=(APT_INDICATOR_$ENV{EVENT_HOST}) && \
        ($ENV{EVENT_USER_TAGS_BYTES_TRANSFERRED} > 100000000)
desc=Potential data exfiltration from compromised host
action=eval %host $ENV{EVENT_HOST}; \
       eval %bytes $ENV{EVENT_USER_TAGS_BYTES_TRANSFERRED}; \
       eval %dst $ENV{EVENT_USER_TAGS_DESTINATION}; \
       shellcmd (logger -t SEC-APT -p local0.crit \
       "APT_CAMPAIGN host=%host bytes=%bytes destination=%dst")

LogZilla Trigger: APT Campaign Response

yaml
name: "APT Campaign Incident Response"
filter:
  - field: program
    op: eq
    value: SEC-APT
  - field: message
    op: "=~"
    value: "APT_CAMPAIGN"
actions:
  exec_script: true
  script_path: "/usr/local/bin/apt-campaign-response.sh"
  send_email: true
  send_email_template: |
    Subject: CRITICAL: APT Campaign Detected
    
    Host: {{event:ut:host}}
    Data Exfiltrated: {{event:ut:bytes}} bytes
    Destination: {{event:ut:destination}}
    
    Immediate containment required.

Privilege Escalation Detection

Account Privilege Changes Correlation

Monitor for suspicious privilege escalations and administrative access patterns.

SEC Rule: Privilege Escalation Correlation

text
# Track administrative access attempts
type=SingleWithThreshold
ptype=SubStr
pattern=ADMIN_ACCESS_ATTEMPT
context=($ENV{EVENT_USER_TAGS_AUTH_RESULT} eq "failed")
desc=Multiple failed admin access attempts
action=eval %username $ENV{EVENT_USER_TAGS_PAM_USER_TRACKING}; \
       eval %target_host $ENV{EVENT_HOST}; \
       shellcmd (logger -t SEC-SECURITY \
       "PRIVILEGE_ESCALATION_ATTEMPT user=%username target=%target_host count=$thresh")
thresh=5
window=300

# Detect successful admin access after failed attempts
type=PairWithWindow
ptype=SubStr
pattern=PRIVILEGE_ESCALATION_ATTEMPT
desc=Successful privilege escalation after failed attempts
action=eval %username $ENV{EVENT_USER_TAGS_PAM_USER_TRACKING}; \
       eval %target_host $ENV{EVENT_HOST}; \
       shellcmd (logger -t SEC-SECURITY -p local0.alert \
       "PRIVILEGE_ESCALATION_SUCCESS user=%username target=%target_host")
ptype2=SubStr
pattern2=ADMIN_ACCESS_ATTEMPT
context2=($ENV{EVENT_USER_TAGS_AUTH_RESULT} eq "success") && \
         ($ENV{EVENT_USER_TAGS_PAM_USER_TRACKING} eq "%username") && \
         ($ENV{EVENT_HOST} eq "%target_host")
desc2=Admin access granted after escalation attempts
action2=logonly
window=600

Related Topics

Soar Security Orchestration | LogZilla Documentation