GreyNoise

security

GreyNoise

Definition

GreyNoise is a cybersecurity intelligence platform that collects and analyzes internet background noise -- the constant barrage of automated scanning, crawling, and probing that constitutes the internet's "weather." Founded by Andrew Morris in 2017, GreyNoise operates a globally distributed network of passive sensors that observe and categorize unsolicited internet traffic. By cataloging which IP addresses are mass-scanning the internet and determining whether their activity is benign (security researchers, search engines, legitimate scanners) or malicious (botnets, worms, exploit scanners), GreyNoise helps analysts distinguish targeted attacks from opportunistic background noise.

The fundamental insight behind GreyNoise is that a significant portion of the alerts generated by security tools are triggered by non-targeted, automated internet scanning rather than actual threat activity. Studies have shown that up to 30-40% of firewall and IDS alerts are caused by benign internet background noise. By identifying and filtering this noise, GreyNoise dramatically reduces the volume of false positives that security teams must investigate, allowing analysts to focus on genuine threats.

GreyNoise categorizes every observed IP address into one of three classifications: benign (known legitimate scanners such as Shodan, Censys, academic researchers, and CDN probes), malicious (known botnets, exploit scanners, and command-and-control infrastructure), or unknown (observed scanning but without sufficient context for classification). This tripartite classification, combined with rich contextual metadata about each scanner's behavior, makes GreyNoise an invaluable complement to active scanning tools like Shodan and Censys.

Core Capabilities

GreyNoise provides several interconnected capabilities for internet noise intelligence:

CapabilityDescriptionSecurity Value
Noise ClassificationCategorize IPs as benign, malicious, or unknownReduce alert fatigue, prioritize real threats
RIOT DatasetRule It Out -- known benign services databaseImmediate false positive elimination
IP ContextDetailed metadata on scanning behaviorUnderstand scanner intent and methodology
Tag SystemBehavioral tags describing scanner activityRapid categorization (e.g., "Mirai-like", "SSH Bruteforcer")
CVE CorrelationMap scanning to specific vulnerability exploitsTrack active exploitation campaigns
Timeline AnalysisHistorical scanning behavior over timeDetect changes in scanner behavior or intent
Mass Assignment DetectionIdentify IPs scanning large portions of the internetDistinguish targeted from opportunistic scanning

IP Classification Model

GreyNoise's classification system provides a nuanced view of internet scanning activity:

ClassificationDefinitionExamplesAlert Action
BenignKnown legitimate, non-malicious scanningShodan, Censys, Google, Cloudflare, University researchersSuppress alerts
MaliciousKnown harmful scanning or exploitationBotnets (Mirai, Hajime), exploit scanners, C2 infrastructureEscalate and investigate
UnknownObserved scanning, insufficient classification dataUnidentified mass scanners, VPN exit nodes, newly observed IPsContext-dependent triage

The classification is supported by rich metadata:

{
  "ip": "198.51.100.42",
  "seen": true,
  "classification": "benign",
  "first_seen": "2024-01-15",
  "last_seen": "2026-02-14",
  "actor": "Censys",
  "tags": ["censys-scanner", "tls-scanner", "http-crawler"],
  "cve": [],
  "metadata": {
    "asn": "AS395954",
    "city": "Ann Arbor",
    "country": "United States",
    "country_code": "US",
    "organization": "Censys, Inc.",
    "os": "Linux",
    "rdns": "scanner-42.censys.io"
  },
  "raw_data": {
    "scan": [
      {"port": 443, "protocol": "TCP"},
      {"port": 80, "protocol": "TCP"}
    ],
    "web": {
      "useragents": ["Mozilla/5.0 zgrab/0.x"]
    }
  }
}

RIOT Dataset

The RIOT (Rule It Out) dataset is a curated database of IP addresses belonging to known benign services. Unlike the main classification system which observes scanning behavior, RIOT identifies IPs based on their organizational ownership:

RIOT CategoryExamplesPurpose
CDN ProvidersCloudflare, Akamai, Fastly, AWS CloudFrontFilter CDN health checks and edge probes
Search EnginesGooglebot, Bingbot, Yandex, Baidu SpiderFilter crawler traffic
Cloud ProvidersAWS, GCP, Azure health checksFilter infrastructure monitoring
Security ScannersShodan, Censys, Qualys, Rapid7Filter known-benign security scanning
DNS ProvidersGoogle DNS, Cloudflare DNS, OpenDNSFilter DNS resolution traffic
Monitoring ServicesPingdom, UptimeRobot, StatusCakeFilter uptime monitoring probes

The RIOT dataset enables instant false positive elimination: if an alert-triggering IP is in the RIOT database, the alert can be safely suppressed without further analysis. This "rule it out" approach is significantly faster than behavioral analysis.

API Integration

GreyNoise provides both Community (free) and Enterprise APIs for programmatic access:

# GreyNoise API client for Prismatic EASM
defmodule PrismaticPerimeter.Sources.GreyNoise do
  @moduledoc "GreyNoise API integration for noise filtering and IP context"

  @base_url "https://api.greynoise.io/v3"

  @type ip_context :: %{
    ip: String.t(),
    seen: boolean(),
    classification: :benign | :malicious | :unknown,
    actor: String.t() | nil,
    tags: [String.t()],
    cve: [String.t()],
    first_seen: Date.t() | nil,
    last_seen: Date.t() | nil,
    metadata: map()
  }

  @doc "Get full context for a specific IP address"
  @spec ip_context(String.t()) :: {:ok, ip_context()} | {:error, term()}
  def ip_context(ip) do
    case authenticated_request(:get, "/community/#{ip}") do
      {:ok, %{status: 200, body: body}} ->
        {:ok, parse_context(body)}

      {:ok, %{status: 404}} ->
        {:ok, %{ip: ip, seen: false, classification: :unknown}}

      {:error, reason} ->
        {:error, reason}
    end
  end

  @doc "Quick check if IP is noise (benign scanner)"
  @spec is_noise?(String.t()) :: {:ok, boolean()} | {:error, term()}
  def is_noise?(ip) do
    case ip_context(ip) do
      {:ok, %{classification: :benign}} -> {:ok, true}
      {:ok, _} -> {:ok, false}
      {:error, reason} -> {:error, reason}
    end
  end

  @doc "Check if IP is in RIOT dataset (known benign service)"
  @spec riot_check(String.t()) :: {:ok, map()} | {:error, term()}
  def riot_check(ip) do
    case authenticated_request(:get, "/riot/#{ip}") do
      {:ok, %{status: 200, body: body}} -> {:ok, body}
      {:ok, %{status: 404}} -> {:ok, %{riot: false, ip: ip}}
      {:error, reason} -> {:error, reason}
    end
  end

  @doc "Bulk context lookup for multiple IPs"
  @spec bulk_context([String.t()]) :: {:ok, [ip_context()]} | {:error, term()}
  def bulk_context(ips) when is_list(ips) do
    body = %{ips: ips}

    case authenticated_request(:post, "/noise/multi/quick", body) do
      {:ok, %{status: 200, body: results}} ->
        {:ok, Enum.map(results, &parse_context/1)}

      {:error, reason} ->
        {:error, reason}
    end
  end

  @doc "Lookup context for IPs associated with a domain's attack surface"
  @spec context_lookup(String.t()) :: {:ok, [ip_context()]} | {:error, term()}
  def context_lookup(domain) do
    # GreyNoise does not search by domain directly;
    # this is called after Shodan/Censys resolve IPs for a domain
    {:ok, []}
  end

  defp authenticated_request(method, path, body \\ nil) do
    headers = [
      {"key", api_key()},
      {"Accept", "application/json"}
    ]

    HTTPClient.request(method, "#{@base_url}#{path}",
      headers: headers,
      json: body
    )
  end

  defp api_key, do: Application.get_env(:prismatic_perimeter, :greynoise_api_key)
end

Context in Prismatic

The Prismatic Platform integrates GreyNoise in the Perimeter module to contextualize findings from Shodan and Censys. When the EASM discovery pipeline identifies exposed services, GreyNoise data determines whether incoming traffic to those services represents targeted threat activity or benign background noise. This context significantly improves security rating accuracy by preventing benign scanner activity from inflating risk scores.

