Claude
Skills
Sign in
Back

d-and-r-rules

Included with Lifetime
$97 forever

Working with Detection & Response rules in LimaCharlie — AI-assisted generation, validation, unit testing, historical replay, deployment, FP rules, stateful rules, behavioral detection patterns, suppression, alternate detection targets, and response actions. Use when creating, testing, modifying, or managing D&R rules, false positive rules, or understanding detection patterns.

General

What this skill does


# D&R Rules

How to work with Detection & Response rules in LimaCharlie. This covers rule generation, validation, testing, deployment, stateful rules, behavioral detection patterns, suppression, alternate targets, and response actions.

## Critical Rule: NEVER Write D&R Rules Manually

D&R rule syntax is validated against organization-specific schemas. Manual YAML will fail validation. **Always use AI generation commands.**

## Rule Generation

### Generate Detection Component

```bash
limacharlie ai generate-detection --description "Detect NEW_PROCESS events where the command line contains '-enc' and the process is powershell.exe" --oid <oid> --output yaml
```

### Generate Response Component

```bash
limacharlie ai generate-response --description "Report the detection with priority 8, add tag 'encoded-powershell' with 7 day TTL" --oid <oid> --output yaml
```

### Common Response Actions

| Action | Description |
|--------|-------------|
| `report` | Create a detection (alert) |
| `tag` | Add/remove sensor tags |
| `task` | Send command to sensor |
| `isolate network` | Persistent network isolation (survives reboot) |
| `rejoin network` | Remove network isolation |
| `seal` / `unseal` | Tamper-resistance for the EDR |
| `add var` / `del var` | Set/remove sensor variables |
| `extension request` | Call an extension asynchronously |
| `start ai agent` | Spawn AI session |
| `output` | Forward event to a specific output |
| `wait` | Delay before next action (max 1 minute) |

## Validation

**Always validate before deploying.** Write YAML to temp files, then validate:

```bash
cat > /tmp/detect.yaml << 'EOF'
<detection_yaml>
EOF
cat > /tmp/respond.yaml << 'EOF'
<response_yaml>
EOF
limacharlie dr validate --detect /tmp/detect.yaml --respond /tmp/respond.yaml --oid <oid>
```

## Unit Testing

Test rules against crafted sample events:

```bash
# Write combined rule file
cat > /tmp/rule.yaml << 'EOF'
detect:
  <detection>
respond:
  <response>
EOF

# Write test events
cat > /tmp/events.json << 'EOF'
[
  {
    "routing": {"event_type": "NEW_PROCESS"},
    "event": {
      "COMMAND_LINE": "powershell.exe -enc SGVsbG8=",
      "FILE_PATH": "C:\\Windows\\System32\\powershell.exe"
    }
  }
]
EOF

limacharlie dr test --input-file /tmp/rule.yaml --events /tmp/events.json --trace --oid <oid> --output yaml
```

Create both positive tests (MUST match) and negative tests (MUST NOT match).

## Historical Replay

Test rules against real historical data. The rule must be deployed first (use a temporary name):

```bash
# Deploy as temporary rule
limacharlie dr set --key temp-test-rule --input-file /tmp/rule.yaml --oid <oid>

# Calculate time range
start=$(date -d '1 hour ago' +%s) && end=$(date +%s)

# Estimate volume first (dry run)
limacharlie dr replay --name temp-test-rule --start $start --end $end --dry-run --oid <oid> --output yaml

# Run replay
limacharlie dr replay --name temp-test-rule --start $start --end $end --oid <oid> --output yaml

# With selector
limacharlie dr replay --name temp-test-rule --start $start --end $end --selector 'plat == "windows"' --oid <oid> --output yaml

# Clean up temporary rule
limacharlie dr delete --key temp-test-rule --confirm --oid <oid>
```

## Deployment

### Create/Update a Rule

```bash
cat > /tmp/rule.yaml << 'EOF'
detect:
  <validated_detection>
respond:
  <validated_response>
EOF
limacharlie dr set --key <rule-name> --input-file /tmp/rule.yaml --oid <oid>
```

### List Rules

```bash
limacharlie dr list --oid <oid> --output yaml
```

### Get a Rule

```bash
limacharlie dr get --key <rule-name> --oid <oid> --output yaml
```

### Delete a Rule

```bash
limacharlie dr delete --key <rule-name> --confirm --oid <oid>
```

## Rule Hive Namespaces

