mihari 3.9.2 → 3.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c12a4ec4b0c1eee79deba3e5f3a511edcea4a13d7d72dc8142dbd85821095f55
4
- data.tar.gz: 4a1e388e55efff4b715caf2261990e6122afd4eb26aca0874a33d3025a16ba5b
3
+ metadata.gz: c4d53239fe8be60cdc674dc22c14f801147a71144649cec83f4fd3caaf2c99fa
4
+ data.tar.gz: 71b9b3746164b1f3eec9b98a807a6940e85a9184991efd7dd9abe5bd9b3f3578
5
5
  SHA512:
6
- metadata.gz: 8ead20235892bf77e222eff200f25539ffdd68cd21d14c5000d9196e518b9d2da2b461a2fe5d3dae4bc4bd899fb210f5f75b6330afad61826bc84dcfe40af23f
7
- data.tar.gz: 4b5679794091a79adb426ef34c5396819c702d67ad84791dec1430eba0f007d1dcab5f7defc53b5dab06e8a0e174963c777fb05606f79a5f16c4377f07847f75
6
+ metadata.gz: 6bee10443bd55e0ac483e8495c508bcce95dc56073aeb99f6c1566f38fb73707140baa838c07212c39795017d109aef8e9478f560bc3d04a21cbb949a48c9b61
7
+ data.tar.gz: c35f757168a737c37dcbf9a54d0408eabdfbf807a7a57db77c59c10f9a5b803d6731c615f3360db93b05647ee5e6cdcd35518baf4a7a7efe8d73e198d7f2664e
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "greynoise"
4
+
5
+ module Mihari
6
+ module Analyzers
7
+ class GreyNoise < Base
8
+ param :query
9
+ option :title, default: proc { "GreyNoise search" }
10
+ option :description, default: proc { "query = #{query}" }
11
+ option :tags, default: proc { [] }
12
+
13
+ def artifacts
14
+ res = Structs::GreyNoise::Response.from_dynamic!(search)
15
+ res.data.map do |datum|
16
+ build_artifact datum
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ PAGE_SIZE = 10_000
23
+
24
+ def configuration_keys
25
+ %w[greynoise_api_key]
26
+ end
27
+
28
+ def api
29
+ @api ||= ::GreyNoise::API.new(key: Mihari.config.greynoise_api_key)
30
+ end
31
+
32
+ #
33
+ # Search
34
+ #
35
+ # @return [Hash]
36
+ #
37
+ def search
38
+ api.experimental.gnql(query, size: PAGE_SIZE)
39
+ end
40
+
41
+ #
42
+ # Build an artifact from a GreyNoise search API response
43
+ #
44
+ # @param [Structs::GreyNoise::Datum] datum
45
+ #
46
+ # @return [Artifact]
47
+ #
48
+ def build_artifact(datum)
49
+ as = AutonomousSystem.new(asn: normalize_asn(datum.metadata.asn))
50
+
51
+ geolocation = Geolocation.new(
52
+ country: datum.metadata.country,
53
+ country_code: datum.metadata.country_code
54
+ )
55
+
56
+ Artifact.new(
57
+ data: datum.ip,
58
+ source: source,
59
+ autonomous_system: as,
60
+ geolocation: geolocation
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end
@@ -11,6 +11,7 @@ module Mihari
11
11
  "crtsh" => Crtsh,
12
12
  "dnpedia" => DNPedia,
13
13
  "dnstwister" => DNSTwister,
14
+ "greynoise" => GreyNoise,
14
15
  "onyphe" => Onyphe,
15
16
  "otx" => OTX,
16
17
  "passivetotal" => PassiveTotal,
@@ -78,7 +78,9 @@ module Mihari
78
78
  # @return [Artifact]
79
79
  #
80
80
  def build_artifact(match)
81
- as = AutonomousSystem.new(asn: normalize_asn(match.asn))
81
+ as = nil
82
+ as = AutonomousSystem.new(asn: normalize_asn(match.asn)) unless match.asn.nil?
83
+
82
84
  geolocation = Geolocation.new(
83
85
  country: match.location.country_name,
84
86
  country_code: match.location.country_code
@@ -6,6 +6,7 @@ require "mihari/commands/circl"
6
6
  require "mihari/commands/crtsh"
7
7
  require "mihari/commands/dnpedia"
8
8
  require "mihari/commands/dnstwister"
9
+ require "mihari/commands/greynoise"
9
10
  require "mihari/commands/onyphe"
10
11
  require "mihari/commands/otx"
11
12
  require "mihari/commands/passivetotal"
@@ -33,6 +34,7 @@ module Mihari
33
34
  include Mihari::Commands::Crtsh
34
35
  include Mihari::Commands::DNPedia
35
36
  include Mihari::Commands::DNSTwister
37
+ include Mihari::Commands::GreyNoise
36
38
  include Mihari::Commands::JSON
37
39
  include Mihari::Commands::Onyphe
38
40
  include Mihari::Commands::OTX
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ module Commands
5
+ module GreyNoise
6
+ def self.included(thor)
7
+ thor.class_eval do
8
+ desc "greynoise [QUERY]", "GreyNoise search"
9
+ method_option :title, type: :string, desc: "title"
10
+ method_option :description, type: :string, desc: "description"
11
+ method_option :tags, type: :array, desc: "tags"
12
+ def greynoise(query)
13
+ with_error_handling do
14
+ run_analyzer Analyzers::GreyNoise, query: query, options: options
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -13,6 +13,8 @@ module Mihari
13
13
  optional(:censys_secret).value(:string)
14
14
  optional(:circl_passive_password).value(:string)
15
15
  optional(:circl_passive_username).value(:string)
16
+ optional(:database).value(:string)
17
+ optional(:greynoise_api_key).value(:string)
16
18
  optional(:ipinfo_api_key).value(:string)
17
19
  optional(:misp_api_endpoint).value(:string)
18
20
  optional(:misp_api_key).value(:string)
@@ -30,10 +32,9 @@ module Mihari
30
32
  optional(:thehive_api_key).value(:string)
31
33
  optional(:urlscan_api_key).value(:string)
32
34
  optional(:virustotal_api_key).value(:string)
33
- optional(:zoomeye_api_key).value(:string)
34
35
  optional(:webhook_url).value(:string)
35
36
  optional(:webhook_use_json_body).value(:bool)
36
- optional(:database).value(:string)
37
+ optional(:zoomeye_api_key).value(:string)
37
38
  end
38
39
 
39
40
  class ConfigurationContract < Dry::Validation::Contract
@@ -0,0 +1,55 @@
1
+ require "json"
2
+ require "dry/struct"
3
+
4
+ module Mihari
5
+ module Structs
6
+ module GreyNoise
7
+ class Metadata < Dry::Struct
8
+ attribute :country, Types::String
9
+ attribute :country_code, Types::String
10
+ attribute :asn, Types::String
11
+
12
+ def self.from_dynamic!(d)
13
+ d = Types::Hash[d]
14
+ new(
15
+ country: d.fetch("country"),
16
+ country_code: d.fetch("country_code"),
17
+ asn: d.fetch("asn")
18
+ )
19
+ end
20
+ end
21
+
22
+ class Datum < Dry::Struct
23
+ attribute :ip, Types::String
24
+ attribute :metadata, Metadata
25
+
26
+ def self.from_dynamic!(d)
27
+ d = Types::Hash[d]
28
+ new(
29
+ ip: d.fetch("ip"),
30
+ metadata: Metadata.from_dynamic!(d.fetch("metadata"))
31
+ )
32
+ end
33
+ end
34
+
35
+ class Response < Dry::Struct
36
+ attribute :complete, Types::Bool
37
+ attribute :count, Types::Int
38
+ attribute :data, Types.Array(Datum)
39
+ attribute :message, Types::String
40
+ attribute :query, Types::String
41
+
42
+ def self.from_dynamic!(d)
43
+ d = Types::Hash[d]
44
+ new(
45
+ complete: d.fetch("complete"),
46
+ count: d.fetch("count"),
47
+ data: d.fetch("data").map { |x| Datum.from_dynamic!(x) },
48
+ message: d.fetch("message"),
49
+ query: d.fetch("query")
50
+ )
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -18,7 +18,7 @@ module Mihari
18
18
  end
19
19
 
20
20
  class Match < Dry::Struct
21
- attribute :asn, Types::String
21
+ attribute :asn, Types::String.optional
22
22
  attribute :hostnames, Types.Array(Types::String)
23
23
  attribute :location, Location
24
24
  attribute :domains, Types.Array(Types::String)
@@ -27,7 +27,7 @@ module Mihari
27
27
  def self.from_dynamic!(d)
28
28
  d = Types::Hash[d]
29
29
  new(
30
- asn: d.fetch("asn"),
30
+ asn: d["asn"],
31
31
  hostnames: d.fetch("hostnames"),
32
32
  location: Location.from_dynamic!(d.fetch("location")),
33
33
  domains: d.fetch("domains"),
data/lib/mihari/types.rb CHANGED
@@ -19,6 +19,7 @@ module Mihari
19
19
  "circl",
20
20
  "dnpedia",
21
21
  "dnstwister",
22
+ "greynoise",
22
23
  "onyphe",
23
24
  "otx",
24
25
  "passivetotal",
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "3.9.2"
4
+ VERSION = "3.10.0"
5
5
  end
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/static/favicon.ico"><title>Mihari</title><link href="/static/js/app.14008741.js" rel="preload" as="script"></head><body><noscript><strong>We're sorry but Mihari doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/app.14008741.js"></script></body></html>
1
+ <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/static/favicon.ico"><title>Mihari</title><link href="/static/js/app.0a0cc502.js" rel="preload" as="script"></head><body><noscript><strong>We're sorry but Mihari doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/app.0a0cc502.js"></script></body></html>