Skip to content

New: Microsoft Sentinel TAXII integration is in technical preview.Read the integration guide

ELQ query language

ELQ (ELLIO Query) is the query language behind ELLIO Threat Intelligence search. It powers the dashboard search bar and the CTI search API (/v1/cti/search, /v1/cti/search-docs, /v1/cti/search-aggs) through the q parameter. Queries are field: value clauses combined with boolean operators, lists, ranges, and wildcards:

classification: malicious AND network.port IN (22, 2222) AND last_seen: 7d

Paste an indicator on its own - ELQ recognises the shape and searches the right field automatically:

You type Interpreted as
198.51.100.7 ip: "198.51.100.7"
203.0.113.0/24 ip: "203.0.113.0/24"
CVE-2024-3400 cve: "CVE-2024-3400"
TA0043 mitre_attack.tactics: TA0043
T1595 mitre_attack.techniques: T1595
T1595.002 mitre_attack.sub_techniques: T1595.002
AS13335 src.asn.number: 13335
t13i190800_9dc949149365_97f8aa674fd9 fingerprints.ja4: ...
64240_2-4-8-1-3_1460_7 fingerprints.ja4t: ...
c36s36_c51s80_c0s0 fingerprints.ja4ssh: ...
32-character hex hash fingerprints.ja3: ...

Any other bare word runs as free text across the text fields: rdns, src.asn.name, http.path, http.user_agent, ssh.auth.username, ssh.auth.password, tag, and actor.

Operator Meaning Example
: term match (any listed value matches on multi-valued fields) classification: malicious
!: negated term match classification!: benign
~: full-text match on analysed text fields http.user_agent ~: zgrab
!~: negated full-text match http.user_agent !~: curl
= / != exact equality / inequality network.port = 23
> >= < <= numeric and date comparison active_days > 30
IN (a, b, c) any of the listed values port IN (22, 23, 2323)
[a TO b] inclusive range (both ends required) first_seen:[2026-06-01 TO 2026-06-30]
exists / not_exists field presence rdns not_exists
AND both sides must match (two clauses side by side are also ANDed) tag: "Shodan" AND spoofable: false
OR either side must match country: CN OR country: RU
NOT negate a clause or group NOT tag: "Censys"
( ) group expressions (country: CN OR country: RU) AND spoofable: false
* / ? wildcard: any run / any single character rdns: "*.censys-scanner.com"
"..." exact string with spaces or special characters tag: "Fast Scanner (i.e. Masscan / ZMap)"

Quote string values that contain spaces, slashes, or special characters. Numbers, booleans, enum values, and identifiers like T1595 can stay bare.

Date fields accept relative values: last_seen: 7d means “within the last 7 days”. Units are d, w, m, and y; the dashboard suggests 1d, 3d, 7d, 30d, and 90d (document freshness is daily, so 1d is the smallest useful window). Absolute dates (last_seen >= 2026-07-01) and ranges (last_seen:[7d TO 1d]) work too.

Common fields have short aliases that resolve silently: port, asn, ua, path, username, password, country, city, tactic, technique, sub_technique, and the fingerprint names (muonfp, ja4, ja4t, ja4h, ja4ssh, ja3). country and src.geo.country match either the country code or the country name.

47 fields, organised the way the dashboard organises them.

Field Description Example
ip The IP being searched; accepts single IPs and CIDR blocks ip: "198.51.100.7", ip: "203.0.113.0/24"
classification ELLIO verdict for the IP malicious, promiscuous, benign, unknown
seen Whether the IP was observed in the current window seen: true
spoofable True when the IP never completed a TCP handshake spoofable: false
rdns Reverse DNS hostname rdns: "*.censys-scanner.com"
active_days Days the IP was active in the 91-day window active_days > 30
Field Description Example
last_seen Most recent observation last_seen: 1d, last_seen >= 2026-07-01
first_seen First observation first_seen: 7d, first_seen:[2026-06-01 TO 2026-06-30]
Field Description Example
network.port Destination port the IP touched (any handshake state) network.port: 23, port IN (22, 23, 2323)
network.non_spoofable_port Port with a completed TCP handshake network.non_spoofable_port: 445
network.spoofable_port Port seen only without a completed handshake network.spoofable_port: 53
src.asn.number Autonomous system number announcing the IP src.asn.number: 13335, AS13335
src.asn.name Name of the announcing autonomous system src.asn.name: "*cloudflare*"

