mihari 1.5.1 → 2.0.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +41 -17
  3. data/README.md +13 -274
  4. data/build_frontend.sh +14 -0
  5. data/images/web_alerts.png +0 -0
  6. data/images/web_config.png +0 -0
  7. data/lib/mihari.rb +2 -2
  8. data/lib/mihari/cli.rb +12 -23
  9. data/lib/mihari/configurable.rb +4 -5
  10. data/lib/mihari/database.rb +8 -2
  11. data/lib/mihari/emitters/slack.rb +5 -5
  12. data/lib/mihari/models/alert.rb +51 -0
  13. data/lib/mihari/serializers/alert.rb +1 -1
  14. data/lib/mihari/serializers/artifact.rb +1 -1
  15. data/lib/mihari/serializers/tag.rb +1 -1
  16. data/lib/mihari/status.rb +10 -10
  17. data/lib/mihari/version.rb +1 -1
  18. data/lib/mihari/web/app.rb +126 -0
  19. data/lib/mihari/web/public/index.html +21 -0
  20. data/lib/mihari/web/public/static/favicon.ico +0 -0
  21. data/lib/mihari/web/public/static/fonts/fa-brands-400.099a9556.woff +0 -0
  22. data/lib/mihari/web/public/static/fonts/fa-brands-400.30cc681d.eot +0 -0
  23. data/lib/mihari/web/public/static/fonts/fa-brands-400.3b89dd10.ttf +0 -0
  24. data/lib/mihari/web/public/static/fonts/fa-brands-400.f7307680.woff2 +0 -0
  25. data/lib/mihari/web/public/static/fonts/fa-regular-400.1f77739c.ttf +0 -0
  26. data/lib/mihari/web/public/static/fonts/fa-regular-400.7124eb50.woff +0 -0
  27. data/lib/mihari/web/public/static/fonts/fa-regular-400.7630483d.eot +0 -0
  28. data/lib/mihari/web/public/static/fonts/fa-regular-400.f0f82301.woff2 +0 -0
  29. data/lib/mihari/web/public/static/fonts/fa-solid-900.1042e8ca.eot +0 -0
  30. data/lib/mihari/web/public/static/fonts/fa-solid-900.605ed792.ttf +0 -0
  31. data/lib/mihari/web/public/static/fonts/fa-solid-900.9fe5a17c.woff +0 -0
  32. data/lib/mihari/web/public/static/fonts/fa-solid-900.e8a427e1.woff2 +0 -0
  33. data/lib/mihari/web/public/static/img/fa-brands-400.ba7ed552.svg +3717 -0
  34. data/lib/mihari/web/public/static/img/fa-regular-400.0bb42845.svg +801 -0
  35. data/lib/mihari/web/public/static/img/fa-solid-900.376c1f97.svg +5034 -0
  36. data/lib/mihari/web/public/static/js/app.58b32d15.js +12 -0
  37. data/lib/mihari/web/public/static/js/app.58b32d15.js.map +1 -0
  38. data/mihari.gemspec +9 -3
  39. metadata +140 -20
  40. data/lib/mihari/alert_viewer.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 951201ccebc7b6c4c117a687c1abce9ab24fa8d450f5a0f0badeeececa6db5cb
4
- data.tar.gz: aed5f37c4031ffbc1a635ddd4fc979f4e40ab68a94ef880730bc48a2df600678
3
+ metadata.gz: 3cf190c27b1be3c0eeb690354361c3bb3295beb8609661a861fcc31e227cb7f0
4
+ data.tar.gz: e989209e3668e9342803ed1b91c9e668bcf0519e659f9fb88687cc38460818cb
5
5
  SHA512:
6
- metadata.gz: a81ff55bf880a3581ad52f6bf2d8652e1d7824119ed31daed81eb0e8f215d4d26a19a10d646b5497346e6795a320de18cd63fa817958081c2ba4393efad4c20a
7
- data.tar.gz: b3fa4c9979fc22863d0e171d87918c320ec177b5e27c0820f4997919cb714d8c19516d37e15eccaed8b0a81102498820b4865864dcb56c650c186ef1bd057b56
6
+ metadata.gz: 0a40de96264eaf211240b0020aa3494e6a64bddf8e2aa74461e91122fff29d72a5ab66032e226fa80c19c984fcb7a3e37d1e78aa0da317f6fd1445945b93d200
7
+ data.tar.gz: b0b55e75e84037cf7761fd28128504d45fc049de01d0f4db65184b2e8ff0e9bc3948e06b8165e90c19244fb1c8b8af33efa77d260bb323d4084d85e21f72245f
@@ -4,11 +4,10 @@ on: [pull_request]
4
4
 
5
5
  jobs:
6
6
  build:
7
-
8
7
  runs-on: ubuntu-latest
9
8
 
10
9
  services:
11
- db:
10
+ postgres:
12
11
  image: postgres:12
13
12
  env:
14
13
  POSTGRES_USER: postgres
@@ -22,23 +21,48 @@ jobs:
22
21
  ports:
23
22
  - 5432:5432
24
23
 
24
+ mysql:
25
+ image: mysql:8.0
26
+ env:
27
+ MYSQL_USER: mysql
28
+ MYSQL_PASSWORD: mysql
29
+ MYSQL_DATABASE: test
30
+ MYSQL_ROOT_PASSWORD: rootpassword
31
+ ports:
32
+ - 3306:3306
33
+ options: >-
34
+ --health-cmd="mysqladmin ping"
35
+ --health-interval=10s
36
+ --health-timeout=5s
37
+ --health-retries=3
38
+
25
39
  strategy:
26
40
  fail-fast: false
27
41
  matrix:
28
- ruby: [2.7, '3.0']
42
+ ruby: [2.7, "3.0"]
29
43
 
30
44
  steps:
31
- - uses: actions/checkout@v2
32
- - name: Set up Ruby 2.7
33
- uses: ruby/setup-ruby@v1
34
- with:
35
- ruby-version: ${{ matrix.ruby }}
36
- bundler-cache: true
37
- - name: Build and test with Rake
38
- env:
39
- DATABASE: postgresql://postgres:postgres@localhost:5432/test
40
- run: |
41
- sudo apt-get -yqq install libpq-dev
42
- gem install bundler
43
- bundle install
44
- bundle exec rake
45
+ - uses: actions/checkout@v2
46
+ - name: Set up Ruby 2.7
47
+ uses: ruby/setup-ruby@v1
48
+ with:
49
+ ruby-version: ${{ matrix.ruby }}
50
+ bundler-cache: true
51
+
52
+ - name: Install dependencies
53
+ run: |
54
+ sudo apt-get -yqq install libpq-dev libmysqlclient-dev
55
+ gem install bundler
56
+ bundle install
57
+
58
+ - name: Test with PostgreSQL
59
+ env:
60
+ DATABASE: postgresql://postgres:postgres@localhost:5432/test
61
+ run: |
62
+ bundle exec rake
63
+
64
+ - name: Test with MySQL
65
+ env:
66
+ DATABASE: mysql2://mysql:mysql@127.0.0.1:3306/test
67
+ run: |
68
+ bundle exec rake
data/README.md CHANGED
@@ -8,65 +8,22 @@
8
8
 
