mihari 1.5.1 → 2.0.0

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