Each field exists in a src.geo.* variant (where the IP is) and a dst.geo.* variant (where the ELLIO sensors it targeted are).

Field Description Example
src.geo.country.code / dst.geo.country.code ISO 3166-1 alpha-2 country code country IN (CN, RU)
src.geo.country.name / dst.geo.country.name Country name src.geo.country.name: "United States"
src.geo.city / dst.geo.city City city: "Amsterdam"
src.geo.continent.code / dst.geo.continent.code Continent code src.geo.continent.code: EU
src.geo.continent.name / dst.geo.continent.name Continent name dst.geo.continent.name: Europe
src.geo.latitude / dst.geo.latitude Latitude src.geo.latitude > 50
src.geo.longitude / dst.geo.longitude Longitude src.geo.longitude < 0
Field Description Example
http.path Request paths observed from the IP http.path: "/.env", path: "/wp-*"
http.user_agent User-Agent strings observed from the IP ua: "*zgrab*"
Field Description Example
ssh.auth.username Usernames attempted username: "root"
ssh.auth.password Passwords attempted password: "admin123"
ssh.auth.attempt_count Attempts for this credential pair ssh.auth.attempt_count > 100
ssh.auth.first_seen First observation of the pair ssh.auth.first_seen: 7d
ssh.auth.last_seen Latest observation of the pair ssh.auth.last_seen: 1d
Field Description Example
fingerprints.muonfp MuonFP TCP fingerprint (window_size:tcp_options:mss:window_scale) muonfp: "64240:2-4-8-1-3:1460:7", muonfp: "*:::"
fingerprints.ja4 JA4 TLS client fingerprint ja4: "t13i190800_9dc949149365_97f8aa674fd9"
fingerprints.ja4t JA4T TCP fingerprint ja4t: "64240_2-4-8-1-3_1460_7"
fingerprints.ja4h JA4H HTTP client fingerprint ja4h: "ge11nn15enus_42d7418375b7_000000000000_000000000000"
fingerprints.ja4ssh JA4SSH fingerprint ja4ssh: "c36s36_c51s80_c0s0"
fingerprints.ja3 JA3 TLS client fingerprint (MD5); prefer JA4 where available ja3: "6734f37431670b3ab4292b8f60f29984"

MuonFP fingerprints the TCP SYN packet passively. A value has four colon-separated segments - window_size:tcp_options:mss:window_scale:

Segment Meaning
window_size TCP window advertised in the SYN
tcp_options Option kinds in wire order, joined with dashes (2 = MSS, 4 = SACK permitted, 8 = timestamps, 1 = NOP, 3 = window scale)
mss Maximum segment size, when the MSS option is present
window_scale Window scale value, when that option is present

So 64240:2-4-8-1-3:1460:7 is a full OS TCP stack: window 64240, the common five-option sequence, MSS 1460, window scale 7. Segments the SYN does not populate stay empty but keep their colons - a SYN carrying no TCP options at all produces values like 1024::: or 65535:::, the hallmark of raw-socket scanners such as Masscan and ZMap that craft packets without the kernel’s TCP stack.

Common query shapes:

muonfp: "64240:2-4-8-1-3:1460:7" exact fingerprint
muonfp: "*:::" any optionless SYN (raw-socket tools)
muonfp: "1024:::" Masscan-style: window 1024, no options
muonfp: "65535:*" window 65535, any options
muonfp: "64240:2-4-8-1-3:*:7" same stack, any MSS
muonfp: "??:::" two-digit window, no options
fingerprints.muonfp exists a SYN fingerprint was recorded at all