9
9
  ![img](https://github.com/ninoseki/mihari/raw/master/images/logo.png)
10
10
 
11
- Mihari is a helper to run queries & manage results continuously. Mihari can be used for C2, landing page and phishing hunting.
11
+ Mihari is a framework for continuous OSINT based threat hunting.
12
12
 
13
13
  ## How it works
14
14
 
15
- - Mihari makes a query against Shodan, Censys, VirusTotal, SecurityTrails, etc. and extracts artifacts (IP addresses, domains, URLs and hashes).
16
- - Mihari checks whether a DB (SQLite3 or PostgreSQL) contains the artifacts or not.
15
+ - Mihari makes a query against Shodan, Censys, VirusTotal, SecurityTrails, etc. and extracts artifacts (IP addresses, domains, URLs or hashes).
16
+ - Mihari checks whether a DB (SQLite3, PostgreSQL or MySQL) contains the artifacts or not.
17
17
  - If it doesn't contain the artifacts:
18
18
  - Mihari creates an alert on TheHive.
19
19
  - Mihari sends a notification to Slack.
20
20
  - Mihari creates an event on MISP.
21
21
 
22
- ![img](https://github.com/ninoseki/mihari/raw/master/images/eyecatch.png)
22
+ Also, you can check the alerts on a built-in web app.
23
23
 
24
- ### Screenshots
24
+ ![img](https://github.com/ninoseki/mihari/raw/master/images/web_alerts.png)
25
25
 
26
- - TheHive alert example
27
-
28
- ![img](https://github.com/ninoseki/mihari/raw/master/images/alert.png)
29
-
30
- - Slack notification example
31
-
32
- ![img](https://github.com/ninoseki/mihari/raw/master/images/slack.png)
33
-
34
- - MISP event example
35
-
36
- ![img](https://github.com/ninoseki/mihari/raw/master/images/misp.png)
37
-
38
- ## Requirements
39
-
40
- - Ruby (2.7 or 3.0)
41
- - SQLite3 or PostgreSQL
42
-
43
- ```bash
44
- # For Debian / Ubuntu
45
- apt-get install sqlite3 libsqlite3-dev libpq-dev
46
- ```
47
-
48
- ## Supported platforms & databases
49
-
50
- | Name | Supported versions |
51
- |------------|--------------------|
52
- | PostgreSQL | v12 |
53
- | SQLite | v3 |
54
- | MISP | v2.4 |
55
- | TheHive | v3.x & v4.x |
56
-
57
- ## Installation
58
-
59
- ```bash
60
- gem install mihari
61
- ```
62
-
63
- Or you can use this tool with Docker.
64
-
65
- ```bash
66
- docker pull ninoseki/mihari
67
- ```
68
-
69
- ## Basic usage
26
+ ## Supported services
70
27
 
71
28
  Mihari supports the following services by default.
72
29
 
@@ -87,233 +44,15 @@ Mihari supports the following services by default.
87
44
  - [VirusTotal](http://virustotal.com)
88
45
  - [ZoomEye](https://zoomeye.org)
89
46
 
90
- ```bash
91
- $ mihari
92
- Commands:
93
- mihari alerts # Show the alerts on TheHive
94
- mihari binaryedge [QUERY] # BinaryEdge host search by a query
95
- mihari censys [QUERY] # Censys IPv4 search by a query
96
- mihari circl [DOMAIN|SHA1] # CIRCL passive DNS/SSL lookup by a domain or SHA1 certificate fingerprint
97
- mihari crtsh [QUERY] # crt.sh search by a query
98
- mihari dnpedia [QUERY] # DNPedia domain search by a query
99
- mihari dnstwister [DOMAIN] # dnstwister lookup by a domain
100
- mihari free_text [TEXT] # Cross search with search engines by a free text
101
- mihari help [COMMAND] # Describe available commands or one specific command
102
- mihari http_hash # Cross search with search engines by a hash of an HTTP response (SHA256, MD5 and MurmurHash3)
103
- mihari import_from_json # Give a JSON input via STDIN
104
- mihari onyphe [QUERY] # Onyphe datascan search by a query
105
- mihari otx [IP|DOMAIN] # OTX lookup by an IP or domain
106
- mihari passive_dns [IP|DOMAIN] # Cross search with passive DNS services by an ip or domain
107
- mihari passive_ssl [SHA1] # Cross search with passive SSL services by an SHA1 certificate fingerprint
108
- mihari passivetotal [IP|DOMAIN|EMAIL|SHA1] # PassiveTotal lookup by an ip, domain, email or SHA1 certificate fingerprint
109
- mihari pulsedive [IP|DOMAIN] # Pulsedive lookup by an ip or domain
110
- mihari reverse_whois [EMAIL] # Cross search with reverse whois services by an email
111
- mihari securitytrails [IP|DOMAIN|EMAIL] # SecurityTrails lookup by an ip, domain or email
112
- mihari securitytrails_domain_feed [REGEXP] # SecurityTrails new domain feed search by a regexp
113
- mihari shodan [QUERY] # Shodan host search by a query
114
- mihari spyse [QUERY] # Spyse search by a query
115
- mihari ssh_fingerprint [FINGERPRINT] # Cross search with search engines by an SSH fingerprint (e.g. dc:14:de:8e:d7:c1:15:43:23:82:25:81:d2:59:e8:c0)
116
- mihari status # Show the current configuration status
117
- mihari urlscan [QUERY] # urlscan search by a given query
118
- mihari virustotal [IP|DOMAIN] # VirusTotal resolutions lookup by an ip or domain
119
- mihari zoomeye [QUERY] # ZoomEye search by a query
120
-
121
- Options:
122
- [--config=CONFIG] # path to config file
123
-
124
- ```
125
-
126
- ### Cross searches
127
-
128
- Mihari has cross search features. A cross search is a search across a number of services.
129
-
130
- You can get aggregated results by using the following commands.
131
-
132
- | Command | Desc. |
133
- |-----------------|---------------------------------------------------------------------------------------------------------|
134
- | passive_dns | Passive DNS lookup with CIRCL passive DNS, OTX, PassiveTotal, Pulsedive, SecurityTrails and VirusTotal |
135
- | passive_ssl | Passive SSL lookup with CIRCL passive SSL and PassiveTotal |
136
- | reverse_whois | Revese Whois lookup with PassiveTotal and SecurityTrails |
137
- | http_hash | HTTP response hash lookup with BinaryEdge(SHA256), Censys(SHA256), Onyphpe(MD5) and Shodan(MurmurHash3) |
138
- | free_text | Free text lookup with BinaryEdge and Censys |
139
- | ssh_fingerprint | SSH fingerprint lookup with BinaryEdge and Shodan |
140
-
141
- #### http_hash command
142
-
143
- The usage of `http_hash` command is a little bit tricky.
144
-
145
- ```bash
146
- $ mihari help http_hash
147
- Usage:
148
- mihari http_hash
149
-
150
- Options:
151
- [--title=TITLE] # title
152
- [--description=DESCRIPTION] # description
153
- [--tags=one two three] # tags
154
- [--md5=MD5] # MD5 hash
155
- [--sha256=SHA256] # SHA256 hash
156
- [--mmh3=N] # MurmurHash3 hash
157
-
158
- Cross search with search engines by a hash of an HTTP response (SHA256, MD5 and MurmurHash3)
159
-
160
- ```
161
-
162
- There are 2 ways to use this command.
163
-
164
- First one is passing `--md5`, `--sha256` and `--mmh3` parameters.
165
-
166
- ```bash
167
- mihari http_hash --md5=881191f7736b5b8cfad5959ca99d2a51 --sha256=b064187ebdc51721708ad98cd89dacc346017cb0fb0457d530032d387f1ff20e --mmh3=-1467534799
168
- ```
169
-
170
- Another one is passing `--html` parameter. In this case, hashes of an HTML file are automatically calculated.
171
-
172
- ```bash
173
- wget http://example.com -O /tmp/index.html
174
- mihari http_hash --html /tmp/index.html
175
- ```
176
-
177
- ### Example usages
178
-
179
- ```bash
180
- # Censys lookup for PANDA C2
181
- mihari censys '("PANDA" AND "SMAdmin" AND "layui")' --title "PANDA C2"
182
-
183
- # VirusTotal passive DNS lookup of a FAKESPY host
184
- mihari virustotal "jppost-hi.top" --title "FAKESPY passive DNS"
185
-
186
- # You can pass a "defanged" indicator as an input
187
- mihari virustotal "jppost-hi[.]top" --title "FAKESPY passive DNS"
188
- ```
189
-
190
- ### Import from JSON
191
-
192
- ```bash
193
- echo '{ "title": "test", "description": "test", "artifacts": ["1.1.1.1", "github.com", "2.2.2.2"] }' | mihari import_from_json
194
- ```
195
-
196
- The input is a JSON data should have `title`, `description` and `artifacts` key. `tags` key is an optional parameter.
197
-
198
- ```json
199
- {
200
- "title": "test",
201
- "description": "test",
202
- "artifacts": ["1.1.1.1", "github.com"],
203
- "tags": ["test"]
204
- }
205
- ```
206
-
207
- | Key | Desc. | Required or optional |
208
- |-------------|----------------------------------------------------------------------------|----------------------|
209
- | title | A title of an alert | Required |
210
- | description | A description of an alert | Required |
211
- | artifacts | An array of artifacts (supported data types: ip, domain, url, email, hash) | Required |
212
- | tags | An array of tags | Optional |
213
-
214
- ## Configuration
215
-
216
- Configuration can be done via environment variables or a YAML file.
217
-
218
- | Key | Description | Default |
219
- |------------------------|-------------------------------------------------------------------------------------------------|-------------|
220
- | DATABASE | A path to the SQLite database or a DB URL (e.g. `postgres://postgres:pass@db.host:5432/somedb`) | `mihari.db` |
221
- | BINARYEDGE_API_KEY | BinaryEdge API key | |
222
- | CENSYS_ID | Censys API ID | |
223
- | CENSYS_SECRET | Censys secret | |
224
- | CIRCL_PASSIVE_PASSWORD | CIRCL passive DNS/SSL password | |
225
- | CIRCL_PASSIVE_USERNAME | CIRCL passive DNS/SSL username | |
226
- | MISP_API_ENDPOINT | MISP URL | |
227
- | MISP_API_KEY | MISP API key | |
228
- | ONYPHE_API_KEY | Onyphe API key | |
229
- | OTX_API_KEY | OTX API key | |
230
- | PASSIVETOTAL_API_KEY | PassiveTotal API key | |
231
- | PASSIVETOTAL_USERNAME | PassiveTotal username | |
232
- | PULSEDIVE_API_KEY | Pulsedive API key | |
233
- | SECURITYTRAILS_API_KEY | SecurityTrails API key | |
234
- | SHODAN_API_KEY | Shodan API key | |
235
- | SLACK_CHANNEL | Slack channel name | `#general` |
236
- | SLACK_WEBHOOK_URL | Slack Webhook URL | |
237
- | SPYSE_API_KEY | Spyse API key | |
238
- | THEHIVE_API_ENDPOINT | TheHive URL | |
239
- | THEHIVE_API_KEY | TheHive API key | |
240
- | URLSCAN_API_KEY | urlscan.io API key | |
241
- | VIRUSTOTAL_API_KEY | VirusTotal API key | |
242
- | ZOOMEYE_PASSWORD | ZoomEye password | |
243
- | ZOOMEYE_USERNAMME | ZoomEye username | |
244
-
245
- Instead of using environment variables, you can use a YAML file for configuration.
246
-
247
- ```bash
248
- mihari virustotal 1.1.1.1 --config /path/to/yaml.yml
249
- ```
250
-
251
- The YAML file should be a YAML hash like below:
252
-
253
- ```yaml
254
- database: /tmp/mihari.db
255
- thehive_api_endpoint: https://localhost
256
- thehive_api_key: foo
257
- virustotal_api_key: foo
258
- ```
259
-
260
- You can check the configuration status via `status` command.
261
-
262
- ```bash
263
- mihari status
264
- ```
265
-
266
- ## How to create a custom script
267
-
268
- Create a class which extends `Mihari::Analyzers::Base` and implements the following methods.
269
-
270
- | Name | Desc. | @return | Required or optional |
271
- |----------------|----------------------------------------------------------------------------|---------------|----------------------|
272
- | `#title` | A title of an alert | String | Required |
273
- | `#description` | A description of an alert | String | Required |
274
- | `#artifacts` | An array of artifacts (supported data types: ip, domain, url, email, hash) | Array<String> | Required |
275
- | `#tags` | An array of tags | Array<String> | Optional |
276
-
277
- ```ruby
278
- require "mihari"
279
-
280
- module Mihari
281
- module Analyzers
282
- class Example < Base
283
- def title
284
- "example"
285
- end
286
-
287
- def description
288
- "example"
289
- end
290
-
291
- def artifacts
292
- ["9.9.9.9", "example.com"]
293
- end
294
-
295
- def tags
296
- ["example"]
297
- end
298
- end
299
- end
300
- end
301
-
302
- example = Mihari::Analyzers::Example.new
303
- example.run
304
- ```
305
-
306
- See `/examples` for more.
47
+ See [Usage](https://github.com/ninoseki/mihari/wiki/Usage) for more information.
307
48
 
308
- ## Using it with Docker
49
+ ## Docs
309
50
 
310
- ```bash
311
- $ docker run --rm ninoseki/mihari
312
- # Note that you should pass configurations via environment variables
313
- $ docker run --rm ninoseki/mihari -e THEHIVE_API_ENDPOINT="http://THEHIVE_URL" -e THEHIVE_API_KEY="API KEY" mihari
314
- # or
315
- $ docker run --rm ninoseki/mihari --env-file ~/.mihari.env mihari
316
- ```
51
+ - [Requirements & Installation](https://github.com/ninoseki/mihari/wiki/Requirements-&-Installation)
52
+ - [Usage](https://github.com/ninoseki/mihari/wiki/Usage)
53
+ - [Configuration](https://github.com/ninoseki/mihari/wiki/Configuration)
54
+ - [Custom script](https://github.com/ninoseki/mihari/wiki/Custom-script)
55
+ - [Docker](https://github.com/ninoseki/mihari/wiki/Docker)
317
56
 
318
57
  ## License
319
58
 
data/build_frontend.sh ADDED
@@ -0,0 +1,14 @@
1
+ #!/bin/sh
2
+
3
+ CURRENT_DIR=${PWD}
4
+
5
+ mkdir -p tmp
6
+ cd tmp
7
+ git clone https://github.com/ninoseki/mihari-frontend.git
8
+ cd mihari-frontend
9
+ npm install
10
+ npm run build
11
+
12
+ cp -r dist/* ${CURRENT_DIR}/lib/mihari/web/public
13
+
14
+ rm -rf ${CURRENT_DIR}/tmp/mihari-frontend
Binary file
Binary file
data/lib/mihari.rb CHANGED
@@ -79,8 +79,8 @@ require "mihari/emitters/slack"
79
79
  require "mihari/emitters/stdout"
80
80
  require "mihari/emitters/the_hive"
81
81
 
82
- require "mihari/alert_viewer"
83
-
84
82
  require "mihari/status"
85
83
 
84
+ require "mihari/web/app"
85
+
86
86
  require "mihari/cli"
data/lib/mihari/cli.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "thor"
4
3
  require "json"
4
+ require "rack/builder"
5
+ require "rack/handler/webrick"
6
+ require "thor"
5
7
 
6
8
  module Mihari
7
9
  class CLI < Thor
@@ -275,34 +277,21 @@ module Mihari
275
277
  end
276
278
  end
277
279
 
278
- desc "alerts", "Show the alerts on TheHive"
279
- method_option :limit, type: :string, default: "5", desc: "Number of alerts to show (or 'all' to show all the alerts)"
280
- method_option :title, type: :string, desc: "Title to filter"
281
- method_option :source, type: :string, desc: "Source to filter"
282
- method_option :tag, type: :string, desc: "Tag to filter"
283
- def alerts
284
- with_error_handling do
285
- load_configuration
280
+ desc "web", "Launch the web app"
281
+ method_option :port, type: :numeric, default: 9292
282
+ method_option :host, type: :string, default: "localhost"
283
+ def web
284
+ port = options["port"].to_i || 9292
285
+ host = options["host"] || "localhost"
286
286
 
287
- viewer = AlertViewer.new
288
- alerts = viewer.list(limit: options["limit"], title: options["title"], source: options["source"], tag: options[:tag])
289
- puts JSON.pretty_generate(alerts)
290
- end
291
- end
292
-
293
- desc "status", "Show the current configuration status"
294
- def status
295
- with_error_handling do
296
- load_configuration
297
-
298
- puts JSON.pretty_generate(Status.check)
299
- end
287
+ load_configuration
288
+ Mihari::App.run!(port: port, host: host)
300
289
  end
301
290
 
302
291
  no_commands do
303
292
  def with_error_handling
304
293
  yield
305
- rescue => e
294
+ rescue StandardError => e
306
295
  notifier = Notifiers::ExceptionNotifier.new
307
296
  notifier.notify e
308
297
  end