Chapter 62

Searching in Arkime

Arkime's query language is a powerful expression language for searching session metadata. Understanding it fluently is what separates a responder who spends 10 minutes retrieving the right PCAP from one who spends 10 seconds. This chapter covers the query syntax with practical incident response search patterns.

Scenario

A Suricata alert fires for a Cobalt Strike JA3 hash at 14:23 UTC from source 10.0.0.50. The analyst searches Arkime: ip.src==10.0.0.50 && tls.ja3=="51c64c77e60f3980eea90869b68c58a8" && starttime>=2024-01-15T14:00 && stoptime<=2024-01-15T15:00. Two sessions match. The analyst clicks "Download PCAP" on the first one and has the full handshake and C2 traffic in Wireshark within 30 seconds.

Query Language Reference

  Arkime Query Language — Syntax
  ═══════════════════════════════════════════════════════════════════

  Comparison operators:
    field==value         exact match
    field!=value         not equal
    field>value          greater than (numeric/time)
    field>=value         greater or equal
    field

Incident Response Search Patterns

textarkime-search-patterns.txt
# ── SCENARIO 1: Host isolation forensics ──────────────────────────────
# Everything from/to a compromised host in the last 24 hours
ip==10.0.0.50 && starttime>=-24h

# All external connections from a compromised host
ip.src==10.0.0.50 && ip.dst != 10.0.0.0/8
&& ip.dst != 172.16.0.0/12 && ip.dst != 192.168.0.0/16

# ── SCENARIO 2: C2 identification ─────────────────────────────────────
# Cobalt Strike JA3 fingerprint
tls.ja3=="51c64c77e60f3980eea90869b68c58a8"

# Self-signed or no-SNI TLS to external
(tls.issuer==/.*CN=.*/ && tls.subject==tls.issuer)
&& ip.dst != 10.0.0.0/8

# TLS to external on non-443 port
protocols==tls && port.dst != 443 && port.dst != 8443
&& ip.dst != 10.0.0.0/8

# ── SCENARIO 3: DNS investigation ─────────────────────────────────────
# DNS queries to specific domain
dns.host==/.*evil\.example\.com.*/

# High NXDOMAIN rate from single host (DGA)
# (Use Arkime's SPI view: group by dns.host, sort by count)
dns.status==NXDOMAIN && ip.src==10.0.0.50

# Long subdomain (DNS tunneling indicator)
dns.host==/[A-Za-z0-9+\/=]{40,}\..*/

# ── SCENARIO 4: Data exfiltration ─────────────────────────────────────
# Large outbound transfers (>10MB in originator direction)
bytes.src>10000000 && ip.dst != 10.0.0.0/8

# HTTP POST with large body to external
http.method==POST && bytes.src>1000000 && ip.dst != 10.0.0.0/8

# ── SCENARIO 5: Lateral movement investigation ────────────────────────
# SMB connections between internal hosts
port.dst==445 && ip.src==10.0.0.0/8 && ip.dst==10.0.0.0/8

# RDP connections (potential lateral movement via RDP)
port.dst==3389 && ip.src==10.0.0.0/8 && ip.dst==10.0.0.0/8
&& starttime>=-24h

# ── SCENARIO 6: Web shell activity ────────────────────────────────────
# POST requests to unusual file extensions
http.method==POST && (http.uri==/*.php* || http.uri==/*.asp*
|| http.uri==/*.aspx*) && http.statuscode==200

# Unusual HTTP User-Agent strings (Cobalt Strike default)
http.user-agent=="Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1)"

# ── SCENARIO 7: Timeline of all events for an IP ──────────────────────
# All sessions involving IP in chronological order
ip==10.0.0.50 && starttime>=2024-01-15T00:00 && stoptime<=2024-01-15T23:59
# Sort by starttime ascending in the UI
Mental model: Arkime search → download PCAP → Wireshark is the forensic workflow

The operational pattern for Arkime use in incident response has three phases: (1) Search: use the Arkime query language to narrow down to the sessions of interest. Start broad (IP + time range), then add protocol-specific filters to reduce to the exact sessions you need. The goal is to identify the right 1-10 sessions from potentially millions in the archive. (2) Inspect: Arkime's session view shows decoded protocol fields — HTTP headers, TLS metadata, DNS queries — without needing to download PCAP. Use this to confirm which sessions are forensically relevant. (3) Download: for sessions that require deeper analysis (payload inspection, protocol anomaly verification, evidence collection), download the PCAP and open in Wireshark. The PCAP download reconstructs only the packets for that specific session — you get a clean, focused PCAP without needing to carve out the right flows from a multi-hour capture file. This workflow compresses what would be hours of manual PCAP work into minutes.

Q & A

Q: Arkime returns no results for a time range I know should have sessions. What's wrong?

Common causes and debugging steps: (1) Time zone mismatch: Arkime stores all times in UTC. If you're in UTC-5 and search for starttime>=2024-01-15T14:00, that's 14:00 UTC — which might be before the event you're looking for if it happened at 14:00 your local time (19:00 UTC). Always use UTC in Arkime queries, or use the relative time format -24h which is always relative to now. (2) Capture node not capturing: check arkime-capture's status — if the capture process crashed or the network interface went down, there will be a gap in the session data. The Arkime web UI shows a green indicator if capture is active. (3) PCAP already rotated/deleted: Arkime metadata persists longer than PCAP (per config.ini settings). Searching for a session from 60 days ago might return metadata but the PCAP download button will fail because the file has been deleted. The session metadata in Elasticsearch is still there, but the packet file isn't. (4) Elasticsearch query timeout: for very broad queries over large time ranges, Elasticsearch may timeout before returning results. Narrow the time range or add more specific filter criteria to reduce the query scope.