Module: Mihari::Schemas

Defined in:
lib/mihari/schemas/rule.rb,
lib/mihari/schemas/emitter.rb,
lib/mihari/schemas/analyzer.rb

Defined Under Namespace

Classes: RuleContract

Constant Summary collapse

Rule =
Dry::Schema.Params do
  required(:title).value(:string)
  required(:description).value(:string)

  optional(:tags).value(array[:string]).default([])
  optional(:id).value(:string)

  optional(:author).value(:string)
  optional(:created_on).value(:date)
  optional(:updated_on).value(:date)

  required(:queries).value(:array).each { AnalyzerWithoutAPIKey | AnalyzerWithAPIKey | Censys | CIRCL | PassiveTotal | Spyse | ZoomEye | Urlscan | Crtsh | Feed }

  optional(:emitters).value(:array).each { Emitter | MISP | TheHive | Slack | HTTP }

  optional(:allowed_data_types).value(array[Types::DataTypes]).default(ALLOWED_DATA_TYPES)
  optional(:disallowed_data_values).value(array[:string]).default([])

  optional(:ignore_old_artifacts).value(:bool).default(false)
  optional(:ignore_threshold).value(:integer).default(0)

  before(:key_coercer) do |result|
    # it looks like that dry-schema v1.9.1 has an issue with setting an array of schemas as a default value
    # e.g. optional(:emitters).value(:array).each { Emitter | HTTP }.default(DEFAULT_EMITTERS) does not work well
    # so let's do a dirty hack...
    h = result.to_h

    emitters = h[:emitters]
    h[:emitters] = emitters || DEFAULT_EMITTERS

    h
  end
end
Emitter =
Dry::Schema.Params do
  required(:emitter).value(Types::EmitterTypes)
end
MISP =
Dry::Schema.Params do
  required(:emitter).value(Types::String.enum("misp"))
  optional(:api_endpoint).value(:string)
  optional(:api_key).value(:string)
end
TheHive =
Dry::Schema.Params do
  required(:emitter).value(Types::String.enum("the_hive"))
  optional(:api_endpoint).value(:string)
  optional(:api_key).value(:string)
  optional(:api_version).value(Types::String.enum("v4", "v5")).default("v4")
end
Slack =
Dry::Schema.Params do
  required(:emitter).value(Types::String.enum("slack"))
  optional(:webhook_url).value(:string)
  optional(:channel).value(:string)
end
HTTP =
Dry::Schema.Params do
  required(:emitter).value(Types::String.enum("http"))
  required(:url).value(:string)
  optional(:http_request_method).value(Types::HTTPRequestMethods).default("POST")
  optional(:http_request_headers).value(:hash).default({})
  optional(:template).value(:string)
end
AnalyzerOptions =
Dry::Schema.Params do
  optional(:interval).value(:integer)
end
AnalyzerWithoutAPIKey =
Dry::Schema.Params do
  required(:analyzer).value(Types::String.enum("crtsh", "dnpedia", "dnstwister"))
  required(:query).value(:string)
  optional(:options).hash(AnalyzerOptions)
end
AnalyzerWithAPIKey =
Dry::Schema.Params do
  required(:analyzer).value(
    Types::String.enum(
      "binaryedge",
      "greynoise",
      "onyphe",
      "otx",
      "pulsedive",
      "securitytrails",
      "shodan",
      "st",
      "virustotal_intelligence",
      "virustotal",
      "vt_intel",
      "vt"
    )
  )
  required(:query).value(:string)
  optional(:api_key).value(:string)
  optional(:options).hash(AnalyzerOptions)
end
Censys =
Dry::Schema.Params do
  required(:analyzer).value(Types::String.enum("censys"))
  required(:query).value(:string)
  optional(:id).value(:string)
  optional(:secret).value(:string)
  optional(:options).hash(AnalyzerOptions)
end
CIRCL =
Dry::Schema.Params do
  required(:analyzer).value(Types::String.enum("circl"))
  required(:query).value(:string)
  optional(:username).value(:string)
  optional(:password).value(:string)
  optional(:options).hash(AnalyzerOptions)
end
PassiveTotal =
Dry::Schema.Params do
  required(:analyzer).value(Types::String.enum("passivetotal", "pt"))
  required(:query).value(:string)
  optional(:username).value(:string)
  optional(:api_key).value(:string)
  optional(:options).hash(AnalyzerOptions)
end
Spyse =
Dry::Schema.Params do
  required(:analyzer).value(Types::String.enum("spyse"))
  required(:query).value(:string)
  required(:type).value(Types::String.enum("ip", "domain"))
  optional(:options).hash(AnalyzerOptions)
end
ZoomEye =
Dry::Schema.Params do
  required(:analyzer).value(Types::String.enum("zoomeye"))
  required(:query).value(:string)
  required(:type).value(Types::String.enum("host", "web"))
  optional(:options).hash(AnalyzerOptions)
end
Crtsh =
Dry::Schema.Params do
  required(:analyzer).value(Types::String.enum("crtsh"))
  required(:query).value(:string)
  optional(:exclude_expired).value(:bool).default(true)
  optional(:options).hash(AnalyzerOptions)
end
Urlscan =
Dry::Schema.Params do
  required(:analyzer).value(Types::String.enum("urlscan"))
  required(:query).value(:string)
  optional(:options).hash(AnalyzerOptions)
end
Feed =
Dry::Schema.Params do
  required(:analyzer).value(Types::String.enum("feed"))
  required(:query).value(:string)
  required(:selector).value(:string)
  optional(:http_request_method).value(Types::HTTPRequestMethods).default("GET")
  optional(:http_request_headers).value(:hash).default({})
  optional(:http_request_payload).value(:hash).default({})
  optional(:http_request_payload_type).value(Types::HTTPRequestPayloadTypes)
  optional(:options).hash(AnalyzerOptions)
end