osakana 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21f7bc97c893c14d7c702ab8867c7ce63144f5c4cdb54f019e9c8fa99393e3b8
4
- data.tar.gz: 3d41bfebf99474b4e9176b8dd2218e3febfa3a106ab70fb1e287de3650683733
3
+ metadata.gz: e16910b5733fad0a62fd5334ea405cda967abf3a8bce51042785a586340f049d
4
+ data.tar.gz: 171eff5ae67aa6030407e8ea4d34d2b3f38d592ebdb9992224ac4ce03b96b1d4
5
5
  SHA512:
6
- metadata.gz: 7582cf02d5e62690d0b5db05aaf2eacc3360b6f9f53380ff4eec99701a00069bc673d0f4a65bfd0eb93fb759237ac820ec3bb576e0ade9362357d9a620f935be
7
- data.tar.gz: 3c5d87e8746db988fcc29d67ee72c1907b982f714e8895080b1a0883c7d80f8913e653bd28db3955a0aa0f3aa785ddfa65e7a76bd11ff0ecfc180053d56122fd
6
+ metadata.gz: f8cc4687b7b665b65bc92ad4bf2506d57c71620b479ed1f62b14d4c5f685baa82763ae2d3f62d335196b5202e214cd1713e3318b0600d86a95f0c90fac0b545a
7
+ data.tar.gz: 7d883c02582709a28aa762550dd3ec93a4ab3756137f90df3e2b016c13adaab64e0d4997db9a8f989c2479c34650782a03cfb868aa70236ed9e707d8507e8297
data/README.md CHANGED
@@ -8,10 +8,16 @@ Osakana is a Swiss army knife tool for my phishing research.
8
8
 
9
9
  ## Features
10
10
 
