osakana 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|