Two things to know:

  • Bare MuonFP values are not auto-recognised. Unlike JA4 or JA3, a MuonFP value pasted on its own is not sniffed as an indicator (its colons read as field syntax), so always spell the field: muonfp: "...". Quoting is recommended, though unquoted values also parse - muonfp:64240:2-4-8-1-3:1460:7 stays in one piece.
  • MuonFP and JA4T encode the same four SYN attributes. The stack above appears as 64240:2-4-8-1-3:1460:7 in MuonFP and 64240_2-4-8-1-3_1460_7 in JA4T, so you can pivot between the two fields by swapping separators.
Field Description Example
tag Human-readable behaviour tag from the detection pipeline tag: "Telnet Bruteforce"
tag_id Stable identifier of the tag tag_id: "telnet_bruteforce"
actor Known actor or scanner attribution actor: "Censys"
cve CVE identifiers tied to exploitation behaviour cve: "CVE-2024-3400", cve: "CVE-2024-*"
mitre_attack.tactics MITRE ATT&CK tactic IDs tactic: TA0043
mitre_attack.techniques MITRE ATT&CK technique IDs technique: T1595
mitre_attack.sub_techniques MITRE ATT&CK sub-technique IDs sub_technique: T1595.002

Useful combinations to copy-paste into the search bar.

country IN (CN, RU) AND tag: "Fast Scanner (i.e. Masscan / ZMap)"

Always filter spoofable sources out of automated decision-making:

classification: malicious AND spoofable: false
cve: "CVE-2024-3400" AND last_seen: 7d

IPs first seen this week that already carry a CVE association:

first_seen: 7d AND cve exists AND spoofable: false
ssh.auth.username: "root" AND ssh.auth.attempt_count > 100

Long-lived promiscuous scanners active most of the window:

classification: promiscuous AND active_days > 60
rdns: "*.censys-scanner.com"
http.path: "/.env" OR http.path: "/.git/config"
ja4: "t13i190800_9dc949149365_97f8aa674fd9" AND classification: malicious

SYNs with every option segment empty come from tools that build packets in userspace instead of using the OS TCP stack - Masscan, ZMap, and friends:

muonfp: "*:::" AND last_seen: 7d

Narrow it to Masscan’s signature window size:

muonfp: "1024:::"

Scan fleets rotate IPs and ASNs far more often than they rebuild their TCP stack. Take the MuonFP value from an IP you already caught and look for fresh arrivals wearing the same stack:

muonfp: "64240:2-4-8-1-3:1460:7" AND first_seen: 7d AND spoofable: false

IPs in one continent targeting ELLIO sensors in another:

src.geo.continent.code: AS AND dst.geo.continent.code: NA
  • Paste indicators directly. IPs, CIDRs, CVEs, ATT&CK IDs, ASNs, and JA3/JA4-family fingerprints work without a field name. MuonFP is the exception - its colons read as field syntax, so give it the field name: muonfp: "...".
  • Quote anything with spaces or special characters. Tag names, organisations, RDNS hostnames, HTTP paths, and SSH credentials almost always need quotes.
  • Use wildcards to match families. rdns: "*.censys-scanner.com" catches every Censys scanner host; tag: "*Scanner*" catches every scanner tag.
  • Group with parentheses before joining with AND. Mixing OR and AND without parentheses leads to surprising precedence.
  • Add spoofable: false to anything you feed into a blocklist or alerting pipeline - spoofable observations can come from a forged source.
  • Let the search bar help. Autocomplete suggests fields, operators, and live values from the current index as you type, and flags syntax problems with one-click fixes before the search runs.
  • IP detail page - every field in this reference, rendered for a single IP.
  • Tags - the canonical list of values for the tag field.
  • CTI API - run the same ELQ queries programmatically via the q parameter of the search endpoints, alongside per-IP lookup.