D&R rules are stored across three hives:

| Hive | Description | How Added |
|------|-------------|-----------|
| `dr-general` | Custom rules you create | `limacharlie dr set` |
| `dr-managed` | Managed rules from subscribed rulesets | Automatic from subscriptions |
| `dr-services` | Service-provided rules | From extensions/services |

When listing or auditing rules, check all three for the full picture.

## False Positive (FP) Rules

FP rules suppress known benign detections without modifying the original detection rule. **FP rules operate on the detection output, not the raw event** — the paths reference detection fields, not event fields.

### Create FP Rule

```bash
cat > /tmp/fp-rule.yaml << 'EOF'
detection:
  op: and
  rules:
    - op: is
      path: cat
      value: suspicious_process
    - op: is
      path: routing/hostname
      value: SCCM-SERVER
EOF
limacharlie fp set --key <fp-rule-name> --input-file /tmp/fp-rule.yaml --oid <oid>
```

### FP Rule Paths

FP rules operate on detection output. Key paths:

| Path | Description |
|------|-------------|
| `cat` | Detection category |
| `detect/name` | Detection rule name |
| `detect/event/*` | Original event fields |
| `routing/hostname` | Sensor hostname |
| `routing/tags` | Sensor tags |
| `routing/sid` | Sensor ID |

### List / Delete FP Rules

```bash
limacharlie fp list --oid <oid> --output yaml
limacharlie fp delete --key <fp-rule-name> --confirm --oid <oid>
```

## Detection Logic Operators

| Operator | Description |
|----------|-------------|
| `and` | All conditions must match |
| `or` | Any condition must match |
| `is` | Exact match |
| `contains` | Substring match |
| `starts with` | Prefix match |
| `ends with` | Suffix match |
| `exists` | Field exists |
| `matches` | Regex match |
| `is platform` | Platform check |
| `is tagged` | Tag check |
| `is windows` | Windows platform shorthand |
| `lookup` | Look up a value against a lookup table or API resource |
| `is public address` | Check if IP is public |
| `string distance` | Levenshtein distance |

---

# Stateful Rules

Stateful rules track and remember the state of past events to detect patterns over time. Unlike stateless rules (which evaluate events in isolation), stateful rules detect patterns like "process A spawning process B" or "5 failed logins within 60 seconds."

Events in LimaCharlie have well-defined relationships via `routing/this`, `routing/parent`, and `routing/target`. Stateful rules leverage these relationships.

## Detecting Children / Descendants

Use `with child` (direct children only) or `with descendant` (children, grandchildren, etc.) to detect process tree patterns:

```yaml
# Detect cmd.exe spawning calc.exe
event: NEW_PROCESS
op: ends with
path: event/FILE_PATH
value: cmd.exe
case sensitive: false
with child:
  op: ends with
  event: NEW_PROCESS
  path: event/FILE_PATH
  value: calc.exe
  case sensitive: false
```

This detects `cmd.exe → calc.exe` but NOT `cmd.exe → firefox.exe → calc.exe`. Use `with descendant` to match at any depth.

### Complex Child Patterns with `and`/`or`

Stateful rules support full operator nesting. Detect outlook.exe spawning a browser AND dropping a PowerShell script:

```yaml
event: NEW_PROCESS
op: ends with
path: event/FILE_PATH
value: outlook.exe
case sensitive: false
with child:
  op: and
  rules:
    - op: ends with
      event: NEW_PROCESS
      path: event/FILE_PATH
      value: chrome.exe
      case sensitive: false
    - op: ends with
      event: NEW_DOCUMENT
      path: event/FILE_PATH
      value: .ps1
      case sensitive: false
```

## Detecting Proximal Events (Repetition)

Use `with events` to detect event repetition on the same sensor within a time window:

```yaml
# 5 failed login attempts within 60 seconds
event: WEL
op: is windows
with events:
  event: WEL
  op: is
  path: event/EVENT/System/EventID
  value: '4625'
  count: 5
  within: 60
```

## Counting Events in Process Trees

`with child` and `with descendant` also support `count` and `within`:

```yaml
# Outlook writing 5+ .ps1 files within 60 seconds
event: NEW_PROCESS
op: ends with
path: event/FILE_PATH
value: outlook.exe
case sensitive: false
with child:
  op: ends with
  event: NEW_DOCUMENT
  path: event/FILE_PATH
  value: .ps1
  

Related in General