GreyNoise integration occurs at the enrichment stage of the discovery pipeline:

  1. Discovery (Shodan + Censys): Identify exposed services and their source IPs
  2. Noise Filtering (GreyNoise): Classify IPs interacting with discovered services
  3. Context Enrichment: Attach behavioral tags, classification, and RIOT data to findings
  4. Scoring Adjustment: Modify risk scores based on noise classification
# GreyNoise noise filtering in the EASM pipeline
defmodule PrismaticPerimeter.Enrichment.NoiseFilter do
  alias PrismaticPerimeter.Sources.GreyNoise

  @doc "Filter and contextualize findings with GreyNoise data"
  @spec enrich_findings([finding()]) :: [enriched_finding()]
  def enrich_findings(findings) do
    # Extract unique IPs from findings
    ips = findings |> Enum.map(& &1.source_ip) |> Enum.uniq()

    # Bulk lookup for efficiency
    {:ok, contexts} = GreyNoise.bulk_context(ips)
    context_map = Map.new(contexts, &{&1.ip, &1})

    # Enrich each finding
    Enum.map(findings, fn finding ->
      context = Map.get(context_map, finding.source_ip, %{classification: :unknown})

      %{finding |
        noise_classification: context.classification,
        noise_actor: context[:actor],
        noise_tags: context[:tags] || [],
        risk_adjustment: calculate_risk_adjustment(context),
        confidence_modifier: confidence_from_classification(context)
      }
    end)
  end

  defp calculate_risk_adjustment(%{classification: :benign}), do: -0.5
  defp calculate_risk_adjustment(%{classification: :malicious}), do: +0.3
  defp calculate_risk_adjustment(%{classification: :unknown}), do: 0.0

  defp confidence_from_classification(%{classification: :benign}), do: 0.95
  defp confidence_from_classification(%{classification: :malicious}), do: 0.90
  defp confidence_from_classification(_), do: 0.50
end

GreyNoise acts as the third independent signal source for the Signal Plurality axiom. While Shodan and Censys provide asset discovery signals, GreyNoise provides threat context signals, creating a multi-dimensional assessment that satisfies the epistemic requirement for independent corroboration.

False Positive Reduction Impact

The quantitative impact of GreyNoise integration on alert accuracy:

MetricWithout GreyNoiseWith GreyNoiseImprovement
Alert volume100% (baseline)60-70%30-40% reduction
False positive rate30-40%5-10%75-80% reduction
Analyst triage time15-30 min per alert5-10 min per alert50-67% reduction
Mean time to respondHoursMinutesOrder of magnitude
Risk score accuracyModerateHighSignificant improvement

Comparison with Alternatives

FeatureGreyNoiseShodanCensysAbuseIPDB
Primary purposeNoise classificationService discoveryHost/cert scanningAbuse reporting
Data collectionPassive sensorsActive scanningActive scanningCommunity reports
Classification modelBenign/Malicious/UnknownService identificationHost enumerationAbuse categories
RIOT datasetYes (curated benign DB)NoNoNo
CVE correlationActive exploitation trackingVulnerability taggingLimitedNo
API speedVery fast (single IP lookup <100ms)ModerateModerateFast
Prismatic roleNoise filtering, threat contextPrimary discoveryCertificate corroborationNot integrated
  • Shodan - Scanning platform whose findings GreyNoise contextualizes
  • Censys - Discovery platform complemented by GreyNoise noise filtering
  • EASM - Attack surface management benefiting from noise reduction
  • Signal Plurality - Axiom satisfied by GreyNoise as third signal source
  • Attack Surface - External surface where noise filtering improves accuracy
  • Risk Score - Grades improved by filtering benign scanner activity
  • Rate Limiting - API quota management for GreyNoise integration
  • Contradiction Preservation - Handling conflicting threat assessments
  • Time Decay - GreyNoise temporal context for aging findings
  • Confidence Scoring - Classification confidence levels from GreyNoise data

See Also

  • Architecture - EASM enrichment pipeline architecture
  • Apps - Prismatic Perimeter application
  • OSINT - Open-source intelligence collection methodology

Connect & Contribute

Created by Tomáš Korcak (korczis) | Open Source under GHL