11
- - [Ayashige](https://github.com/ninoseki/ayashige) lookup
12
- - Censys lookup
13
- - Check newly registered domains on DNPedia by keyword
14
- - Slack integration
11
+ - Lookup supports:
12
+ - [Ayashige](https://github.com/ninoseki/ayashige) lookup
13
+ - Censys lookup
14
+ - DNPedia (newly registered domains) lookup
15
+ - urlscan.io lookup
16
+ - IoC enrichment:
17
+ - SecurityTrails integration (an API Key is required)
18
+ - Robtex integration
19
+ - Notification:
20
+ - Slack notification
15
21
 
16
22
  ## Prerequisites
17
23
 
@@ -32,6 +38,7 @@ Commands:
32
38
  osakana censys_lookup [QUERY] # lookup on Censys by a given query
33
39
  osakana check_newly_domains [KEYWORD] # check newly registered domains on DNPedia by a given keyword
34
40
  osakana help [COMMAND] # Describe available commands or one specific command
41
+ osakana urlscan_lookup [QUERY] # look up on urlscan.io by a given query
35
42
  ```
36
43
 
37
44
  ## Configuration
@@ -40,15 +47,21 @@ Commands:
40
47
 
41
48
  Please set the following environmental variables for enabling Censys lookup.
42
49
 
43
- - CENSYS_ID: your Censys API ID
44
- - CENSYS_SECRET: your Censys secret key
50
+ - `CENSYS_ID`: your Censys API ID
51
+ - `CENSYS_SECRET`: your Censys secret key
52
+
53
+ ### SecurityTrails
54
+
55
+ Please set the following environmental variable for enabling SecurityTrails integration.
56
+
57
+ - `SECURITYTRAILS_API_KEY`: your SecurityTrails API key
45
58
 
46
59
  ### Slack
47
60
 
48
- Please set the following environmental variables for enabling Slack integration.
61
+ Please set the following environmental variables for enabling Slack notification.
49
62
 
50
- - SLACK_WEBHOOK_URL: A Slack webhook URL.
51
- - SLACK_CHANNEL_NAME: A Slask channel name which will be notified.
63
+ - `SLACK_WEBHOOK_URL`: A Slack webhook URL.
64
+ - `SLACK_CHANNEL_NAME`: A Slask channel name which will be notified.
52
65
 
53
66
  ## Screenshots
54
67
 
@@ -2,11 +2,17 @@
2
2
 
3
3
  require "osakana/version"
4
4
 
5
+ require "osakana/enrichers/base"
6
+ require "osakana/enrichers/robtex"
7
+ require "osakana/enrichers/securitytrails"
8
+ require "osakana/enrichers/enricher"
9
+
5
10
  require "osakana/website"
6
11
 
7
12
  require "osakana/ayashige"
8
13
  require "osakana/censys"
9
14
  require "osakana/dnpedia"
15
+ require "osakana/urlscan"
10
16
 
11
17
  require "osakana/notifier"
12
18
  require "osakana/monitor"
@@ -19,6 +19,12 @@ module Osakana
19
19
  Monitor.ayashige_lookup(keyword)
20
20
  end
21
21
 
22
+ desc "urlscan_lookup [QUERY]", "look up on urlscan.io by a given query"
23
+ option :size, type: :numeric, default: 100
24
+ def urlscan_lookup(query)
25
+ Monitor.urlscan_lookup(query, size: options.dig("size"))
26
+ end
27
+
22
28
  no_commands do
23
29
  def with_error_handling
24
30
  yield
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Osakana
4
+ module Enrichers
5
+ class Base
6
+ def domain_to_ipv4(_domain)
7
+ raise NotImplementedError, "You must implement #{self.class}##{__method__}"
8
+ end
9
+
10
+ def ipv4_to_domain(_ipv4)
11
+ raise NotImplementedError, "You must implement #{self.class}##{__method__}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Osakana
4
+ module Enrichers
5
+ class Enricher < Base
6
+ def initialize
7
+ @enrichers = [SecurityTrails.new, Robtex.new]
8
+ end
9
+
10
+ def ipv4_to_domain(ipv4)
11
+ @enrichers.each do |enricher|
12
+ return enricher.ipv4_to_domain(ipv4)
13
+ rescue ArgumentError, ::SecurityTrails::Error, ::Robtex::ResponseError, URI::InvalidURIError => _
14
+ next
15
+ end
16
+ nil
17
+ end
18
+
19
+ def domain_to_ipv4(domain)
20
+ @enrichers.each do |enricher|
21
+ return enricher.domain_to_ipv4(domain)
22
+ rescue ArgumentError, ::SecurityTrails::Error, ::Robtex::ResponseError => _
23
+ next
24
+ end
25
+ nil
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "robtex"
4
+
5
+ module Osakana
6
+ module Enrichers
7
+ class Robtex < Base
8
+ def api
9
+ @api ||= ::Robtex::API.new
10
+ end
11
+
12
+ def domain_to_ipv4(domain)
13
+ results = api.fpdns(domain)
14
+ result = results.find do |res|
15
+ res.dig("rrtype") == "A"
16
+ end
17
+ result&.dig("rrdata")
18
+ end
19
+
20
+ def ipv4_to_domain(ipv4)
21
+ res = api.ip(ipv4)
22
+ active = res.dig("act")
23
+ active&.first&.dig("o")
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securitytrails"
4
+
5
+ module Osakana
6
+ module Enrichers
7
+ class SecurityTrails < Base
8
+ def api
9
+ @api ||= ::SecurityTrails::API.new
10
+ end
11
+
12
+ def domain_to_ipv4(domain)
13
+ res = api.history.get_dns_history(domain, "a")
14
+ res&.records&.first&.values&.first&.ip
15
+ end
16
+
17
+ def ipv4_to_domain(ipv4)
18
+ res = api.domains.search( filter: { ipv4: ipv4 })
19
+ res&.records&.first&.hostname
20
+ end
21
+ end
22
+ end
23
+ end
@@ -19,5 +19,11 @@ module Osakana
19
19
  attachements = websites.map(&:to_attachement)
20
20
  Notifier.notify("Ayashige keyword: #{keyword}", attachements)
21
21
  end
22
+
23
+ def self.urlscan_lookup(query, size:)
24
+ websites = Urlscan.lookup(query, size: size)
25
+ attachements = websites.map(&:to_attachement)
26
+ Notifier.notify("urlscan.io query: #{query}", attachements)
27
+ end
22
28
  end
23
29
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "http"
4
+ require "json"
5
+
6
+ module Osakana
7
+ class Urlscan
8
+ BASE_URL = "https://urlscan.io/api/v1/search/"
9
+
10
+ def lookup(query, size: 100)
11
+ res = HTTP.get(BASE_URL, params: { q: query, size: size })
12
+ return [] unless res.code == 200
13
+
14
+ websites = []
15
+ json = JSON.parse(res.body.to_s)
16
+ results = json.dig("results") || []
17
+ results.each do |item|
18
+ domain = item.dig("page", "domain")
19
+ ipv4 = item.dig("page", "ip")
20
+ time = item.dig("task", "time")
21
+
22
+ websites << Website.new(domain: domain, ipv4: ipv4, date: time)
23
+ end
24
+ websites
25
+ end
26
+
27
+ def self.lookup(query, size: 100)
28
+ new.lookup(query, size: size)
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Osakana
4
- VERSION = "0.2.1"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "date"
4
- require "robtex"
5
4
 
6
5
  module Osakana
7
6
  class Website
@@ -16,29 +15,18 @@ module Osakana
16
15
  @domain = domain
17
16
  @date = date ? DateTime.parse(date).to_date.to_s : "N/A"
18
17
 
19
- @robtex = Robtex::API.new
18
+ @enricher = Enrichers::Enricher.new
20
19
  end
21
20
 
22
21
  def domain
23
22
  @domain ||= [].tap do |out|
24
- res = @robtex.ip(ipv4)
25
- active = res.dig("act")
26
- next unless active
27
- next if active.empty?
28
-
29
- out << active.first.dig("o")
23
+ out << @enricher.ipv4_to_domain(ipv4)
30
24
  end.first || "N/A"
31
25
  end
32
26
 
33
27
  def ipv4
34
28
  @ipv4 ||= [].tap do |out|
35
- results = @robtex.fpdns(domain)
36
- result = results.find do |res|
37
- res.dig("rrtype") == "A"
38
- end
39
- next unless result
40
-
41
- out << result.dig("rrdata")
29
+ out << @enricher.domain_to_ipv4(domain)
42
30
  end.first || "N/A"
43
31
  end
44
32
 
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency "censu", "~> 0.2"
35
35
  spec.add_dependency "http", "~> 4.0"
36
36
  spec.add_dependency "robtex", "~> 0.1"
37
+ spec.add_dependency "securitytrails", "~> 0.1"
37
38
  spec.add_dependency "slack-incoming-webhooks", "~> 0.2"
38
39
  spec.add_dependency "thor", "~> 0.19"
39
40
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: osakana
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manabu Niseki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-22 00:00:00.000000000 Z
11
+ date: 2019-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0.1'
139
+ - !ruby/object:Gem::Dependency
140
+ name: securitytrails
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.1'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.1'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: slack-incoming-webhooks
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -187,8 +201,13 @@ files:
187
201
  - lib/osakana/censys.rb
188
202
  - lib/osakana/cli.rb
189
203
  - lib/osakana/dnpedia.rb
204
+ - lib/osakana/enrichers/base.rb
205
+ - lib/osakana/enrichers/enricher.rb
206
+ - lib/osakana/enrichers/robtex.rb
207
+ - lib/osakana/enrichers/securitytrails.rb
190
208
  - lib/osakana/monitor.rb
191
209
  - lib/osakana/notifier.rb
210
+ - lib/osakana/urlscan.rb
192
211
  - lib/osakana/version.rb
193
212
  - lib/osakana/website.rb
194
213
  - osakana.gemspec