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 +4 -4
- data/README.md +22 -9
- data/lib/osakana.rb +6 -0
- data/lib/osakana/cli.rb +6 -0
- data/lib/osakana/enrichers/base.rb +15 -0
- data/lib/osakana/enrichers/enricher.rb +29 -0
- data/lib/osakana/enrichers/robtex.rb +27 -0
- data/lib/osakana/enrichers/securitytrails.rb +23 -0
- data/lib/osakana/monitor.rb +6 -0
- data/lib/osakana/urlscan.rb +31 -0
- data/lib/osakana/version.rb +1 -1
- data/lib/osakana/website.rb +3 -15
- data/osakana.gemspec +1 -0
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e16910b5733fad0a62fd5334ea405cda967abf3a8bce51042785a586340f049d
|
4
|
+
data.tar.gz: 171eff5ae67aa6030407e8ea4d34d2b3f38d592ebdb9992224ac4ce03b96b1d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
-
|
12
|
-
-
|
13
|
-
-
|
14
|
-
-
|
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
|
44
|
-
- CENSYS_SECRET
|
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
|
61
|
+
Please set the following environmental variables for enabling Slack notification.
|
49
62
|
|
50
|
-
- SLACK_WEBHOOK_URL
|
51
|
-
- SLACK_CHANNEL_NAME
|
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
|
|
data/lib/osakana.rb
CHANGED
@@ -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"
|
data/lib/osakana/cli.rb
CHANGED
@@ -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
|
data/lib/osakana/monitor.rb
CHANGED
@@ -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
|
data/lib/osakana/version.rb
CHANGED
data/lib/osakana/website.rb
CHANGED
@@ -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
|
-
@
|
18
|
+
@enricher = Enrichers::Enricher.new
|
20
19
|
end
|
21
20
|
|
22
21
|
def domain
|
23
22
|
@domain ||= [].tap do |out|
|
24
|
-
|
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
|
-
|
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
|
|
data/osakana.gemspec
CHANGED
@@ -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.
|
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-
|
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
|