Compare commits

...

157 Commits

Author SHA1 Message Date
Robert Bongart (MSc MSc MA)
aa0233ad59
Merge pull request #18 from 2lambda123/dependabot/npm_and_yarn/app/backend/npm_and_yarn-ec7b19cc00
Bump the npm_and_yarn group across 2 directories with 10 updates
2024-06-29 06:49:54 +02:00
dependabot[bot]
be98df17b0
Bump the npm_and_yarn group across 2 directories with 10 updates
Bumps the npm_and_yarn group with 3 updates in the /app/backend directory: [shell-quote](https://github.com/ljharb/shell-quote), [ws](https://github.com/websockets/ws) and [y18n](https://github.com/yargs/y18n).
Bumps the npm_and_yarn group with 8 updates in the /app/frontend directory:

| Package | From | To |
| --- | --- | --- |
| [semver](https://github.com/npm/node-semver) | `5.7.1` | `5.7.2` |
| [async](https://github.com/caolan/async) | `2.6.3` | `2.6.4` |
| [qs](https://github.com/ljharb/qs) | `6.5.2` | `6.5.3` |
| [dns-packet](https://github.com/mafintosh/dns-packet) | `1.3.1` | `1.3.4` |
| [highlight.js](https://github.com/highlightjs/highlight.js) | `9.18.3` | `10.7.3` |
| [cli-highlight](https://github.com/felixfbecker/cli-highlight) | `2.1.4` | `2.1.11` |
| [minimist](https://github.com/minimistjs/minimist) | `1.2.5` | `1.2.8` |
| [shell-quote](https://github.com/ljharb/shell-quote) | `1.7.2` | `1.8.1` |



Updates `shell-quote` from 1.7.2 to 1.8.1
- [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/shell-quote/compare/v1.7.2...v1.8.1)

Updates `ws` from 6.2.1 to 6.2.3
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/6.2.1...6.2.3)

Updates `y18n` from 4.0.0 to 4.0.3
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/y18n-v4.0.3/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/compare/v4.0.0...y18n-v4.0.3)

Updates `semver` from 5.7.1 to 5.7.2
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2)

Updates `async` from 2.6.3 to 2.6.4
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.3...v2.6.4)

Updates `qs` from 6.5.2 to 6.5.3
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.5.2...v6.5.3)

Updates `dns-packet` from 1.3.1 to 1.3.4
- [Changelog](https://github.com/mafintosh/dns-packet/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mafintosh/dns-packet/compare/v1.3.1...v1.3.4)

Updates `highlight.js` from 9.18.3 to 10.7.3
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/10.7.3/CHANGES.md)
- [Commits](https://github.com/highlightjs/highlight.js/commits/10.7.3)

Updates `cli-highlight` from 2.1.4 to 2.1.11
- [Release notes](https://github.com/felixfbecker/cli-highlight/releases)
- [Commits](https://github.com/felixfbecker/cli-highlight/compare/v2.1.4...v2.1.11)

Updates `minimist` from 1.2.5 to 1.2.8
- [Changelog](https://github.com/minimistjs/minimist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/minimistjs/minimist/compare/v1.2.5...v1.2.8)

Updates `shell-quote` from 1.7.2 to 1.8.1
- [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/shell-quote/compare/v1.7.2...v1.8.1)

---
updated-dependencies:
- dependency-name: shell-quote
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: ws
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: y18n
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: semver
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: async
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: qs
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: dns-packet
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: highlight.js
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: cli-highlight
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: minimist
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: shell-quote
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-28 14:38:10 +00:00
Robert Bongart (MSc MSc MA)
daa3c0f165
Merge pull request #17 from 2lambda123/dependabot/npm_and_yarn/app/backend/npm_and_yarn-ecfa3dbf2e
Bump the npm_and_yarn group across 2 directories with 11 updates
2024-06-28 16:17:52 +02:00
dependabot[bot]
a44e61fe46
Bump the npm_and_yarn group across 2 directories with 11 updates
Bumps the npm_and_yarn group with 1 update in the /app/backend directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 11 updates in the /app/frontend directory:

| Package | From | To |
| --- | --- | --- |
| [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) | `7.11.5` | `7.24.7` |
| [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) | `0.2.0` | `0.2.2` |
| [elliptic](https://github.com/indutny/elliptic) | `6.5.3` | `6.5.5` |
| [eventsource](https://github.com/EventSource/eventsource) | `1.0.7` | `1.1.2` |
| [follow-redirects](https://github.com/follow-redirects/follow-redirects) | `1.13.0` | `1.15.6` |
| [json-schema](https://github.com/kriszyp/json-schema) | `0.2.3` | `0.4.0` |
| [jsprim](https://github.com/joyent/node-jsprim) | `1.4.1` | `1.4.2` |
| [lodash](https://github.com/lodash/lodash) | `4.17.20` | `4.17.21` |
| [url-parse](https://github.com/unshiftio/url-parse) | `1.4.7` | `1.5.10` |
| [ws](https://github.com/websockets/ws) | `6.2.1` | `6.2.3` |
| [y18n](https://github.com/yargs/y18n) | `4.0.0` | `4.0.3` |



Updates `lodash` from 4.17.20 to 4.17.21
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Updates `@babel/traverse` from 7.11.5 to 7.24.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.24.7/packages/babel-traverse)

Updates `decode-uri-component` from 0.2.0 to 0.2.2
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

Updates `elliptic` from 6.5.3 to 6.5.5
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.5)

Updates `eventsource` from 1.0.7 to 1.1.2
- [Changelog](https://github.com/EventSource/eventsource/blob/master/HISTORY.md)
- [Commits](https://github.com/EventSource/eventsource/compare/v1.0.7...v1.1.2)

Updates `follow-redirects` from 1.13.0 to 1.15.6
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.13.0...v1.15.6)

Updates `json-schema` from 0.2.3 to 0.4.0
- [Commits](https://github.com/kriszyp/json-schema/compare/v0.2.3...v0.4.0)

Updates `jsprim` from 1.4.1 to 1.4.2
- [Changelog](https://github.com/TritonDataCenter/node-jsprim/blob/v1.4.2/CHANGES.md)
- [Commits](https://github.com/joyent/node-jsprim/compare/v1.4.1...v1.4.2)

Updates `lodash` from 4.17.20 to 4.17.21
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Updates `url-parse` from 1.4.7 to 1.5.10
- [Commits](https://github.com/unshiftio/url-parse/compare/1.4.7...1.5.10)

Updates `ws` from 6.2.1 to 6.2.3
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/6.2.1...6.2.3)

Updates `y18n` from 4.0.0 to 4.0.3
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/y18n-v4.0.3/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/compare/v4.0.0...y18n-v4.0.3)

---
updated-dependencies:
- dependency-name: lodash
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: "@babel/traverse"
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: decode-uri-component
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: elliptic
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: eventsource
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: follow-redirects
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: json-schema
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: jsprim
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: url-parse
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: ws
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: y18n
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-28 11:16:40 +00:00
snorkell-ai[bot]
3ff9520114
snorkell_ai/config_54b37
main
2024-04-14 17:12:47 +00:00
Robert Bongart (MSc MSc MA)
cf5808cf71
Merge pull request #1 from 2lambda123/dependabot/pip/assets/pip-33fa3f9920
Bump the pip group across 1 directory with 2 updates
2024-04-14 11:59:46 -05:00
Robert Bongart (MSc MSc MA)
052ce4cd9c
Merge pull request #2 from 2lambda123/imgbot
[ImgBot] Optimize images
2024-04-14 11:59:41 -05:00
Robert Bongart (MSc MSc MA)
1eecd892f7
Merge pull request #9 from 2lambda123/ablesov/add_diagnostics_script
Added diagnostics script
2024-04-14 11:59:11 -05:00
Robert Bongart (MSc MSc MA)
f9be1daccb
Merge pull request #8 from 2lambda123/ablesov/fix_requirements
Update requirements.txt
2024-04-14 11:52:34 -05:00
Robert Bongart (MSc MSc MA)
6d0560c311
Merge pull request #6 from 2lambda123/ablesov/pwd_compare_fix
Update install.sh
2024-04-14 11:28:44 -05:00
Robert Bongart (MSc MSc MA)
dfdbff5100
Merge pull request #3 from 2lambda123/ablesov/fix_field_name
Fixed field mapping @ zeekengine.py
2024-04-14 11:16:37 -05:00
dependabot[bot]
e93a4c16de
Bump the pip group across 1 directory with 2 updates
Bumps the pip group with 2 updates in the /assets directory: [flask](https://github.com/pallets/flask) and [pyjwt](https://github.com/jpadilla/pyjwt).


Updates `flask` from 1.1.2 to 2.2.5
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/1.1.2...2.2.5)

Updates `pyjwt` from 1.7.1 to 2.4.0
- [Release notes](https://github.com/jpadilla/pyjwt/releases)
- [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/jpadilla/pyjwt/compare/1.7.1...2.4.0)

---
updated-dependencies:
- dependency-name: flask
  dependency-type: direct:production
  dependency-group: pip
- dependency-name: pyjwt
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-14 16:08:55 +00:00
ImgBotApp
bd2c567151
[ImgBot] Optimize images
*Total -- 5,245.48kb -> 4,078.69kb (22.24%)

/app/frontend/src/assets/icon.png -- 27.84kb -> 14.24kb (48.84%)
/assets/network-home.png -- 315.20kb -> 184.93kb (41.33%)
/app/backend/src/assets/network-home.png -- 314.77kb -> 185.00kb (41.23%)
/app/backend/src/assets/network.png -- 133.43kb -> 91.76kb (31.22%)
/assets/backend.png -- 775.25kb -> 540.26kb (30.31%)
/app/frontend/src/assets/logo.png -- 87.56kb -> 63.96kb (26.95%)
/assets/frontend.png -- 404.96kb -> 324.34kb (19.91%)
/app/frontend/src/assets/fonts/Roboto-Bold.svg -- 805.04kb -> 673.54kb (16.34%)
/app/backend/src/assets/fonts/Roboto-Bold.svg -- 805.04kb -> 673.54kb (16.34%)
/app/frontend/src/assets/fonts/Roboto-Regular.svg -- 784.41kb -> 660.24kb (15.83%)
/app/backend/src/assets/fonts/Roboto-Regular.svg -- 784.41kb -> 660.24kb (15.83%)
/app/backend/src/assets/github.png -- 4.17kb -> 3.52kb (15.51%)
/app/frontend/src/assets/loading.svg -- 1.21kb -> 1.05kb (13.12%)
/app/frontend/src/assets/icon_spinner.svg -- 0.95kb -> 0.85kb (9.9%)
/app/frontend/src/assets/icon_plug_usb.svg -- 0.29kb -> 0.27kb (4.42%)
/app/frontend/src/assets/icon_success.svg -- 0.37kb -> 0.35kb (3.71%)
/app/frontend/src/assets/icon_usb.svg -- 0.59kb -> 0.57kb (3.16%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>
2024-04-14 16:08:12 +00:00
Eugeny Ablesov
4f989dcd94
Fixed field mapping @ zeekengine.py (#143)
Fixed field mapping @ zeekengine.py: resp_h is destination host, please refer to https://docs.zeek.org/en/current/log-formats.html
2023-08-14 15:14:42 +03:00
Eugeny Ablesov
4e4c6172cd
Fixed field mapping @ zeekengine.py
Fixed field mapping @ zeekengine.py: resp_h is destination host, please refer to https://docs.zeek.org/en/current/log-formats.html
2023-08-14 15:14:00 +03:00
Eugeny Ablesov
9939dc3bf4
Added diagnostics script (#141) 2023-06-26 14:04:10 +03:00
Eugeny Ablesov
c3f09469b9
Added diagnostics script 2023-06-26 14:01:58 +03:00
Eugeny Ablesov
5091308d0b
Update install.sh (#140)
Fixed password comparison
2023-06-26 14:00:43 +03:00
Eugeny Ablesov
69512ba605
Update install.sh
Fixed password comparison
2023-06-26 14:00:12 +03:00
Eugeny Ablesov
0dafbf63a2
Update requirements.txt (#139)
Use only fixed versions for dependencies
2023-06-26 13:59:03 +03:00
Eugeny Ablesov
bd4ab27c21
Update requirements.txt
Use only fixed versions for dependencies
2023-06-26 13:57:42 +03:00
Tangui Morlier
bfbb76c55a
Update requirements.txt (#136)
Duplicated
2023-06-26 13:44:53 +03:00
Eugeny Ablesov
e2a040798a
Ablesov/fix tinycheck installation (#135)
* Update requirements.txt

Fix:
pymisp - use older version to keep code compatibility
sqlalchemy - use 1.4 latest build (api 2.0 incompatible with codebase)

M2Crypto - removed (not used)
pyOpenSSL - removed (not used)

* Update scheme.sql

pymisp warning fix

* Update main.py

Unused reference to pyOpenSSL removed
2023-05-30 15:20:09 +03:00
chebatory
7696f840c7
Merge pull request #124 from vollkorn1982/fix_failing_zeek_analysis
zeek 5.1.1-0 has a new logfile format, fixes #123
2023-01-11 15:55:59 +03:00
Jan Girlich
fae904ec48
zeek 5.1.1-0 has a new logfile format, fixes #123
The columns tx_host and rx_host have been renamed. This commit reflects the
name change and repairs the analysis process.
2022-12-18 15:37:48 +01:00
chebatory
52a705e0c7
Update README.md 2022-08-31 15:22:05 +03:00
chebatory
8012ab8c10
Merge pull request #107 from chenxiaoqino/main
Translation: Add Chinese translation
2022-08-22 17:57:53 +03:00
chebatory
1c3c2f1634
Merge pull request #109 from besendorf/patch-1
add all ipv6 multicast adresses to whitelist.json
2022-08-22 17:56:27 +03:00
chebatory
8e6617f0a1
Merge pull request #111 from Te-k/main
Update owner and url of the stalkerware IOC repository
2022-08-22 17:52:15 +03:00
chebatory
ff71f561ec
Update README.md 2022-08-22 17:51:54 +03:00
chebatory
dca4bdd4a7
Merge pull request #92 from chebatory/main
fixing permanent NO-Internet issue
2022-08-22 17:47:59 +03:00
tek
16fe644fcb Update owner and url of the stalkerware IOC repository 2022-08-08 21:21:49 +02:00
chebatory
403ddfc14f
Update config.yaml 2022-07-15 16:50:11 +03:00
chebatory
3dcbd89979
Merge branch 'main' into main 2022-07-15 16:48:28 +03:00
Victor Chebyshev
60e7009a65 fixing own bug with Slovak 2022-07-14 17:56:48 +03:00
Victor Chebyshev
77edcde21d Adding Slovak locale 2022-07-14 17:22:55 +03:00
Victor Chebyshev
87700adb4c switch from iptable to nftables 2022-07-14 15:59:52 +03:00
besendorf
5b607d47d7
add all ipv6 multicast adresses
I noticed some ff02:... addresses in my reports. Those should be whitelisted
ff00::/8 are all ipv6 multicast addresses. See rfc5156 2.13
2022-07-07 21:23:29 +02:00
Xiaoqi Chen
8d0f93ad33 [Translation] Add Chinese locale for frontend, cn.json 2022-07-06 00:51:11 -04:00
Xiaoqi Chen
19934f8279 [Translation] Add Chinese locale for reports, cn.json 2022-07-06 00:36:35 -04:00
Félix Aimé
ab3f5b584e
Update zeekengine.py 2022-06-04 23:14:43 +02:00
Félix Aimé
5cc0abcf83
Merge pull request #85 from besendorf/main
Change hardcoded paths make analysis.py usable standalone
2022-06-04 22:24:00 +02:00
felixaime
9bdcaf92cd Adding iptables install for new Raspbian OS 2022-06-04 22:07:39 +02:00
Félix Aimé
4059562f97
Merge pull request #84 from ranlo/ranlo-patch-1
Make the frontend port configurable
2022-06-04 22:04:32 +02:00
Félix Aimé
c7b54a50e1
Merge branch 'main' into ranlo-patch-1 2022-06-04 22:03:06 +02:00
Félix Aimé
7973c006d4
Merge pull request #82 from g-hartmann/patch-1
Fixes #81
2022-06-04 15:14:03 +02:00
Félix Aimé
ed6b94c8ec
Merge pull request #94 from PlazzmiK/patch-2
Thanks for your PR @PlazzmiK !
2022-06-04 14:47:25 +02:00
Dan
96290575af
Merge pull request #99 from Te-k/main
Updates the stalkerware IOC path
2022-05-04 18:12:29 +03:00
Dan
29054295e9
Merge pull request #100 from juliopovedacs/patch-1
Minor typo fix and pronoun change suggestion
2022-05-04 18:11:42 +03:00
Julio Poveda
b2bbb89baa
Minor typo fix and pronoun change suggestion 2022-04-22 15:26:34 -04:00
tek
bc98fa5d92 Updates IOC path 2022-04-12 10:39:30 +02:00
chebatory
c7e838385f some more fixes for Ubuntu (Suricata repository added) 2022-03-05 06:08:48 -08:00
chebatory
55bc816a67 one more Ubuntu install fix 2022-03-04 00:50:11 -08:00
chebatory
fcce3fe19d Ubuntu support added (dnsmasq issue workaround) 2022-03-04 00:22:56 -08:00
chebatory
2d5ae65847 Adding Debian support 2022-02-25 17:48:55 +03:00
PlazzmiK
ca980a74a3
Added six - Fixes issue #93
FIX for issue #93 :
ImportError: cannot import name 'collections_abc' from 'six.moves' (unkown location)
2022-02-16 20:14:51 +01:00
chebatory
6941655ab3 fixing permanent NO-Internet issue 2022-01-12 10:08:13 -05:00
Dan
a6fb73b87e
Merge pull request #86 from chebatory/npmpublic
Npmpublic
2021-10-27 15:15:48 +02:00
chebatory
59c5f8a45b fixing supply-chain attack vulnerability 2021-10-26 07:19:43 -04:00
chebatory
1c381f5b39 fixing supply-chain attack vulnerability 2021-10-26 06:34:27 -04:00
Janik Besendorf
c170ae2fb2 change hardcoded paths and introduce -f flag for calling analysis.py from frontende to skip device.json in report generation 2021-10-19 16:54:10 +02:00
ranlo
8da2a72df5
Update main.py 2021-09-28 12:52:54 +03:00
ranlo
c745f3ce34
Update main.py - configurable listen port
support configuration for listen port. Default to 80 if no configuration
2021-09-28 12:49:52 +03:00
ranlo
5c889cd0c6
Update config.yaml 2021-09-28 12:42:55 +03:00
ghartmann
14fec39371
Fixes #10 2021-08-31 13:36:19 +02:00
Félix Aimé
48539a13df
Merge pull request #75 from securechicken/watcherfix1
FIX watcher crash when remote file does not have a "to_delete" key
2021-08-05 09:27:27 +02:00
Félix Aimé
e582f5a3c2
Update iocs.json 2021-08-05 09:26:21 +02:00
securechicken
ed98061396 FIX uninit to_delete var exception 2021-07-22 16:26:25 +02:00
Félix Aimé
4b9413ba37
Update network.py 2021-06-15 18:20:31 +02:00
Félix Aimé
98bd7bab1a
Update hostapd.conf 2021-06-15 15:53:39 +02:00
Félix Aimé
08d24632a3
Update network.py 2021-06-15 15:51:42 +02:00
Félix Aimé
7c1b0f7ced
Merge pull request #74 from KasperskyLab/dev
PR of the version v0.7-test
2021-06-15 15:37:12 +02:00
Félix Aimé
09de9177d2
Update iocs-misp.vue 2021-06-15 14:54:44 +02:00
Félix Aimé
bd329c27cf
Update iocs-misp.vue 2021-06-14 17:16:08 +02:00
Félix Aimé
793a97b530
Merge pull request #73 from KasperskyLab/misp
Adding MISP support to dev
2021-06-14 16:07:03 +02:00
Félix Aime
920bd6785c Enchancing report.vue 2021-06-14 13:22:26 +02:00
Félix Aime
bbfbfc2e84 Adding the choose network option 2021-06-14 10:10:24 +02:00
Félix Aime
6f5fd11a26 Modifying iocs search to show the source 2021-06-11 17:15:12 +02:00
Félix Aime
22315277f3 Changing last synchronization value style 2021-06-11 16:27:10 +02:00
Félix Aime
601450d9fd Adding last sync tooltip 2021-06-11 15:45:57 +02:00
Félix Aime
b8bed722dc Merge branch 'misp' of https://github.com/KasperskyLab/TinyCheck into misp 2021-06-11 14:46:27 +02:00
Félix Aime
940d5954a3 Updating MISP watcher 2021-06-11 14:46:11 +02:00
Félix Aimé
cb0742d440
Hiding warnings of watchers. 2021-06-11 14:10:08 +02:00
Félix Aime
436870960d Correcting error 2021-06-10 21:11:41 +02:00
Félix Aime
772ff95108 Updating the update script 2021-06-10 20:17:24 +02:00
Félix Aime
926daf3e34 Debug after testing, everything works great now 2021-06-10 19:48:35 +02:00
Félix Aime
73946c27e2 More code modification regarding MISP integration 2021-06-10 19:00:06 +02:00
Félix Aime
8e09d4e1c8 More code modification regarding MISP integration 2021-06-10 18:37:40 +02:00
Félix Aime
f189f2e100 Code modifications regarding MISP integration 2021-06-09 18:24:37 +02:00
Félix Aime
a481e88251 Deleting get iocs endpoint 2021-06-09 12:49:28 +02:00
Félix Aime
1d1c217258 Deleting edit endpoint 2021-06-09 12:48:44 +02:00
Félix Aime
93e164d7c2 Typo in comment 2021-06-09 11:17:30 +02:00
Félix Aime
50baeaa9e5 Updating misp class and associated watcher code 2021-06-09 11:11:55 +02:00
Félix Aime
691a413bfb Modifying ip4addr & ip6addr types 2021-06-09 09:27:30 +02:00
Félix Aime
73ee7a280b Some modifications, still need tests and debug 2021-06-08 20:11:51 +02:00
Félix Aime
e0c79fa5d6 Working on the MISP integration, still WIP (untested) 2021-06-08 18:22:52 +02:00
Félix Aime
61de73d989 Adding the channel check to prevent interferences 2021-06-08 11:49:53 +02:00
Félix Aimé
9f75d339da
Update config.yaml 2021-06-07 14:28:50 +02:00
Félix Aimé
c1b8f4a447
Merge pull request #70 from JulAkx/misp
New Feature : Import IoCs from an added MISP instance.
2021-06-06 11:08:35 +02:00
Félix Aimé
1d8c2387ca
Check window location host value to show the close button.
The close button was available even if the interface is requested remotely. Now the script hides the close button if the value of window.location.host is equal to 127.0.0.1 or localhost.
2021-06-04 14:40:16 +02:00
Félix Aimé
fd66d2274e
Update install.sh 2021-06-03 15:20:25 +02:00
Félix Aimé
fa8393cba5
Merge pull request #72 from KasperskyLab/dev
Adding detection improvements and capture removing.
2021-06-03 14:54:38 +02:00
Félix Aime
8ea52b1a4f Resolving import and var error 2021-06-03 14:25:51 +02:00
Félix Aime
2968d6fcb6 Adding unsaved captures deletion 2021-06-03 14:08:34 +02:00
Félix Aimé
cb7aeb2721
Update iocs.json
Adding IOCs from the ESET report. Thanks guys.
Report: https://www.welivesecurity.com/wp-content/uploads/2021/05/eset_android_stalkerware.pdf
2021-05-31 20:21:53 +02:00
Julien DEPAILLAT
24be446598 New Feature : It is now possible to import IoCs from an added MISP instance. 2021-05-10 16:08:58 +02:00
Félix Aime
e04ef547c2 Update snort rule issue + http header detection 2021-05-04 14:48:09 +02:00
Félix Aimé
033d751e31
Update iocs.json 2021-05-04 10:21:29 +02:00
Félix Aimé
d41ad28c25
Update iocs.json 2021-04-30 16:51:24 +02:00
Félix Aimé
bf8edb0283
Update iocs.json 2021-04-29 20:24:09 +02:00
Félix Aimé
f00a6d67b9
Merge pull request #69 from KasperskyLab/dev
Correcting issue with certificates detection
2021-04-25 11:09:58 +02:00
Félix Aimé
056f8b0b64
Update update.sh 2021-04-25 11:09:35 +02:00
Félix Aime
bf848cd224 Adding new detections 2021-04-25 11:06:35 +02:00
Félix Aimé
79b597de8e
Update zeekengine.py 2021-04-24 22:56:00 +02:00
Félix Aimé
c3f132fc26
Update update.sh 2021-04-24 22:47:42 +02:00
Félix Aimé
0a00cc1b08
Update update.sh 2021-04-24 22:46:23 +02:00
Félix Aimé
6bca89630e
Update iocs.json 2021-04-24 22:40:43 +02:00
Félix Aimé
27942c224b
Correcting issue with certificates detection 2021-04-24 22:39:02 +02:00
Félix Aimé
c69f2a3d6e
Update iocs.json 2021-04-24 11:28:05 +02:00
Félix Aimé
d5ff62590a
Update iocs.json 2021-04-23 15:06:19 +02:00
Félix Aimé
1923348538
Update iocs.json 2021-04-23 14:00:40 +02:00
Félix Aimé
022f23be1c
Update iocs.json 2021-04-23 11:53:57 +02:00
Félix Aimé
8f006e4ecc
Update iocs.json 2021-04-23 10:05:46 +02:00
Félix Aimé
24e35d9ef5
Update iocs.json 2021-04-21 15:35:20 +02:00
Félix Aimé
53271bbb33
Update iocs.json 2021-04-20 19:04:29 +02:00
Félix Aimé
d9fed1a558
Update install.sh 2021-04-14 16:50:16 +02:00
Félix Aimé
e2f5801a99
Update iocs.json 2021-04-14 15:11:41 +02:00
Félix Aimé
8ac1beba9d
Update whitelist.json 2021-04-09 18:21:39 +02:00
Félix Aimé
16a4a3675a
Update iocs.json 2021-04-09 18:19:57 +02:00
Félix Aimé
7d98f47cba
Merge pull request #66 from KasperskyLab/dev
Update install.sh with new checks
2021-03-25 16:14:43 +01:00
Félix Aime
5e29f8c850 Update install.sh with new checks 2021-03-25 15:42:51 +01:00
Félix Aimé
1f0a9e8c68
Merge pull request #65 from KasperskyLab/dev
Adding Wi-Fi network priority
2021-03-25 15:05:12 +01:00
Félix Aime
ceb36f81ae Adding Wi-Fi network priority #55 2021-03-25 15:01:58 +01:00
Félix Aimé
32e04398fe
Update iocs.json 2021-03-25 13:48:54 +01:00
Félix Aimé
866f24bad8
Merge pull request #64 from KasperskyLab/main
Update of the dev branch with main (new) code
2021-03-25 10:30:16 +01:00
Félix Aimé
1c2d7033f0
Update install.sh
Adding Desktop directory check.
2021-03-25 10:10:36 +01:00
Félix Aimé
6d1a0d88e0
Merge pull request #63 from KasperskyLab/dev
Adding more translations and few fixes
2021-03-25 09:46:48 +01:00
Félix Aimé
f1250a00ba
Merge pull request #62 from bl4ckh0l3z/main
Fix for JWT token generation and validation
2021-03-25 09:46:28 +01:00
Félix Aime
208d408d37 Adding npm timeout for slow bandwidth 2021-03-24 19:03:48 +01:00
Félix Aime
fadcee35db Adding more translations and few fixes 2021-03-24 14:37:20 +01:00
bl4ckh0l3z
36833e1c6b
Update main.py
ERROR in app: Exception on /api/get-token [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/dist-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.7/dist-packages/flask_httpauth.py", line 164, in decorated
    return f(*args, **kwargs)
  File "/usr/share/sauron/server/backend/main.py", line 37, in get_token
    return jsonify({"token": token.decode("utf8")})
AttributeError: 'str' object has no attribute 'decode'
2021-03-23 21:02:41 +01:00
bl4ckh0l3z
2f232bbc15
Specify algorithm for jwt.decode
>>> jwt.decode(token, app.config["SECRET_KEY"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/dist-packages/jwt/api_jwt.py", line 113, in decode
    decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/jwt/api_jwt.py", line 80, in decode_complete
    'It is required that you pass in a value for the "algorithms" argument when calling decode().'
jwt.exceptions.DecodeError: It is required that you pass in a value for the "algorithms" argument when calling decode().
2021-03-23 20:57:23 +01:00
Félix Aimé
a98679a923
Update whitelist.json 2021-03-11 20:40:05 +01:00
Félix Aimé
3ff29226b7
Merge pull request #60 from KasperskyLab/dev
Minor changes (loader link + iptables rule)
2021-03-11 10:26:21 +01:00
Félix Aime
0d32a1d3c4 Minor changes (loader link + iptables rule) 2021-03-10 18:07:33 +01:00
Félix Aimé
6d5389370c
Update iocs.json 2021-03-01 16:59:38 +01:00
Félix Aimé
6b29daad59
Update iocs.json 2021-03-01 16:52:31 +01:00
Félix Aimé
3bdac850b6
Merge pull request #58 from KasperskyLab/dev
Adding few features.
2021-02-26 14:28:16 +01:00
Félix Aime
885d67afd0 Adding few seconds before internet check 2021-02-26 14:26:50 +01:00
Félix Aime
6de9f4aabe Change icon button to home button 2021-02-26 14:10:09 +01:00
Félix Aime
c3b48f278d Add back button 2021-02-26 13:47:57 +01:00
Félix Aime
e4d63a7ef5 Preventing the analyzed device to reach TinyCheck 2021-02-26 13:25:10 +01:00
Félix Aimé
672b8cf0c1
Merge pull request #57 from KasperskyLab/dev
Update install.sh with new node version.
2021-02-26 12:20:26 +01:00
Félix Aimé
4488a52631
Update install.sh 2021-02-26 12:15:45 +01:00
Félix Aimé
92b89b78cf
Merge pull request #56 from KasperskyLab/main
Update dev branch
2021-02-26 12:13:27 +01:00
Félix Aimé
22c7cf1119
Merge pull request #54 from KasperskyLab/update-feature
Update from GUI feature
2021-02-19 16:45:41 +01:00
Félix Aimé
67ac58ef46
Deleting Q&A. 2021-02-18 09:17:54 +01:00
84 changed files with 27563 additions and 70142 deletions

View File

@ -0,0 +1,19 @@
# This workflow will improvise current file with AI genereated documentation and Create new PR
name: Snorkell.ai - Revolutionizing Documentation on GitHub
on:
push:
branches: ["main"]
workflow_dispatch:
jobs:
Documentation:
runs-on: ubuntu-latest
steps:
- name: Snorkell DocGen Client
uses: SingularityX-ai/snorkell-documentation-client@v1.0.0
with:
client_id: ${{ secrets.SNORKELL_CLIENT_ID }}
api_key: ${{ secrets.SNORKELL_API_KEY }}
branch_name: "main"

View File

@ -8,11 +8,11 @@ TinyCheck allows you to easily capture network communications from a smartphone
The idea of TinyCheck emerged in a meeting about stalkerware with a [French women's shelter](https://www.centre-hubertine-auclert.fr). During this meeting we talked about how to easily detect [stalkerware](https://stopstalkerware.org/) without installing very technical apps nor doing forensic analysis on the victim's smartphone. The initial concept was to develop a tiny kiosk device based on Raspberry Pi which can be used by non-tech people to test their smartphones against malicious communications issued by stalkerware or any spyware. The idea of TinyCheck emerged in a meeting about stalkerware with a [French women's shelter](https://www.centre-hubertine-auclert.fr). During this meeting we talked about how to easily detect [stalkerware](https://stopstalkerware.org/) without installing very technical apps nor doing forensic analysis on the victim's smartphone. The initial concept was to develop a tiny kiosk device based on Raspberry Pi which can be used by non-tech people to test their smartphones against malicious communications issued by stalkerware or any spyware.
Of course, TinyCheck can also be used to spot any malicious communications from cybercrime to state-sponsored implants. It allows the end-user to push his own extended Indicators of Compromise via a backend in order to detect some ghosts over the wire. Of course, TinyCheck can also be used to spot any malicious communications from cybercrime to state-sponsored implants. It allows the end-user to push their own extended Indicators of Compromise via a backend in order to detect some ghosts over the wire.
<p align="center"><strong>If you need more documentation on how to install it, use it and the internals, don't hesitate to take a look at the <a href="https://github.com/KasperskyLab/TinyCheck/wiki">TinyCheck Wiki</a>.</strong></p> <p align="center"><strong>If you need more documentation on how to install it, use it and the internals, don't hesitate to take a look at the <a href="https://github.com/KasperskyLab/TinyCheck/wiki">TinyCheck Wiki</a>.</strong></p>
<p align="center">If you have any question about the projet, want to contribute or just send your feedback, <br />don't hesitate to contact us at tinycheck[@]kaspersky[.]com.</p> <p align="center">If you have any question about the project, want to contribute or just send your feedback, <br />don't hesitate to contact us at tinycheck[@]kaspersky[.]com.</p>
### Use cases ### Use cases
@ -24,36 +24,29 @@ TinyCheck can be used in several ways by individuals and entities:
### Installation ### Installation
Please check the few steps in the [Wiki's Installation Page](https://github.com/KasperskyLab/TinyCheck/wiki/TinyCheck-installation). Please check the few steps in the [Wiki's Installation Page](https://github.com/KasperskyLab/TinyCheck/wiki/TinyCheck-installation).
### Meet the frontend ### Meet the frontend
The frontend - which can be accessed from `http://tinycheck.local` is a kind of tunnel which help the user throughout the process of network capture and reporting. It allows the user to setup a Wi-Fi connection to an existing Wi-Fi network, create an ephemeral Wi-Fi network, capture the communications and show a report to the user... in less than one minute, 5 clicks and without any technical knowledge. The frontend - which can be accessed from `http://tinycheck.local` is a kind of tunnel which help the user throughout the process of network capture and reporting. It allows the user to setup a Wi-Fi connection to an existing Wi-Fi network, create an ephemeral Wi-Fi network, capture the communications and show a report to the user... in less than one minute, 5 clicks and without any technical knowledge.
![Frontend](/assets/frontend.png) ![Frontend](/assets/frontend.png)
### Meet the backend ### Meet the backend
Once installed, you can connect yourself to the TinyCheck backend by browsing the URL `https://tinycheck.local` and accepting the SSL self-signed certificate. Once installed, you can connect yourself to the TinyCheck backend by browsing the URL `https://tinycheck.local` and accepting the SSL self-signed certificate.
![Backend](/assets/backend.png) ![Backend](/assets/backend.png)
The backend allows you to edit the configuration of TinyCheck, add extended IOCs and whitelisted elements in order to prevent false positives. Several IOCs are already provided such as few suricata rules, FreeDNS, Name servers, CIDRs known to host malicious servers and so on. The backend allows you to edit the configuration of TinyCheck, add extended IOCs and whitelisted elements in order to prevent false positives. Several IOCs are already provided such as few suricata rules, FreeDNS, Name servers, CIDRs known to host malicious servers and so on.
### Questions & Answers
**Your project seem very cool, does it send data to Kaspersky or any telemetry server?**<br /><br />
No, at all. You can look to the sources, the only data sent by TinyCheck is an HTTP GET request to a website that you can specify in the config, as well as the watchers URLs. Kaspersky don't - and will not - receive any telemetry from your TinyCheck device.<br /><br />
**Can you list some hardware which can be used with this project (touch screen, wifi dongle etc.)?**<br /><br />
Unfortunately, we prefer to not promote any hardware/constructor/website on this page. Do not hesitate to contact us if you want specific references. <br /><br />
**I'm not very confortable with the concept of "watchers" as the IOCs downloaded are public. Do you plan to develop a server to centralize AMBER/RED IOCs?**<br /><br />
Yes, if the demand is felt by NGOs (contact us!). Is it possible to develop this kind of thing, allowing you to centralize your IOCs and managing your fleet of TinyCheck instances on a server that you host. The server can also embed better detection rules thanks to the telemetry that it will receive from devices.<br />
### Special thanks ### Special thanks
**Guys who provided some IOCs** **Felix Aime**, for his idea and passion while developing and testing this project. Felix is a main contributor and we really appreciate his work on TinyCheck.
**People who provided some IOCs**
- [Cian Heasley](https://twitter.com/nscrutables) for his android stalkerwares IOC repo, available here: https://github.com/diskurse/android-stalkerware - [Cian Heasley](https://twitter.com/nscrutables) for his android stalkerwares IOC repo, available here: https://github.com/diskurse/android-stalkerware
- [Te-k](https://twitter.com/tenacioustek) for his stalkerwares awesome IOCs repo, available here: https://github.com/Te-k/stalkerware-indicators - [Echap](https://github.com/AssoEchap) for their stalkerwares awesome IOCs repo, available here: https://github.com/AssoEchap/stalkerware-indicators
- [Emilien](https://twitter.com/__Emilien__) for his Stratum rules, available here: https://github.com/kwouffe/cryptonote-hunt - [Emilien](https://twitter.com/__Emilien__) for his Stratum rules, available here: https://github.com/kwouffe/cryptonote-hunt
- [Costin Raiu](https://twitter.com/craiu) for his geo-tracker domains, available here: https://github.com/craiu/mobiletrackers/blob/master/list.txt - [Costin Raiu](https://twitter.com/craiu) for his geo-tracker domains, available here: https://github.com/craiu/mobiletrackers/blob/master/list.txt

View File

@ -16,60 +16,82 @@ import os
containing a capture.pcap file. containing a capture.pcap file.
""" """
if __name__ == "__main__":
if len(sys.argv) == 2:
capture_directory = sys.argv[1]
if os.path.isdir(capture_directory):
manager = Manager() def analyze(capture_directory,frontend=False):
alerts = manager.dict() if os.path.isdir(capture_directory):
def zeekengine(alerts): manager = Manager()
zeek = ZeekEngine(capture_directory) alerts = manager.dict()
zeek.start_zeek()
alerts["zeek"] = zeek.retrieve_alerts()
# whitelist.json writing. def zeekengine(alerts):
with open(os.path.join(capture_directory, "assets/whitelist.json"), "w") as f: zeek = ZeekEngine(capture_directory)
f.write(json.dumps(zeek.retrieve_whitelist(), zeek.start_zeek()
indent=4, separators=(',', ': '))) alerts["zeek"] = zeek.retrieve_alerts()
# conns.json writing. if not os.path.isdir(os.path.join(capture_directory, "assets")):
with open(os.path.join(capture_directory, "assets/conns.json"), "w") as f: os.mkdir(os.path.join(capture_directory, "assets"))
f.write(json.dumps(zeek.retrieve_conns(), # whitelist.json writing.
indent=4, separators=(',', ': '))) with open(os.path.join(capture_directory, "assets/whitelist.json"), "w") as f:
f.write(json.dumps(zeek.retrieve_whitelist(),
indent=4, separators=(',', ': ')))
def snortengine(alerts): # conns.json writing.
suricata = SuricataEngine(capture_directory) with open(os.path.join(capture_directory, "assets/conns.json"), "w") as f:
suricata.start_suricata() f.write(json.dumps(zeek.retrieve_conns(),
alerts["suricata"] = suricata.get_alerts() indent=4, separators=(',', ': ')))
# Start the engines. def snortengine(alerts):
p1 = Process(target=zeekengine, args=(alerts,)) suricata = SuricataEngine(capture_directory)
p2 = Process(target=snortengine, args=(alerts,)) suricata.start_suricata()
p1.start() alerts["suricata"] = suricata.get_alerts()
p2.start()
# Wait to their end. # Start the engines.
p1.join() p1 = Process(target=zeekengine, args=(alerts,))
p2.join() p2 = Process(target=snortengine, args=(alerts,))
p1.start()
p2.start()
# Some formating and alerts.json writing. # Wait to their end.
with open(os.path.join(capture_directory, "assets/alerts.json"), "w") as f: p1.join()
report = {"high": [], "moderate": [], "low": []} p2.join()
for alert in (alerts["zeek"] + alerts["suricata"]):
if alert["level"] == "High": # Some formating and alerts.json writing.
report["high"].append(alert) with open(os.path.join(capture_directory, "assets/alerts.json"), "w") as f:
if alert["level"] == "Moderate": report = {"high": [], "moderate": [], "low": []}
report["moderate"].append(alert) for alert in (alerts["zeek"] + alerts["suricata"]):
if alert["level"] == "Low": if alert["level"] == "High":
report["low"].append(alert) report["high"].append(alert)
f.write(json.dumps(report, indent=4, separators=(',', ': '))) if alert["level"] == "Moderate":
report["moderate"].append(alert)
if alert["level"] == "Low":
report["low"].append(alert)
f.write(json.dumps(report, indent=4, separators=(',', ': ')))
# Generate the report
report = Report(capture_directory,frontend)
report.generate_report()
# Generate the report
report = Report(capture_directory)
report.generate_report()
else:
print("The directory doesn't exist.")
else: else:
print("Please specify a capture directory in argument.") print("The directory doesn't exist.")
def usage():
print("""Usage: python analysis.py [capture_directory]
where [capture_directory] is a directory containing a capture.pcap file
analysis.py -f starts the analysis in frontend mode intended to be called by the TinyCheck frontend.""")
if __name__ == "__main__":
if len(sys.argv) == 2: #called manually without frontend
analyze(sys.argv[1], False)
elif len(sys.argv) == 3:
if(sys.argv[1]) == "-f": #frontend mode
analyze(sys.argv[2], True)
else:
usage()
else:
usage()

View File

@ -13,7 +13,7 @@ from utils import get_config
class Report(object): class Report(object):
def __init__(self, capture_directory): def __init__(self, capture_directory, frontend):
self.capture_directory = capture_directory self.capture_directory = capture_directory
self.alerts = self.read_json(os.path.join( self.alerts = self.read_json(os.path.join(
capture_directory, "assets/alerts.json")) capture_directory, "assets/alerts.json"))
@ -21,10 +21,13 @@ class Report(object):
capture_directory, "assets/whitelist.json")) capture_directory, "assets/whitelist.json"))
self.conns = self.read_json(os.path.join( self.conns = self.read_json(os.path.join(
capture_directory, "assets/conns.json")) capture_directory, "assets/conns.json"))
self.device = self.read_json(os.path.join( self.device = None
capture_directory, "assets/device.json")) self.capinfos = None
self.capinfos = self.read_json(os.path.join( if frontend:
capture_directory, "assets/capinfos.json")) self.device = self.read_json(os.path.join(
capture_directory, "assets/device.json"))
self.capinfos = self.read_json(os.path.join(
capture_directory, "assets/capinfos.json"))
try: try:
with open(os.path.join(self.capture_directory, "capture.pcap"), "rb") as f: with open(os.path.join(self.capture_directory, "capture.pcap"), "rb") as f:
self.capture_sha1 = hashlib.sha1(f.read()).hexdigest() self.capture_sha1 = hashlib.sha1(f.read()).hexdigest()
@ -204,16 +207,18 @@ class Report(object):
""" """
header = "<div class=\"header\">" header = "<div class=\"header\">"
header += "<div class=\"logo\"></div>" header += "<div class=\"logo\"></div>"
header += "<p><br /><strong>{}: {}</strong><br />".format(self.template["device_name"], if self.device is not None:
header += "<p><br /><strong>{}: {}</strong><br />".format(self.template["device_name"],
self.device["name"]) self.device["name"])
header += "{}: {}<br />".format(self.template["device_mac"], header += "{}: {}<br />".format(self.template["device_mac"],
self.device["mac_address"]) self.device["mac_address"])
header += "{} {}<br />".format(self.template["report_generated_on"], header += "{} {}<br />".format(self.template["report_generated_on"],
datetime.now().strftime("%d/%m/%Y - %H:%M:%S")) datetime.now().strftime("%d/%m/%Y - %H:%M:%S"))
header += "{}: {}s<br />".format(self.template["capture_duration"], if self.capinfos is not None:
self.capinfos["Capture duration"]) header += "{}: {}s<br />".format(self.template["capture_duration"],
header += "{}: {}<br />".format(self.template["packets_number"], self.capinfos["Capture duration"])
self.capinfos["Number of packets"]) header += "{}: {}<br />".format(self.template["packets_number"],
self.capinfos["Number of packets"])
header += "{}: {}<br />".format( header += "{}: {}<br />".format(
self.template["capture_sha1"], self.capture_sha1) self.template["capture_sha1"], self.capture_sha1)
header += "</p>" header += "</p>"

View File

@ -34,6 +34,22 @@ class ZeekEngine(object):
self.active_analysis = get_config(("analysis", "active")) self.active_analysis = get_config(("analysis", "active"))
self.userlang = get_config(("frontend", "user_lang")) self.userlang = get_config(("frontend", "user_lang"))
# Retreive IOCs.
if self.iocs_analysis:
self.bl_cidrs = [[IPNetwork(cidr[0]), cidr[1]]
for cidr in get_iocs("cidr")]
self.bl_hosts = get_iocs("ip4addr") + get_iocs("ip6addr")
self.bl_domains = get_iocs("domain")
self.bl_freedns = get_iocs("freedns")
self.bl_nameservers = get_iocs("ns")
self.bl_tlds = get_iocs("tld")
# Retreive whitelisted items.
if self.whitelist_analysis:
self.wl_cidrs = [IPNetwork(cidr) for cidr in get_whitelist("cidr")]
self.wl_hosts = get_whitelist("ip4addr") + get_whitelist("ip6addr")
self.wl_domains = get_whitelist("domain")
# Load template language # Load template language
if not re.match("^[a-z]{2,3}$", self.userlang): if not re.match("^[a-z]{2,3}$", self.userlang):
self.userlang = "en" self.userlang = "en"
@ -84,21 +100,17 @@ class ZeekEngine(object):
# Check for whitelisted assets, if any, delete the record. # Check for whitelisted assets, if any, delete the record.
if self.whitelist_analysis: if self.whitelist_analysis:
wl_cidrs = [IPNetwork(cidr) for cidr in get_whitelist("cidr")]
wl_hosts = get_whitelist("ip4addr") + get_whitelist("ip6addr")
wl_domains = get_whitelist("domain")
for i, c in enumerate(self.conns): for i, c in enumerate(self.conns):
if c["ip_dst"] in [ip for ip in wl_hosts]: if c["ip_dst"] in [ip for ip in self.wl_hosts]:
self.whitelist.append(self.conns[i]) self.whitelist.append(self.conns[i])
self.conns[i] = False self.conns[i] = False
elif c["resolution"] in wl_domains: elif c["resolution"] in self.wl_domains:
self.whitelist.append(self.conns[i]) self.whitelist.append(self.conns[i])
self.conns[i] = False self.conns[i] = False
elif True in [c["resolution"].endswith("." + dom) for dom in wl_domains]: elif True in [c["resolution"].endswith("." + dom) for dom in self.wl_domains]:
self.whitelist.append(self.conns[i]) self.whitelist.append(self.conns[i])
self.conns[i] = False self.conns[i] = False
elif True in [IPAddress(c["ip_dst"]) in cidr for cidr in wl_cidrs]: elif True in [IPAddress(c["ip_dst"]) in cidr for cidr in self.wl_cidrs]:
self.whitelist.append(self.conns[i]) self.whitelist.append(self.conns[i])
self.conns[i] = False self.conns[i] = False
@ -151,17 +163,9 @@ class ZeekEngine(object):
if self.iocs_analysis: if self.iocs_analysis:
bl_cidrs = [[IPNetwork(cidr[0]), cidr[1]]
for cidr in get_iocs("cidr")]
bl_hosts = get_iocs("ip4addr") + get_iocs("ip6addr")
bl_domains = get_iocs("domain")
bl_freedns = get_iocs("freedns")
bl_nameservers = get_iocs("ns")
bl_tlds = get_iocs("tld")
for c in self.conns: for c in self.conns:
# Check for blacklisted IP address. # Check for blacklisted IP address.
for host in bl_hosts: for host in self.bl_hosts:
if c["ip_dst"] == host[0]: if c["ip_dst"] == host[0]:
c["alert_tiggered"] = True c["alert_tiggered"] = True
self.alerts.append({"title": self.template["IOC-01"]["title"].format(c["resolution"], c["ip_dst"], host[1].upper()), self.alerts.append({"title": self.template["IOC-01"]["title"].format(c["resolution"], c["ip_dst"], host[1].upper()),
@ -171,7 +175,7 @@ class ZeekEngine(object):
"id": "IOC-01"}) "id": "IOC-01"})
break break
# Check for blacklisted CIDR. # Check for blacklisted CIDR.
for cidr in bl_cidrs: for cidr in self.bl_cidrs:
if IPAddress(c["ip_dst"]) in cidr[0]: if IPAddress(c["ip_dst"]) in cidr[0]:
c["alert_tiggered"] = True c["alert_tiggered"] = True
self.alerts.append({"title": self.template["IOC-02"]["title"].format(c["resolution"], cidr[0], cidr[1].upper()), self.alerts.append({"title": self.template["IOC-02"]["title"].format(c["resolution"], cidr[0], cidr[1].upper()),
@ -180,7 +184,7 @@ class ZeekEngine(object):
"level": "Moderate", "level": "Moderate",
"id": "IOC-02"}) "id": "IOC-02"})
# Check for blacklisted domain. # Check for blacklisted domain.
for domain in bl_domains: for domain in self.bl_domains:
if c["resolution"].endswith(domain[0]): if c["resolution"].endswith(domain[0]):
if domain[1] != "tracker": if domain[1] != "tracker":
c["alert_tiggered"] = True c["alert_tiggered"] = True
@ -197,7 +201,7 @@ class ZeekEngine(object):
"level": "Moderate", "level": "Moderate",
"id": "IOC-04"}) "id": "IOC-04"})
# Check for blacklisted FreeDNS. # Check for blacklisted FreeDNS.
for domain in bl_freedns: for domain in self.bl_freedns:
if c["resolution"].endswith("." + domain[0]): if c["resolution"].endswith("." + domain[0]):
c["alert_tiggered"] = True c["alert_tiggered"] = True
self.alerts.append({"title": self.template["IOC-05"]["title"].format(c["resolution"]), self.alerts.append({"title": self.template["IOC-05"]["title"].format(c["resolution"]),
@ -207,7 +211,7 @@ class ZeekEngine(object):
"id": "IOC-05"}) "id": "IOC-05"})
# Check for suspect tlds. # Check for suspect tlds.
for tld in bl_tlds: for tld in self.bl_tlds:
if c["resolution"].endswith(tld[0]): if c["resolution"].endswith(tld[0]):
c["alert_tiggered"] = True c["alert_tiggered"] = True
self.alerts.append({"title": self.template["IOC-06"]["title"].format(c["resolution"]), self.alerts.append({"title": self.template["IOC-06"]["title"].format(c["resolution"]),
@ -220,7 +224,7 @@ class ZeekEngine(object):
try: # Domain nameservers check. try: # Domain nameservers check.
name_servers = pydig.query(c["resolution"], "NS") name_servers = pydig.query(c["resolution"], "NS")
if len(name_servers): if len(name_servers):
for ns in bl_nameservers: for ns in self.bl_nameservers:
if name_servers[0].endswith(".{}.".format(ns[0])): if name_servers[0].endswith(".{}.".format(ns[0])):
c["alert_tiggered"] = True c["alert_tiggered"] = True
self.alerts.append({"title": self.template["ACT-01"]["title"].format(c["resolution"], name_servers[0]), self.alerts.append({"title": self.template["ACT-01"]["title"].format(c["resolution"], name_servers[0]),
@ -232,6 +236,7 @@ class ZeekEngine(object):
pass pass
try: # Domain history check. try: # Domain history check.
whois_record = whois.whois(c["resolution"]) whois_record = whois.whois(c["resolution"])
creation_date = whois_record.creation_date if type( creation_date = whois_record.creation_date if type(
whois_record.creation_date) is not list else whois_record.creation_date[0] whois_record.creation_date) is not list else whois_record.creation_date[0]
@ -243,6 +248,7 @@ class ZeekEngine(object):
"host": c["resolution"], "host": c["resolution"],
"level": "Moderate", "level": "Moderate",
"id": "ACT-02"}) "id": "ACT-02"})
except: except:
pass pass
@ -263,31 +269,79 @@ class ZeekEngine(object):
for record in ParseZeekLogs(os.path.join(dir, "files.log"), output_format="json", safe_headers=False): for record in ParseZeekLogs(os.path.join(dir, "files.log"), output_format="json", safe_headers=False):
if record is not None: if record is not None:
f = {"filename": record["filename"], f = {"filename": record["filename"],
"ip_src": record["tx_hosts"], "ip_src": record["id.orig_h"],
"ip_dst": record["rx_hosts"], "ip_dst": record["id.resp_h"],
"mime_type": record["mime_type"], "mime_type": record["mime_type"],
"sha1": record["sha1"]} "sha1": record["sha1"]}
if f not in self.files: if f not in self.files:
self.files.append(f) self.files.append(f)
for f in self.files: for f in self.files:
if f["mime_type"] == "application/x-x509-ca-cert": if f["mime_type"] == "application/x-x509-user-cert":
for cert in bl_certs: # Check for blacklisted certificate. for cert in bl_certs: # Check for blacklisted certificate.
if f["sha1"] == cert[0]: if f["sha1"] == cert[0]:
host = self.resolve(f["ip_dst"]) host = self.resolve(f["ip_src"])
c["alert_tiggered"] = True
self.alerts.append({"title": self.template["IOC-07"]["title"].format(cert[1].upper(), host), self.alerts.append({"title": self.template["IOC-07"]["title"].format(cert[1].upper(), host),
"description": self.template["IOC-07"]["description"].format(f["sha1"], host), "description": self.template["IOC-07"]["description"].format(f["sha1"], host),
"host": host, "host": host,
"level": "High", "level": "High",
"id": "IOC-07"}) "id": "IOC-07"})
def http_check(self, dir):
"""
Check on the http.log:
* Blacklisted domain/tld from the Host header field.
Can be used when no DNS query have been done during the session (already cached by the device.)
:return: nothing - all stuff appended to self.alerts
"""
if os.path.isfile(os.path.join(dir, "http.log")):
for record in ParseZeekLogs(os.path.join(dir, "http.log"), output_format="json", safe_headers=False):
if record is not None:
c = {"host": record['host']}
if c not in self.http:
self.http.append(c)
if self.iocs_analysis:
for c in self.http:
# If we already know the host form DNS, let's continue.
if c["host"] in [r["domain"] for r in self.dns]:
continue
# Check for blacklisted domain.
for h in self.bl_domains:
if h[1] != "tracker":
if c["host"].endswith(h[0]):
self.alerts.append({"title": self.template["IOC-08"]["title"].format(c["host"], h[1].upper()),
"description": self.template["IOC-08"]["description"].format(c["host"]),
"host": c["host"],
"level": "High",
"id": "IOC-08"})
# Check for freedns.
for h in self.bl_freedns:
if c["host"].endswith(h[0]):
self.alerts.append({"title": self.template["IOC-09"]["title"].format(c["host"]),
"description": self.template["IOC-09"]["description"].format(c["host"]),
"host": c["host"],
"level": "Moderate",
"id": "IOC-09"})
# Check for fancy TLD.
for h in self.bl_tlds:
if c["host"].endswith(h[0]):
self.alerts.append({"title": self.template["IOC-10"]["title"].format(c["host"]),
"description": self.template["IOC-10"]["description"].format(c["host"], h[0]),
"host": c["host"],
"level": "Low",
"id": "IOC-10"})
def ssl_check(self, dir): def ssl_check(self, dir):
""" """
Check on the ssl.log: Check on the ssl.log:
* SSL connections which doesn't use the 443. * SSL connections which doesn't use the 443.
* "Free" certificate issuer (taken from the config). * "Free" certificate issuer (taken from the config).
* Self-signed certificates. * Self-signed certificates.
* Blacklisted domain in the CN
:return: nothing - all stuff appended to self.alerts :return: nothing - all stuff appended to self.alerts
""" """
ssl_default_ports = get_config(("analysis", "ssl_default_ports")) ssl_default_ports = get_config(("analysis", "ssl_default_ports"))
@ -298,8 +352,9 @@ class ZeekEngine(object):
if record is not None: if record is not None:
c = {"host": record['id.resp_h'], c = {"host": record['id.resp_h'],
"port": record['id.resp_p'], "port": record['id.resp_p'],
"issuer": record["issuer"], "issuer": record["issuer"] if "issuer" in record else "",
"validation_status": record["validation_status"]} "validation_status": record["validation_status"],
"cn": record["server_name"] if "server_name" in record else ""}
if c not in self.ssl: if c not in self.ssl:
self.ssl.append(c) self.ssl.append(c)
@ -335,6 +390,24 @@ class ZeekEngine(object):
"level": "Moderate", "level": "Moderate",
"id": "SSL-03"}) "id": "SSL-03"})
if self.iocs_analysis:
for cert in self.ssl:
# Check if the domain in the certificate haven't been blacklisted
# This check can be good if the domain has already been cached by
# the device so it wont appear in self.dns.
if any([cert["cn"].endswith(r["domain"]) for r in self.dns]):
continue
for domain in self.bl_domains:
if domain[1] != "tracker":
if cert["cn"].endswith(domain[0]):
self.alerts.append({"title": self.template["SSL-04"]["title"].format(domain[0], domain[1].upper()),
"description": self.template["SSL-04"]["description"].format(domain[0]),
"host": domain[0],
"level": "High",
"id": "SSL-04"})
def alerts_check(self): def alerts_check(self):
""" """
Leverage an advice to the user based on the trigered hosts Leverage an advice to the user based on the trigered hosts
@ -353,7 +426,7 @@ class ZeekEngine(object):
self.alerts.append({"title": self.template["ADV-01"]["title"].format(host), self.alerts.append({"title": self.template["ADV-01"]["title"].format(host),
"description": self.template["ADV-01"]["description"].format(host, nb), "description": self.template["ADV-01"]["description"].format(host, nb),
"host": host, "host": host,
"level": "High", "level": "Moderate",
"id": "ADV-01"}) "id": "ADV-01"})
def resolve(self, ip_addr): def resolve(self, ip_addr):
@ -376,10 +449,10 @@ class ZeekEngine(object):
self.working_dir), shell=True).wait() self.working_dir), shell=True).wait()
sp.Popen("cd {} && mv *.log assets/".format(self.working_dir), sp.Popen("cd {} && mv *.log assets/".format(self.working_dir),
shell=True).wait() shell=True).wait()
self.fill_dns(self.working_dir + "/assets/") self.fill_dns(self.working_dir + "/assets/")
self.netflow_check(self.working_dir + "/assets/") self.netflow_check(self.working_dir + "/assets/")
self.ssl_check(self.working_dir + "/assets/") self.ssl_check(self.working_dir + "/assets/")
self.http_check(self.working_dir + "/assets/")
self.files_check(self.working_dir + "/assets/") self.files_check(self.working_dir + "/assets/")
self.alerts_check() self.alerts_check()

View File

@ -48,6 +48,18 @@
"title": "Un certificat associat a activitats {} ha estat identificat en una comunicació cap a {}.", "title": "Un certificat associat a activitats {} ha estat identificat en una comunicació cap a {}.",
"description": "El certificat ({}) associat a {} ha estat explícitament etiquetat com a maliciós. Això indica que el seu dispositiu està probablement compromès i necessita ser analitzat en profunditat per un especialista forense." "description": "El certificat ({}) associat a {} ha estat explícitament etiquetat com a maliciós. Això indica que el seu dispositiu està probablement compromès i necessita ser analitzat en profunditat per un especialista forense."
}, },
"IOC-08": {
"title": "S'ha fet una petició HTTP a {} que està etiquetada com {}.",
"description": "El domini {} identificat en la captura ha estat explícitament etiquetat com a maliciós. Això indica que el dispositiu està probablement compromès i ha de ser investigat en profunditat."
},
"IOC-09": {
"title": "S'ha fet una petició HTTP a el domini {} que és un DNS gratuït.",
"description": "El domini {} està utilitzant un servei DNS gratuït. Aquest tipus de serveis és utilitzat per cibercriminals i altres actors d'amenaces de manera comú. És força sospitós que una aplicació en segon pla utilitzi aquest tipus de serveis.Per favor investigui. "
},
"IOC-10": {
"title": "S'ha fet una petició HTTP a el domini {} que conté un TLD sospitós.",
"description": "El domini {} està utilitzant un domini de primer nivell -TLD- ({}). Encara que no sigui maliciós, aquest TLP no-genèric és usat per cibercriminals i altres actors d'amenaces amb regularitat. Comproveu aquest domini mitjançant la seva cerca a Internet. Si hi ha altres alertes relacionades amb aquest host, considereu-lo com a molt sospitós. "
},
"ACT-01": { "ACT-01": {
"title": "El domini {} està utilitzant un servidor de noms sospitós ({}).", "title": "El domini {} està utilitzant un servidor de noms sospitós ({}).",
"description": "El nom de domini {} utilitza un servidor de noms que ha estat explícitament etiquetat i associat a activitat maliciosa. Molts ciberdelinqüents i altres actors d'amenaces utilitzen aquest tipus de registradors ja que accepten criptomonedes i pagaments anònims. Es recomana investigar aquest domini i l'aplicació en execució associada mitjançant un anàlisi forense de el dispositiu. " "description": "El nom de domini {} utilitza un servidor de noms que ha estat explícitament etiquetat i associat a activitat maliciosa. Molts ciberdelinqüents i altres actors d'amenaces utilitzen aquest tipus de registradors ja que accepten criptomonedes i pagaments anònims. Es recomana investigar aquest domini i l'aplicació en execució associada mitjançant un anàlisi forense de el dispositiu. "
@ -68,6 +80,10 @@
"title": "El certificat associat a {} és autosignat.", "title": "El certificat associat a {} és autosignat.",
"description": "L'ús de certificats autosignats és un element comú en infrastructures utilitzades per atacants. Recomanem comprovar el host {} que està associat a aquest certificat, especialment el seu nom de domini (en cas d'existir), el seu registre WHOIS, la seva data de creació i verificant la seva reputació a Internet. " "description": "L'ús de certificats autosignats és un element comú en infrastructures utilitzades per atacants. Recomanem comprovar el host {} que està associat a aquest certificat, especialment el seu nom de domini (en cas d'existir), el seu registre WHOIS, la seva data de creació i verificant la seva reputació a Internet. "
}, },
"SSL-04": {
"title": "Un certificat conté el nom de domini {}, classificat com a {}",
"description": "Un dels certificats intercanviats conté el nom de domini {}. Aquest nom de domini sha classificat explícitament com a maliciós. El vostre dispositiu està compromès i hauria de ser investigat amb més detall per un equip professional."
},
"ADV-01": { "ADV-01": {
"title": "Comprovi les alertes per {}", "title": "Comprovi les alertes per {}",
"description": "Si us plau, verifiqui la reputació del sistema {}, ja que sembla ser maliciós per aparèixer en {} alertes durant la sessió." "description": "Si us plau, verifiqui la reputació del sistema {}, ja que sembla ser maliciós per aparèixer en {} alertes durant la sessió."

128
analysis/locales/cn.json Normal file
View File

@ -0,0 +1,128 @@
{
"alerts": {
"PROTO-01": {
"title": "{} 协议被主机 {} 用于连接外部网络。",
"description": "{} 协议一般只用于本地网络。请检查主机 {} ,结合其他警报确认是否存在威胁。"
},
"PROTO-02": {
"title": "存在 {} 个前往 {} 的连接使用了大于或等于 {} 的端口号.",
"description": "共有 {} 个目的地主机为 {} 的连接,使用了端口号 {} 。恶意流量时常使用非标准端口号。我们推荐对该主机地址的声誉进行检查,请参考其他警报并在互联网上搜索该地址。"
},
"PROTO-03": {
"title": "前往主机 {} 的HTTP连接",
"description": "您的设备向主机 {} 发起了未加密的HTTP连接。虽然此行为本身未必来自恶意软件但大部分智能手机后台运行的软件不会发起未加密的HTTP连接。请在互联网上搜索该地址以检查该主机的声誉。"
},
"PROTO-04": {
"title": "前往主机 {} 的HTTP连接使用了非标准端口 ({}).",
"description": "您的设备向主机 {} 发起了未加密的HTTP连接并使用了非标准端口号 {} 。此行为相当异常。请在互联网上搜索该地址以检查该主机的声誉。"
},
"PROTO-05": {
"title": "本次分析期间,主机地址 {} 在DNS解析请求中并未出现过。",
"description": "这说明没有任何域名指向地址 {} 或者被分析的设备缓存了之前的DNS解析结果。如果该地址出现在其他警报当中请仔细检查。"
},
"IOC-01": {
"title": "存在前往 {} ({}) 的连接,该地址被标记为 {} 。",
"description": "主机 {} 由于恶意行为已被加入了黑明单。您的设备很可能已被感染需要由IT安全人员进行深度分析。"
},
"IOC-02": {
"title": "前往 {} 的连接目的地处于 {} 网段,该网段已被标记为 {} 。",
"description": "服务器 {} 所处的网段存在大量已知的恶意活动。虽然该行为本身未必来自恶意软件,您仍然需要检查其他警告是否包含该地址。如果您有所怀疑,请在互联网上搜索该地址,以检查其是否恶意。"
},
"IOC-03": {
"title": "向域名 {} 发起的DNS请求已被标记为 {} 。",
"description": "在截获流量中出现的域名 {} 已被明确标记为恶意。您的设备很可能已被感染需要由IT安全人员进一步进行深度分析。"
},
"IOC-04": {
"title": "向域名 {} 发起的DNS请求已被标记为 {} 。",
"description": "在截获流量中出现的域名 {} 已被明确标记为追踪器。您的设备上某个活动的应用正在追踪您的地理位置。"
},
"IOC-05": {
"title": "向 {} 发起的DNS请求是一个免费DNS服务商。",
"description": "在截获流量中出现的域名 {} 使用了免费的DNS服务。这类服务经常被网络犯罪份子或国家资助的黑客在行动中使用。后台运行的应用使用这类服务非常可疑请仔细调查。"
},
"IOC-06": {
"title": "向域名 {} 发起的DNS请求使用了可疑的顶级域名。",
"description": "域名 {} 使用了可疑的顶级域名 ({}). 虽然这并不能确认域名被用于恶意用途,但这个不常见的顶级域名经常被网络犯罪份子或国家资助的黑客在行动中使用。请用搜索引擎在互联网上搜索该域名。如果存在其他警报指向该主机,则非常可疑。"
},
"IOC-07": {
"title": "曾被用于 {} 活动的数字证书被用于与 {} 通信.",
"description": "该数字证书 ({}) 与地址 {} 关联,已被明确标记为恶意。您的设备已被感染,需要对其进行取证分析。"
},
"IOC-08": {
"title": "向 {} 发起的HTTP请求已被标记为 {} 。",
"description": "在截获流量中出现的域名 {} 已被明确标记为恶意。您的设备很可能已被感染需要由IT安全人员进一步进行深度分析。"
},
"IOC-09": {
"title": "向 {} 发起的HTTP请求域名使用了一个免费DNS服务商。",
"description": "域名 {} 使用了免费的DNS服务。这类服务经常被网络犯罪份子或国家资助的黑客在行动中使用。后台运行的应用使用这类服务非常可疑请仔细调查。"
},
"IOC-10": {
"title": "向 {} 发起的HTTP请求使用了可疑的顶级域名。",
"description": "域名 {} 使用了可疑的顶级域名 ({}). 虽然这并不能确认域名被用于恶意用途,但这个不常见的顶级域名经常被网络犯罪份子或国家资助的黑客在行动中使用。请用搜索引擎在互联网上搜索该域名。如果存在其他警报指向该主机,则非常可疑。"
},
"ACT-01": {
"title": "域名 {} 使用了可疑的域名解析服务器 ({}).",
"description": "域名 {} 使用了可疑的域名解析服务器,该解析器已被明确标记为与恶意活动相关联。网络犯罪份子或国家资助的黑客经常使用此类服务,因为他们允许使用加密货币或匿名支付方式。建议对设备进行取证分析,以便该域名和与其相关的正在运行的应用程序进行深入调查。"
},
"ACT-02": {
"title": "域名 {} 最近刚刚被注册 ({} 天前)。",
"description": "域名 {} 非常新。虽然这本身不说明恶意行为,但黑客攻击者经常在每次攻击中使用新的设施,因此会使用刚刚注册的域名."
},
"SSL-01": {
"title": "在非标准端口 ({}) 上发起SSL连接至 {}",
"description": "在智能手机上前往非标准端口的SSL连接非常罕见。虽然这可能来自非常正常的应用程序但我们推荐检查域名 {} 的声誉。请检查该域名的WHOIS记录对应的ASAutonomous System, 自治领),域名注册日期,以及在互联网上搜索该域名。"
},
"SSL-02": {
"title": "前往 {} 的SSL连接使用了免费证书。",
"description": "免费SSL证书提供商 (例如 Let's Encrypt) 常被用于与恶意软件和钓鱼网页有关的后端远程控制服务器。我们建议仔细分析该证书对应的主机,检查其域名,注册日期,以及在互联网上的声誉。"
},
"SSL-03": {
"title": "与 {} 关联的自签名证书",
"description": "黑客攻击设施经常使用自签名证书。我们建议仔细分析该证书对应的主机 {} ,检查其域名 (如有) WHOIS记录注册日期以及在互联网上的声誉。"
},
"SSL-04": {
"title": "数字证书包含域名 {} ,已被归类为 {}",
"description": "一份被交换的证书中包括了域名 {} 。该域名已被明确标记为恶意。您的设备已确定被感染,需要交给专业团队进行进一步调查。"
},
"ADV-01": {
"title": "请检查 {} 的其他警报",
"description": "请检查主机 {} 的声誉,该地址可能存在恶意活动,在本次分析中已经触发了 {} 个警报。"
},
"SNORT-01": {
"title": "Suricata 入侵检测规则被触发: {}",
"description": "网络入侵检测规则被触发。您的设备很可能已经被入侵,或存在其他可疑行为。"
}
},
"report": {
"numbers": [
"一",
"二",
"三",
"四",
"五",
"六",
"七",
"八",
"九"
],
"suspect_title": "可疑通信",
"uncat_title": "未分类通信",
"whitelist_title": "白名单通信",
"protocol": "协议",
"domain": "域名",
"dst_ip": "目的地IP地址",
"dst_port": "目的地端口号",
"device_name": "设备名称",
"device_mac": "设备 MAC 地址",
"report_generated_on": "报告生成于",
"capture_duration": "流量捕获时长",
"packets_number": "数据包数量",
"capture_sha1": "捕获的 SHA1 哈希",
"report_for_the_capture": "捕获报告",
"report_footer": "此报告由 Tinycheck 设备自动生成。如有任何疑问,错误报告或意见反馈,请联系 tinycheck@kaspersky.com 。",
"high_msg": "您的设备很可能已被入侵,存在 {} 条高级警报.",
"moderate_msg": "您有 {} 条中级警报,您的设备存在被入侵的可能性。请仔细检查这些警报。",
"low_msg": "您只有 {} 条低级警报。请检查。",
"none_msg": "情况正常,没有警报。如果存在未分类通信,请检查。"
}
}

128
analysis/locales/de.json Normal file
View File

@ -0,0 +1,128 @@
{
"alerts": {
"PROTO-01": {
"title": "Es besteht {} Kommunikationsverbindung zu {} außerhalb des lokalen Netzwerks.",
"description": "Das Protokoll {} wird häufig in internen Netzwerken verwendet. Bitte überprüfen Sie, ob der Host {} andere Warnungen verursacht hat, was auf bösartiges Verhalten hindeuten kann."
},
"PROTO-02": {
"title": "{} Verbindung zu {} zu einem Port größer als oder gleich {}.",
"description": "{} Verbindungen zu {} über den Port {} wurden erkannt. Die Verwendung eines nicht standardmäßigen Ports ist manchmal ein Merkmal für bösartige Aktivitäten. Wir empfehlen, die Reputation dieses Hosts zu überprüfen, indem Sie sich andere Warnungen ansehen und im Internet danach suchen."
},
"PROTO-03": {
"title": "Mit dem Host {} wurde per HTTP kommuniziert.",
"description": "Ihr Gerät hat mit dem Host {} über das unverschlüsselte HTTP-Protokoll kommuniziert. Auch wenn dieses Verhalten an sich nicht bösartig ist, ist es ungewöhnlich, dass von Smartphone-Anwendungen, die im Hintergrund laufen, HTTP-Kommunikationen ausgehen. Bitte überprüfen Sie die Reputation des Hosts anhand einer Internetsuche."
},
"PROTO-04": {
"title": "Mit dem Host {} wurde über einen nicht standardmäßigen Port ({}) per HTTP kommuniziert.",
"description": "Ihr Gerät hat mit dem Host {} über den Port {} über das unverschlüsselte HTTP-Protokoll kommuniziert. Dieses Verhalten ist recht ungewöhnlich. Bitte überprüfen Sie die Reputation des Hosts anhand einer Internetsuche."
},
"PROTO-05": {
"title": "Der Server {} wurde während der Sitzung nicht in einer DNS-Abfrage aufgelöst.",
"description": "Das bedeutet, dass der Server {} möglicherweise in keinen Domain-Namen aufgelöst wird oder dass die Auflösung bereits vom Gerät zwischengespeichert wurde. Wenn dieser Host in anderen Warnungen vorkommt, überprüfen Sie ihn bitte."
},
"IOC-01": {
"title": "Es wurde eine Verbindung zu {} hergestellt ({}), was als {} gekennzeichnet ist.",
"description": "Der Host {} wurde aufgrund bösartiger Aktivitäten explizit auf die Sperrliste gesetzt. Ihr Gerät ist wahrscheinlich kompromittiert und muss von IT-Sicherheitsexperten genauer untersucht werden."
},
"IOC-02": {
"title": "Kommunikation mit {} unter dem CIDR {}, der als {} gekennzeichnet ist.",
"description": "Der Server {} wird in einem Netzwerk gehostet, das für bösartige Aktivitäten bekannt ist. Auch wenn dieses Verhalten an sich nicht bösartig ist, müssen Sie überprüfen, ob dieser Host auch in anderen Warnungen erwähnt wird. Wenn Sie Zweifel haben, suchen Sie im Internet nach diesem Host, um zu sehen, ob er legitim ist."
},
"IOC-03": {
"title": "Es wurde eine DNS-Abfrage zu {} ausgeführt, was als {} gekennzeichnet ist.",
"description": "Der in der Aufnahme vorkommende Domain-Name {} wurde explizit als bösartig gekennzeichnet. Dies weist darauf hin, dass Ihr Gerät wahrscheinlich kompromittiert ist und eingehend untersucht werden muss."
},
"IOC-04": {
"title": "Es wurde eine DNS-Abfrage zu {} ausgeführt, was als {} gekennzeichnet ist.",
"description": "Der in der Aufnahme vorkommende Domain-Name {} wurde explizit als Tracker gekennzeichnet. Dies weist darauf hin, dass eine der aktiven Apps Ihren Standort geografisch verfolgt."
},
"IOC-05": {
"title": "Es wurde eine DNS-Abfrage zur Domain {} ausgeführt, die einen Free-DNS-Dienst nutzt.",
"description": "Der Domain-Name {} nutzt einen Free-DNS-Dienst. Dienste dieser Art werden häufig von Cyberkriminellen oder staatlich unterstützten Angreifern bei ihren Operationen genutzt. Es ist sehr verdächtig, dass eine im Hintergrund laufende Anwendung einen solchen Dienst verwendet. Bitte untersuchen Sie das näher."
},
"IOC-06": {
"title": "Es wurde eine DNS-Abfrage zur Domain {} ausgeführt, die eine verdächtige TLD enthält.",
"description": "Der Domain-Name {} nutzt eine verdächtige Top-Level-Domain ({}). Diese nicht-generische TLD ist zwar selbst nicht bösartig, wird aber häufig von Cyberkriminellen und bei staatlich unterstützten Operationen verwendet. Bitte überprüfen Sie diese Domain anhand einer Internetsuche. Wenn dieser Host in anderen Warnungen erwähnt wird, können Sie ihn als sehr verdächtig betrachten."
},
"IOC-07": {
"title": "Ein Zertifikat, das mit {} Aktivitäten verknüpft ist, wurde in der Kommunikationsverbindung zu {} gefunden.",
"description": "Das Zertifikat ({}), das mit {} verknüpft ist, wurde explizit als bösartig gekennzeichnet. Dies weist darauf hin, dass Ihr Gerät wahrscheinlich kompromittiert ist und eine forensische Analyse benötigt."
},
"IOC-08": {
"title": "Es wurde eine HTTP-Abfrage zu {} ausgeführt, was als {} gekennzeichnet ist.",
"description": "Der in der Aufnahme vorkommende Domain-Name {} wurde explizit als bösartig gekennzeichnet. Dies weist darauf hin, dass Ihr Gerät wahrscheinlich kompromittiert ist und eingehend untersucht werden muss."
},
"IOC-09": {
"title": "Es wurde eine HTTP-Abfrage zur Domain {} ausgeführt, die einen Free-DNS-Dienst nutzt.",
"description": "Der Domain-Name {} nutzt einen Free-DNS-Dienst. Dienste dieser Art werden häufig von Cyberkriminellen oder staatlich unterstützten Angreifern bei ihren Operationen genutzt. Es ist sehr verdächtig, dass eine im Hintergrund laufende Anwendung einen solchen Dienst verwendet. Bitte untersuchen Sie das näher."
},
"IOC-10": {
"title": "Es wurde eine HTTP-Abfrage zur Domain {} ausgeführt, die eine verdächtige TLD enthält.",
"description": "Der Domain-Name {} nutzt eine verdächtige Top-Level-Domain ({}). Diese nicht-generische TLD ist zwar selbst nicht bösartig, wird aber häufig von Cyberkriminellen und bei staatlich unterstützten Operationen verwendet. Bitte überprüfen Sie diese Domain anhand einer Internetsuche. Wenn dieser Host in anderen Warnungen erwähnt wird, können Sie ihn als sehr verdächtig betrachten."
},
"ACT-01": {
"title": "Die Domain {} nutzt einen verdächtigen Nameserver ({}).",
"description": "Der Domain-Name {} nutzt einen Nameserver, der explizit mit bösartigen Aktivitäten in Verbindung gebracht wird. Viele Cyberkriminelle und staatlich unterstützte Angreifer nutzen Registrare dieser Art, weil sie Kryptowährungen und anonyme Zahlungen zulassen. Es wird empfohlen, diese Domain und die damit verknüpfte laufende Anwendung mithilfe einer forensischen Analyse des Telefons näher zu untersuchen."
},
"ACT-02": {
"title": "Die Domain {} wurde vor kurzem (vor {} Tagen) erstellt.",
"description": "Der Domainname {} ist neu. Auch wenn dies nicht von Natur aus böswillig ist, richten Angreifer häufig für jede Kampagne eine neue Infrastruktur ein, die zur Verwendung neu registrierter Domainnamen führen kann."
},
"SSL-01": {
"title": "SSL-Verbindung über einen nicht standardmäßigen Port ({})",
"description": "Es ist ungewöhnlich, dass SSL-Verbindungen von Smartphones über einen nicht standardmäßigen Port hergestellt werden. Das kann durchaus legitim sein, aber wir empfehlen dennoch, die Reputation von {} zu überprüfen. Sehen Sie sich dazu den entsprechenden WHOIS-Eintrag, das zugehörige autonome System und das Erstellungsdatum an und suchen Sie im Internet danach."
},
"SSL-02": {
"title": "Eine SSL-Verbindung zu {} verwendet ein kostenloses Zertifikat.",
"description": "Kostenlose Zertifikate wie z. B. Let's Encrypt werden gerne von Command-and-Control-Servern verwendet, die mit bösartigen Implants und Phishing-Webseiten in Verbindung stehen. Wir empfehlen, den mit diesem Zertifikat verknüpften Host zu überprüfen. Sehen Sie sich dazu seinen Domain-Namen und das Erstellungsdatum an oder überprüfen Sie die Reputation des Hosts im Internet."
},
"SSL-03": {
"title": "Das mit {} verknüpfte Zertifikat ist selbstsigniert.",
"description": "Die Verwendung von selbstsignierten Zertifikaten ist in der Infrastruktur von Angreifern weit verbreitet. Wir empfehlen, den mit diesem Zertifikat verknüpften Host {} zu überprüfen. Sehen Sie sich dazu seinen Domain-Namen (falls vorhanden), den WHOIS-Eintrag und das Erstellungsdatum an und überprüfen Sie die Reputation des Hosts im Internet."
},
"SSL-04": {
"title": "Ein Zertifikat enthält den Domainnamen {}, der als {} kategorisiert ist",
"description": "Eines der ausgetauschten Zertifikate enthält den Domainnamen {}. Dieser Domainname wurde explizit als bösartig eingestuft. Ihr Gerät ist sicherlich kompromittiert und sollte von einem professionellen Team genauer untersucht werden."
},
"ADV-01": {
"title": "Überprüfen Sie die Warnungen für {}",
"description": "Bitte überprüfen Sie die Reputation des Hosts {}. Dieser scheint bösartig zu sein, da er während der Sitzung {} Warnungen verursacht hat."
},
"SNORT-01": {
"title": "Suricata-Regel ausgelöst: {}",
"description": "Eine Netzwerkerkennungsregel wurde ausgelöst. Es ist wahrscheinlich, dass Ihr Gerät kompromittiert wurde oder verdächtiges Verhalten aufweist."
}
},
"report": {
"numbers": [
"eine",
"zwei",
"drei",
"vier",
"fünf",
"sechs",
"sieben",
"acht",
"neun"
],
"suspect_title": "Verdächtige Kommunikationsverbindungen",
"uncat_title": "Kommunikationsverbindungen ohne Kategorie",
"whitelist_title": "Kommunikationsverbindungen auf der Zulassungsliste",
"protocol": "Protokoll",
"domain": "Domain",
"dst_ip": "Ziel-IP-Adresse",
"dst_port": "Ziel-Portnummer",
"device_name": "Gerätename",
"device_mac": "MAC-Adresse des Geräts",
"report_generated_on": "Bericht erstellt am",
"capture_duration": "Aufnahmedauer",
"packets_number": "Anzahl der Pakete",
"capture_sha1": "SHA1-Aufnahme",
"report_for_the_capture": "Bericht zur Aufnahme",
"report_footer": "Dieser Bericht wurde von einem TinyCheck-Gerät automatisch erstellt. Wenn Sie Fragen haben, Bugs melden oder Feedback geben möchten, kontaktieren Sie uns unter tinycheck@kaspersky.com.",
"high_msg": "Ihr Gerät scheint kompromittiert zu sein, da Sie {} Warnung(en) der Stufe \"Hoch\" haben.",
"moderate_msg": "Sie haben {} Warnungen der Stufe \"Mittel\": Ihr Gerät könnte kompromittiert sein. Bitte sehen Sie sich die Warnungen sorgfältig an.",
"low_msg": "Sie haben nur {} Warnungen der Stufe \"Niedrig\": Überprüfen Sie sie gerne.",
"none_msg": "Alles sieht gut aus kein Warnungen. Sehen Sie sich gerne auch die nicht kategorisierten Kommunikationsverbindungen an, falls welche vorhanden sind."
}
}

View File

@ -48,13 +48,25 @@
"title": "A certificate associated to {} activities have been found in the communication to {}.", "title": "A certificate associated to {} activities have been found in the communication to {}.",
"description": "The certificate ({}) associated to {} has been explicitly tagged as malicious. This indicates that your device is likely compromised and need a forensic analysis." "description": "The certificate ({}) associated to {} has been explicitly tagged as malicious. This indicates that your device is likely compromised and need a forensic analysis."
}, },
"IOC-08": {
"title": "An HTTP request have been done to {} which is tagged as {}.",
"description": "The domain name {} seen in the capture has been explicitly tagged as malicious. This indicates that your device is likely compromised and needs to be investigated deeply."
},
"IOC-09": {
"title": "An HTTP request have been done to the domain {} which is a Free DNS.",
"description": "The domain name {} is using a Free DNS service. This kind of service is commonly used by cybercriminals or state-sponsored threat actors during their operations. It is very suspicious that an application running in background use this kind of service, please investigate."
},
"IOC-10": {
"title": "An HTTP request have been done to the domain {} which contains a suspect TLD.",
"description": "The domain name {} is using a suspect Top Level Domain ({}). Even not malicious, this non-generic TLD is used regularly by cybercrime or state-sponsored operations. Please check this domain by searching it on an internet search engine. If other alerts are related to this host, please consider it as very suspicious."
},
"ACT-01": { "ACT-01": {
"title": "The domain {} is using a suspect nameserver ({}).", "title": "The domain {} is using a suspect nameserver ({}).",
"description": "The domain name {} is using a nameserver that has been explicitly tagged to be associated to malicious activities. Many cybercriminals and state-sponsored threat actors are using this kind of registrars because they allow cryptocurrencies and anonymous payments. It is adviced to investigate on this domain and the associated running application by doing a forensic analysis of the phone." "description": "The domain name {} is using a nameserver that has been explicitly tagged to be associated to malicious activities. Many cybercriminals and state-sponsored threat actors are using this kind of registrars because they allow cryptocurrencies and anonymous payments. It is adviced to investigate on this domain and the associated running application by doing a forensic analysis of the phone."
}, },
"ACT-02": { "ACT-02": {
"title": "The domain {} have been created quite recently ({} days ago).", "title": "The domain {} have been created quite recently ({} days ago).",
"description": "The domain name {} is quite new. Even this is not malicious by itself, its quite common for attackers to set up new infrastructure for each campaign which can lead to the use of recently registered domain names." "description": "The domain name {} is quite new. Even this is not malicious by itself, its quite common for attackers to set up new infrastructure for each attack campaign which can lead to the use of recently registered domain names."
}, },
"SSL-01": { "SSL-01": {
"title": "SSL connection done on a non standard port ({}) to {}", "title": "SSL connection done on a non standard port ({}) to {}",
@ -68,6 +80,10 @@
"title": "The certificate associated to {} is self-signed.", "title": "The certificate associated to {} is self-signed.",
"description": "The use of self-signed certificates is a common thing for attacker infrastructure. We recommend to check the host {} which is associated to this certificate, by looking at the domain name (if any), its WHOIS record, its creation date, and by checking its reputation on the internet." "description": "The use of self-signed certificates is a common thing for attacker infrastructure. We recommend to check the host {} which is associated to this certificate, by looking at the domain name (if any), its WHOIS record, its creation date, and by checking its reputation on the internet."
}, },
"SSL-04": {
"title": "A certificate contains the domain name {}, categorized as {}",
"description": "One of the certificates exchanged contains the domain name {}. This domain name has been explicitly classified as malicious. Your device is definitely compromised and should be investigated further by a professional team."
},
"ADV-01": { "ADV-01": {
"title": "Check the alerts for {}", "title": "Check the alerts for {}",
"description": "Please, check the reputation of the host {}, this one seems to be malicious as it leveraged {} alerts during the session." "description": "Please, check the reputation of the host {}, this one seems to be malicious as it leveraged {} alerts during the session."

View File

@ -48,6 +48,18 @@
"title": "Un certificado asociado a actividades {} ha sido identificado en una comunicación hacia {}.", "title": "Un certificado asociado a actividades {} ha sido identificado en una comunicación hacia {}.",
"description": "El certificado ({}) asociado a {} ha sido explícitamente etiquetado como malicioso. Esto indica que su dispositivo está probablemente comprometido y necesita ser analizado en profundidad por un especialista forense." "description": "El certificado ({}) asociado a {} ha sido explícitamente etiquetado como malicioso. Esto indica que su dispositivo está probablemente comprometido y necesita ser analizado en profundidad por un especialista forense."
}, },
"IOC-08": {
"title": "Se ha realizado una petición HTTP a {} que está etiquetada como {}.",
"description": "El dominio {} identificado en la captura ha sido explícitamente etiquetado como malicioso. Esto indica que su dispositivo está probablemente comprometido y debe ser investigado en profundidad."
},
"IOC-09": {
"title": "Se ha realizado una petición HTTP al dominio {} que es un DNS gratuito.",
"description": "El dominio {} está usando un servicio DNS gratuito. Este tipo de servicios es comúnmente utilizado por cibercriminales y otros actores de amenazas. Es altamente sospechoso que una aplicación ejecutándose en segundo plano use este tipo de servicios. Por favor investigue."
},
"IOC-10": {
"title": "Se ha realizado una petición HTTP al dominio {} que contiene un TLD sospechoso.",
"description": "El dominio {} está usando un dominio de primero nivel -TLD- ({}). Aunque no sea malicioso, este TLP no-genérico es usado por cibercriminales y otros actores de amenazas con regularidad. Verifique este dominio mediante su búsqueda en Internet. Si hay otras alertas relacionadas con este host, por favor considérelo como muy sospechoso."
},
"ACT-01": { "ACT-01": {
"title": "El dominio {} está usando un servidor de nombres sospechoso ({}).", "title": "El dominio {} está usando un servidor de nombres sospechoso ({}).",
"description": "El nombre de dominio {} usa un servidor de nombres que ha sido explícitamente etiquetado como asociado a actividad maliciosa. Muchos ciberdelincuentes y otros actores de amenazas utilizan este tipo de registradores ya que aceptan criptomonedas y pagos anónimos. Se recomienda investigar este dominio y la aplicación en ejecución asociada mediante un análisis forense del dispositivo." "description": "El nombre de dominio {} usa un servidor de nombres que ha sido explícitamente etiquetado como asociado a actividad maliciosa. Muchos ciberdelincuentes y otros actores de amenazas utilizan este tipo de registradores ya que aceptan criptomonedas y pagos anónimos. Se recomienda investigar este dominio y la aplicación en ejecución asociada mediante un análisis forense del dispositivo."
@ -68,6 +80,10 @@
"title": "El certificado asociado a {} es autofirmado.", "title": "El certificado asociado a {} es autofirmado.",
"description": "El uso de certificados autofirmados es un elemento común en infraestructuras utilizadas por atacantes. Recomendamos comprobar el host {} que está asociado a este certificado, especialmente su nombre de dominio (en caso de existir), su registro WHOIS, su fecha de creación y verificando su reputación en Internet." "description": "El uso de certificados autofirmados es un elemento común en infraestructuras utilizadas por atacantes. Recomendamos comprobar el host {} que está asociado a este certificado, especialmente su nombre de dominio (en caso de existir), su registro WHOIS, su fecha de creación y verificando su reputación en Internet."
}, },
"SSL-04": {
"title": "Un certificado contiene el nombre de dominio {}, categorizado como {}",
"description": "Uno de los certificados intercambiados contiene el nombre de dominio {}. Este nombre de dominio se ha clasificado explícitamente como malicioso. Su dispositivo está definitivamente comprometido y debe ser investigado más a fondo por un equipo profesional."
},
"ADV-01": { "ADV-01": {
"title": "Compruebe las alertas para {}", "title": "Compruebe las alertas para {}",
"description": "Por favor, verifique la reputación del host {}, ya que parece ser malicioso por aparecer en {} alertas durante la sesión." "description": "Por favor, verifique la reputación del host {}, ya que parece ser malicioso por aparecer en {} alertas durante la sesión."

View File

@ -48,6 +48,18 @@
"title": "Un certificat associé à des activités de {} a été vu lors de communications vers {}.", "title": "Un certificat associé à des activités de {} a été vu lors de communications vers {}.",
"description": "Le certificat ({}) associé au serveur {} a été explicitement catégorisé comme malveillant. Votre appareil est sûrement compromis et doit être investigué plus en détails par une équipe professionnelle." "description": "Le certificat ({}) associé au serveur {} a été explicitement catégorisé comme malveillant. Votre appareil est sûrement compromis et doit être investigué plus en détails par une équipe professionnelle."
}, },
"IOC-08": {
"title": "Requête HTTP vers le domaine {} qui est tagué en tant que {}.",
"description": "Le serveur {} vers lequel communique votre appareil a été explicitement catégorisé en tant que malveillant. Votre appareil est sûrement compromis et doit être investigué plus en détails par une équipe professionnelle."
},
"IOC-09": {
"title": "Requête HTTP vers le domaine {} qui est un domaine gratuit.",
"description": "Le nom de domaine {} utilise un service de noms de domaine gratuits. Ce type de service est couramment utilisé par les cybercriminels ou des acteurs associés à des États au cours de leurs opérations d'espionnage. Il est très suspect qu'une application exécutée en arrière-plan utilise ce type de service, veuillez enquêter."
},
"IOC-10": {
"title": "Requête HTTP vers le domaine {} contenant une extension suspecte.",
"description": "Le nom de domaine {} utilise une extension suspecte ({}). Même si cela n'est pas malveillant en-soi, l'utilisation d'une extension non générique est l'apanage d'acteurs cybercriminels et étatiques durant leurs opérations. Veuillez vérifier la pertinance de ce domaine en le recherchant sur un moteur de recherche Internet. Si d'autres alertes sont liées à ce dernier, veuillez le considérer comme très suspect."
},
"ACT-01": { "ACT-01": {
"title": "Le domaine {} utilise un serveur de noms suspect ({}).", "title": "Le domaine {} utilise un serveur de noms suspect ({}).",
"description": "Le nom de domaine {} utilise un serveur de noms qui a été explicitement catégorisé comme associé à des activités malveillantes. Plusieurs cybercriminels et acteurs étatiques utilisent ce type de serveurs de noms car ils autorisent les paiements anonymes grâce aux cryptomonnaies. Il est conseillé d'investiguer sur ce domaine et l'application s'y connectant en réalisant une analyse post-mortem de l'appareil analysé." "description": "Le nom de domaine {} utilise un serveur de noms qui a été explicitement catégorisé comme associé à des activités malveillantes. Plusieurs cybercriminels et acteurs étatiques utilisent ce type de serveurs de noms car ils autorisent les paiements anonymes grâce aux cryptomonnaies. Il est conseillé d'investiguer sur ce domaine et l'application s'y connectant en réalisant une analyse post-mortem de l'appareil analysé."
@ -68,6 +80,10 @@
"title": "Le certificat associé à {} est auto-signé.", "title": "Le certificat associé à {} est auto-signé.",
"description": "L'utilisation de certificats auto-signés est une chose courante pour des infrastructures d'attaque associées à des activités malveillantes. Nous vous recommandons de vérifier le serveur {} qui est associé à ce certificat, en regardant le nom de domaine (le cas échéant), son enregistrement WHOIS, sa date de création, et en vérifiant sa réputation sur Internet." "description": "L'utilisation de certificats auto-signés est une chose courante pour des infrastructures d'attaque associées à des activités malveillantes. Nous vous recommandons de vérifier le serveur {} qui est associé à ce certificat, en regardant le nom de domaine (le cas échéant), son enregistrement WHOIS, sa date de création, et en vérifiant sa réputation sur Internet."
}, },
"SSL-04": {
"title": "Un certificat contient le nom de domaine {}, catégorisé en tant que {}",
"description": "Un des certificats échangés contient le nom de domaine {}. Ce nom de domaine a été explicitement catégorisé en tant que malveillant. Votre appareil est sûrement compromis et doit être investigué plus en détails par une équipe professionnelle."
},
"ADV-01": { "ADV-01": {
"title": "Vérifiez les alertes liées au serveur {}", "title": "Vérifiez les alertes liées au serveur {}",
"description": "Merci de vérifier la réputation et les alertes liées au serveur {}, ce dernier semble malveillant, ayant engendré {} alertes durant la session de capture." "description": "Merci de vérifier la réputation et les alertes liées au serveur {}, ce dernier semble malveillant, ayant engendré {} alertes durant la session de capture."

128
analysis/locales/it.json Normal file
View File

@ -0,0 +1,128 @@
{
"alerts": {
"PROTO-01": {
"title": "{} comunicazione in uscita dalla rete locale a {}.",
"description": "Il protocollo {} è comunemente utilizzato nelle reti interne. Verificare se l'host {} ha sfruttato altri avvisi, fattore che potrebbe indicare un possibile comportamento dannoso."
},
"PROTO-02": {
"title": "{} connessione a {} tramite una porta superiore o uguale a {}.",
"description": "Sono state rilevate {} connessioni a {} tramite la porta {}. L'utilizzo di una porta non standard a volte può essere associato ad attività dannose. È consigliabile verificare se questo host ha una buona reputazione esaminando altri avvisi ed effettuando una ricerca in Internet."
},
"PROTO-03": {
"title": "Sono state generate comunicazioni HTTP dirette all'host {}",
"description": "Il dispositivo ha effettuato uno scambio con l'host {} utilizzando HTTP, un protocollo non criptato. Anche se questo comportamento non è dannoso in sé, è raro rilevare comunicazioni HTTP generate da applicazioni per smartphone in esecuzione in background. Controllare la reputazione dell'host effettuando una ricerca in Internet."
},
"PROTO-04": {
"title": "Sono state rilevate comunicazioni HTTP dirette all'host {} su una porta non standard ({}).",
"description": "Il dispositivo ha effettuato uno scambio con l'host {} utilizzando HTTP, un protocollo non criptato sulla porta {}. Questo comportamento è decisamente insolito. Controllare la reputazione dell'host effettuando una ricerca in Internet."
},
"PROTO-05": {
"title": "Il server {} non è stato risolto da nessuna query DNS durante la sessione",
"description": "Questo indica che il server {} probabilmente non è stato risolto da nessun nome di dominio o che la risoluzione è già stata memorizzata nella cache dal dispositivo. Se l'host viene visualizzato in altri avvisi, controllarlo."
},
"IOC-01": {
"title": "È stata stabilita una connessione a {} ({}) con contrassegno {}.",
"description": "L'host {} è stato esplicitamente inserito nella blacklist per attività dannose. Probabilmente il dispositivo è compromesso e deve essere esaminato più a fondo da professionisti della sicurezza IT."
},
"IOC-02": {
"title": "Comunicazione a {} con il CIDR {} con contrassegno {}.",
"description": "Il server {} è ospitato in una rete nota per l'hosting di attività dannose. Nonostante questo comportamento non sia dannoso in sé, è necessario verificare se l'host è menzionato anche in altri avvisi. In caso di dubbi, cercare l'host in Internet per scoprire se è legittimo o meno."
},
"IOC-03": {
"title": "È stata effettuata una richiesta DNS a {} con contrassegno {}.",
"description": "Il nome di dominio {} visualizzato nell'acquisizione è stato esplicitamente contrassegnato come dannoso. Questo indica che il dispositivo è potenzialmente compromesso e deve essere esaminato a fondo."
},
"IOC-04": {
"title": "È stata effettuata una richiesta DNS a {} con contrassegno {}.",
"description": "Il nome di dominio {} visualizzato nell'acquisizione è stato esplicitamente contrassegnato come Tracker. Questo indica che una delle app attive esegue la geolocalizzazione dei movimenti dell'utente."
},
"IOC-05": {
"title": "È stata effettuata una richiesta DNS al dominio {} che è un servizio Free DNS.",
"description": "Il nome di dominio {} utilizza un servizio Free DNS. Questo tipo di servizio è comunemente utilizzato durante le operazioni di criminali informatici o autori di attacchi commissionati da stati esteri. L'utilizzo di questo tipo di servizio da parte di un'applicazione in esecuzione in background è molto sospetto e richiede ulteriori indagini."
},
"IOC-06": {
"title": "È stata effettuata una richiesta DNS al dominio {} contenente un dominio di primo livello sospetto.",
"description": "Il nome di dominio {} utilizza un dominio di primo livello sospetto ({}). Anche se non dannoso, questo dominio di primo livello non generico viene utilizzato regolarmente durante le operazioni di criminali informatici o autori di attacchi commissionati da stati esteri. Controllare questo dominio effettuando una ricerca tramite un motore di ricerca Internet. Se altri avvisi sono correlati all'host, è necessario considerare questo elemento molto sospetto."
},
"IOC-07": {
"title": "Nella comunicazione a {} è stato rilevato un certificato associato ad attività {}.",
"description": "Il certificato ({}) associato a {} è stato esplicitamente contrassegnato come dannoso. Questo indica che il dispositivo è potenzialmente compromesso e necessita di un'analisi forense."
},
"IOC-08": {
"title": "È stata effettuata una richiesta HTTP a {} con contrassegno {}.",
"description": "Il nome di dominio {} visualizzato nell'acquisizione è stato esplicitamente contrassegnato come dannoso. Questo indica che il dispositivo è potenzialmente compromesso e deve essere esaminato a fondo."
},
"IOC-09": {
"title": "È stata effettuata una richiesta HTTP al dominio {} che è un servizio Free DNS.",
"description": "Il nome di dominio {} utilizza un servizio Free DNS. Questo tipo di servizio è comunemente utilizzato durante le operazioni di criminali informatici o autori di attacchi commissionati da stati esteri. L'utilizzo di questo tipo di servizio da parte di un'applicazione in esecuzione in background è molto sospetto e richiede ulteriori indagini."
},
"IOC-10": {
"title": "È stata effettuata una richiesta HTTP al dominio {} contenente un dominio di primo livello sospetto.",
"description": "Il nome di dominio {} utilizza un dominio di primo livello sospetto ({}). Anche se non dannoso, questo dominio di primo livello non generico viene utilizzato regolarmente durante le operazioni di criminali informatici o autori di attacchi commissionati da stati esteri. Controllare questo dominio effettuando una ricerca tramite un motore di ricerca Internet. Se altri avvisi sono correlati all'host, è necessario considerare questo elemento molto sospetto."
},
"ACT-01": {
"title": "Il dominio {} utilizza un server dei nomi sospetto ({}).",
"description": "Il nome di dominio {} utilizza un server dei nomi che è stato esplicitamente contrassegnato come associato ad attività dannose. Molti criminali informatici e autori di attacchi commissionati da stati esteri utilizzano questo tipo di registrar poiché sono ammessi criptovalute e pagamenti anonimi. È consigliabile indagare su questo dominio e sull'applicazione in esecuzione associata eseguendo un'analisi forense del telefono."
},
"ACT-02": {
"title": "Il dominio {} è stato creato di recente ({} giorni fa)",
"description": "Il nome di dominio {} è nuovo. Anche questo non è intrinsecamente dannoso, è abbastanza comune per gli aggressori impostare una nuova infrastruttura per ogni campagna, che può portare all'uso di nomi di dominio appena registrati."
},
"SSL-01": {
"title": "Connessione SSL eseguita su una porta non standard ({}) a {}",
"description": "Non è comune rilevare connessioni SSL generate da smartphone tramite porte non standard. Anche se questo può essere del tutto legittimo, è consigliabile controllare la reputazione di {} prestando attenzione al record WHOIS, al sistema autonomo associato e alla data di creazione, nonché effettuando una ricerca in Internet."
},
"SSL-02": {
"title": "Una connessione SSL a {} utilizza un certificato gratuito.",
"description": "I certificati gratuiti, come Let's Encrypt, sono ampiamente utilizzati dai server di comando e controllo associati a insediamenti dannosi o pagine Web di phishing. È consigliabile controllare l'host associato a questo certificato, prestando attenzione al nome di dominio e alla data di creazione o verificandone la reputazione in Internet."
},
"SSL-03": {
"title": "Il certificato associato a {} è autofirmato.",
"description": "L'utilizzo di certificati autofirmati è una consuetudine per l'infrastruttura degli autori degli attacchi. È consigliabile controllare l'host {} associato a questo certificato, prestando attenzione all'eventuale nome di dominio, al record WHOIS e alla data di creazione, nonché verificandone la reputazione in Internet."
},
"SSL-04": {
"title": "Un certificato contiene il nome di dominio {}, classificato come {}",
"description": "Uno dei certificati scambiati contiene il nome di dominio {}. Questo nome di dominio è stato esplicitamente classificato come dannoso. Il tuo dispositivo è decisamente compromesso e dovrebbe essere esaminato ulteriormente da un team di professionisti."
},
"ADV-01": {
"title": "Controllare gli avvisi per {}",
"description": "Controllare la reputazione dell'host {}, che sembra di natura dannosa poiché ha sfruttato {} avvisi durante la sessione."
},
"SNORT-01": {
"title": "Regola Suricata attivata: {}",
"description": "È stata attivata una regola di rilevamento della rete. È probabile che il dispositivo sia stato compromesso o che presenti comportamenti sospetti."
}
},
"report": {
"numbers": [
"uno",
"due",
"tre",
"quattro",
"cinque",
"sei",
"sette",
"otto",
"nove"
],
"suspect_title": "Comunicazioni sospette",
"uncat_title": "Comunicazioni non categorizzate",
"whitelist_title": "Comunicazioni inserite nella whitelist",
"protocol": "Protocollo",
"domain": "Dominio",
"dst_ip": "Indirizzo IP di destinazione",
"dst_port": "Numero della porta di destinazione",
"device_name": "Nome dispositivo",
"device_mac": "Indirizzo MAC dispositivo",
"report_generated_on": "Rapporto generato in data",
"capture_duration": "Durata acquisizione",
"packets_number": "Numero di pacchetti",
"capture_sha1": "SHA1 acquisizione",
"report_for_the_capture": "Rapporto relativo all'acquisizione",
"report_footer": "Questo rapporto è stato generato automaticamente da un dispositivo Tinycheck. Per eventuali domande, segnalazioni di bug o feedback, contattare tinycheck@kaspersky.com.",
"high_msg": "Sembra che il dispositivo sia compromesso poiché sono presenti {} avvisi con priorità elevata.",
"moderate_msg": "Sono presenti {} avvisi con priorità moderata, è possibile che il dispositivo sia compromesso. Esaminarli con attenzione.",
"low_msg": "Sono presenti solo {} avvisi con priorità bassa da controllare.",
"none_msg": "Sembra tutto a posto, non sono presenti avvisi. Controllare eventuali comunicazioni non categorizzate."
}
}

128
analysis/locales/pt.json Normal file
View File

@ -0,0 +1,128 @@
{
"alerts": {
"PROTO-01": {
"title": "Comunicação {} externa à rede local para {}.",
"description": "O protocolo {} é comumente usado em redes internas. Verifique se o host {} acionou outros alertas que possam indicar um possível comportamento malicioso."
},
"PROTO-02": {
"title": "Conexão {} a {} para uma porta maior ou igual a {}.",
"description": "Conexões {} foram detectadas por {} usando a porta {}. O uso da porta não padrão é comumente associado a atividades maliciosas. É recomendado verificar se esse host tem uma boa reputação verificando outros alertas e pesquisando-o na internet."
},
"PROTO-03": {
"title": "Comunicações HTTP foram realizadas com o host {}",
"description": "O dispositivo foi conectado ao host {} por meio de HTTP, um protocolo não criptografado. Mesmo que esse comportamento, por si só, não seja malicioso, é incomum que comunicações HTTP sejam estabelecidas por meio de aplicativos móveis em segundo plano. Verifique a reputação do host pesquisando-o na Internet."
},
"PROTO-04": {
"title": "Comunicações HTTP foram detectadas pelo host {} por meio de uma porta não padrão ({}).",
"description": "O dispositivo foi conectado ao host {} por meio de HTTP, um protocolo não criptografado na porta {}. Esse comportamento é incomum. Verifique a reputação do host pesquisando-o na Internet."
},
"PROTO-05": {
"title": "O servidor {} não foi resolvido por nenhuma consulta de DNS durante a sessão",
"description": "Isso significa provavelmente que o servidor {} não foi resolvido por nenhum nome de domínio ou a resolução já foi armazenada pelo dispositivo. Se o host aparecer em outros alertas, verifique-os."
},
"IOC-01": {
"title": "Uma conexão foi estabelecida com {} ({}) e marcada como {}.",
"description": "O host {} foi explicitamente bloqueado devido a atividades maliciosas. O dispositivo provavelmente foi comprometido e precisa ser analisado com cuidado por profissionais de segurança de TI."
},
"IOC-02": {
"title": "Comunicação com {} com o CIDR {} marcado como {}.",
"description": "O host {} está hospedado em uma rede que é conhecida por atividades maliciosas. Mesmo que o comportamento, por si só, não seja malicioso, é necessário verificar se outros alertas são gerados para esse host. Em caso de dúvidas, pesquise esse host na internet para verificar sua autenticidade."
},
"IOC-03": {
"title": "Uma solicitação de DNS foi feita para {}, marcado como {}.",
"description": "O nome de domínio {} visto na captura foi explicitamente marcado como malicioso. Isso indica que o dispositivo provavelmente foi comprometido e precisa ser analisado com cuidado."
},
"IOC-04": {
"title": "Uma solicitação de DNS foi feita para {}, marcado como {}.",
"description": "O nome de domínio {} visto na captura foi explicitamente marcado como um Tracker. Isso indica que um dos aplicativos ativos está rastreando sua localização."
},
"IOC-05": {
"title": "Uma solicitação de DNS foi feita para o domínio {}, que é um DNS gratuito.",
"description": "O nome de domínio {} está usando um serviço de DNS gratuito. Esse tipo de serviço é comumente usado por cibercriminosos ou agências de inteligência estatais no exercício de suas funções. É muito suspeito que aplicativos em execução em segundo plano usem esse tipo de serviço e isso deve ser analisado com cuidado."
},
"IOC-06": {
"title": "Uma solicitação de DNS foi feita para o domínio {}, que contém um TLD (domínio de nível superior) suspeito.",
"description": "O nome de domínio {} está usando um TLD suspeito ({}). Mesmo não sendo malicioso, esse TLD não genérico é frequentemente usado por cibercriminosos ou agências de inteligência estatais. Analise a reputação do domínio pesquisando-o na internet. Se outros alertas forem observados, considere esse host como muito suspeito."
},
"IOC-07": {
"title": "Um certificado associado a atividades de {} foi encontrado na comunicação para {}.",
"description": "O certificado ({}) associado a {} foi explicitamente marcado como malicioso. Isso indica que o dispositivo provavelmente foi comprometido e precisa de uma análise forense."
},
"IOC-08": {
"title": "Uma solicitação de HTTP foi feita para {}, marcado como {}.",
"description": "O nome de domínio {} visto na captura foi explicitamente marcado como malicioso. Isso indica que o dispositivo provavelmente foi comprometido e precisa ser analisado com cuidado."
},
"IOC-09": {
"title": "Uma solicitação de HTTP foi feita para o domínio {}, que é um DNS gratuito.",
"description": "O nome de domínio {} está usando um serviço de DNS gratuito. Esse tipo de serviço é comumente usado por cibercriminosos ou agências de inteligência estatais no exercício de suas funções. É muito suspeito que aplicativos em execução em segundo plano usem esse tipo de serviço e isso deve ser analisado com cuidado."
},
"IOC-10": {
"title": "Uma solicitação de HTTP foi feita para o domínio {}, que contém um TLD (domínio de nível superior) suspeito.",
"description": "O nome de domínio {} está usando um TLD suspeito ({}). Mesmo não sendo malicioso, esse TLD não genérico é frequentemente usado por cibercriminosos ou agências de inteligência estatais. Analise a reputação do domínio pesquisando-o na internet. Se outros alertas forem observados, considere esse host como muito suspeito."
},
"ACT-01": {
"title": "O domínio {} está usando um servidor de nomes suspeito ({}).",
"description": "O nome de domínio {} está usando um servidor de nomes explicitamente marcado como associado a atividades maliciosas. Muitos cibercriminosos e agentes de inteligência estatais usam esse tipo de registradores porque isso permite pagamentos com criptomoedas e anônimos. É recomendável investigar esse domínio e o aplicativo em execução por meio de uma análise forense do telefone."
},
"ACT-02": {
"title": "O domínio {} foi criado recentemente ({} dias atrás).",
"description": "O nome de domínio {} é novo. Mesmo que isso não seja intrinsecamente malicioso, é bastante comum que os invasores configurem uma nova infraestrutura para cada campanha, o que pode levar ao uso de nomes de domínio recém-registrados."
},
"SSL-01": {
"title": "Conexão SSL feita em uma porta não padrão ({}) para {}",
"description": "Não é comum ver conexões SSL a partir de dispositivos móveis usando portas não padrão. Mesmo que a conexão pareça ser autêntica, é recomendável analisar a reputação de {} verificando pesquisando na internet o registro de domínio, o sistema autônomo associado e a data de criação."
},
"SSL-02": {
"title": "Uma conexão SSL com {} está usando um certificado gratuito.",
"description": "Certificados gratuitos, como o Let's Encrypt, são amplamente usados por servidores de comando e controle associados a arquivos maliciosos ou páginas de phishing. É recomendável analisar o host associado a esse certificado verificando o nome de domínio, a data de criação ou pesquisando sua reputação na internet."
},
"SSL-03": {
"title": "O certificado associado a {} é autoassinado.",
"description": "O uso de certificados autoassinados é comum na infraestrutura de invasores. É recomendável analisar o host {} que está associado a esse certificado verificando o nome e o registro de domínio (se houver), a data de criação e sua reputação na internet."
},
"SSL-04": {
"title": "Um certificado contém o nome de domínio {}, categorizado como {}",
"description": "Um dos certificados trocados contém o nome de domínio {}. Este nome de domínio foi explicitamente classificado como malicioso. Seu dispositivo está definitivamente comprometido e deve ser investigado por uma equipe profissional."
},
"ADV-01": {
"title": "Verifique os alertas para {}",
"description": "Verifique a reputação do host {}, este parece ser malicioso, pois acionou alertas para {} durante a sessão."
},
"SNORT-01": {
"title": "Regra do Suricata acionada: {}",
"description": "Uma regra de detecção de rede foi acionada. É provável que o dispositivo tenha sido comprometido ou apresente comportamento suspeito."
}
},
"report": {
"numbers": [
"um",
"dois",
"três",
"quatro",
"cinco",
"seis",
"sete",
"oito",
"nove"
],
"suspect_title": "Comunicações suspeitas",
"uncat_title": "Comunicações não categorizadas",
"whitelist_title": "Comunicações permitidas",
"protocol": "Protocolo",
"domain": "Domínio",
"dst_ip": "Endereço IP do dst",
"dst_port": "Número da porta do dst",
"device_name": "Nome do dispositivo",
"device_mac": "Endereço MAC do dispositivo",
"report_generated_on": "Relatório criado em",
"capture_duration": "Duração da captura",
"packets_number": "Número de pacotes",
"capture_sha1": "Captura SHA1",
"report_for_the_capture": "Relatório da captura",
"report_footer": "Este relatório foi gerado automaticamente por um dispositivo Tinycheck. Em caso de dúvidas, relatório de erros ou comentários, envie uma mensagem para tinycheck@kaspersky.com.",
"high_msg": "O dispositivo parece estar comprometido porque você tem {} alerta(s) crítico(s).",
"moderate_msg": "Você tem {} alerta(s) moderado(s), seu dispositivo pode estar comprometido. Analise-os com cuidado.",
"low_msg": "Você tem apenas {} alerta(s) leve(s), não deixe de verificá-los.",
"none_msg": "Tudo parece estar bem, zero alertas. Não deixe de verificar comunicações não categorizadas, se houver."
}
}

128
analysis/locales/ru.json Normal file
View File

@ -0,0 +1,128 @@
{
"alerts": {
"PROTO-01": {
"title": "Обнаружено подключение {}, ведущее за пределы локальной сети к {}.",
"description": "Протокол {} обычно используется во внутренних сетях. Проверьте, выдавало ли устройство {} другие предупреждения, которые могут свидетельствовать о вредоносной активности."
},
"PROTO-02": {
"title": "Подключение {} к {} установлено на порте, равном или более {}.",
"description": "Обнаружено {} подключений к {} с использованием порта {}. Использование нестандартного порта иногда может свидетельствовать о вредоносной активности. Рекомендуется проверить репутацию этого устройства, просмотрев другие предупреждения и выполнив их поиск в интернете."
},
"PROTO-03": {
"title": "Установлено HTTP-подключение к устройству {}",
"description": "Ваше устройство обменивается данными с устройством {} по незашифрованному протоколу HTTP. Даже если такое поведение само по себе не является вредоносным, фоновое исходящее HTTP-подключение является нетипичным для приложений, работающих на смартфоне в фоновом режиме. Проверьте репутацию устройства, выполнив поиск в интернете."
},
"PROTO-04": {
"title": "Установлено HTTP-подключение к устройству {} через нестандартный порт ({}).",
"description": "Ваше устройство обменивается данными с устройством {} по незашифрованному протоколу HTTP через порт {}. Такое поведение является нетипичным. Проверьте репутацию устройства, выполнив поиск в интернете."
},
"PROTO-05": {
"title": "Сервер {} не разрешался никакими DNS-запросами во время сеанса",
"description": "Это, вероятно, означает, что сервер {} не разрешен ни одним доменным именем или разрешение уже кешировано устройством. Если устройство фигурирует в других предупреждениях, проверьте его."
},
"IOC-01": {
"title": "Установлено соединение с {} ({}), отмеченным как {}.",
"description": "Устройство {} было явно занесено в черный список за выполнение вредоносных действий. Ваше устройство, вероятно, взломано. Требуется более тщательное расследование специалистами по IT-безопасности."
},
"IOC-02": {
"title": "Подключение к {}, отмеченному как {}, в рамках бесклассовой адресации {}.",
"description": "Сервер {} размещен в сети, в которой размещаются объекты, выполняющие вредоносные действия. Даже если такое поведение само по себе не является вредоносным, необходимо проверить, не упоминается ли это устройство в других предупреждениях. При наличии сомнений выполните поиск этого устройства в интернете и выясните, является ли его поведение легитимным."
},
"IOC-03": {
"title": "Выполнен DNS-запрос к {}, отмеченному как {}.",
"description": "Доменное имя {}, обнаруженное при сборе данных, явно отмечено как вредоносное. Это указывает на то, что ваше устройство, вероятно, взломано и требуется тщательное расследование."
},
"IOC-04": {
"title": "Выполнен DNS-запрос к {}, отмеченному как {}.",
"description": "Доменное имя {}, обнаруженное при сборе данных, явно отмечено как геотрекер. Это указывает, что одно из активных приложений отслеживает ваши перемещения."
},
"IOC-05": {
"title": "Выполнен DNS-запрос к домену {}, использующему бесплатную службу DNS.",
"description": "Доменное имя {} использует бесплатную службу DNS. Такие службы обычно используются киберпреступниками или спонсируемыми государством злоумышленниками для атак. Очень подозрительно, что приложение, работающее в фоновом режиме, использует такую службу. Требуется расследование."
},
"IOC-06": {
"title": "Выполнен DNS-запрос к домену {}, содержащему подозрительный домен верхнего уровня.",
"description": "Доменное имя {} использует подозрительный домен верхнего уровня ({}). Даже не являясь вредоносным, этот не универсальный домен верхнего уровня регулярно используется киберпреступниками или спонсируемыми государством злоумышленниками. Проверьте этот домен, выполнив поиск в интернете. Если с этим устройством связаны другие предупреждения, это очень подозрительно."
},
"IOC-07": {
"title": "Сертификат, связанный с действиями {}, был обнаружен при взаимодействии с {}.",
"description": "Сертификат ({}), связанный с {}, явно отмечен как вредоносный. Это указывает на то, что ваше устройство, вероятно, взломано и требуется провести экспертный анализ."
},
"IOC-08": {
"title": "Выполнен HTTP-запрос к {}, отмеченному как {}.",
"description": "Доменное имя {}, обнаруженное при сборе данных, явно отмечено как вредоносное. Это указывает на то, что ваше устройство, вероятно, взломано и требуется тщательное расследование."
},
"IOC-09": {
"title": "Выполнен HTTP-запрос к домену {}, использующему бесплатную службу DNS.",
"description": "Доменное имя {} использует бесплатную службу DNS. Такие службы обычно используются киберпреступниками или спонсируемыми государством злоумышленниками для атак. Очень подозрительно, что приложение, работающее в фоновом режиме, использует такую службу. Требуется расследование."
},
"IOC-10": {
"title": "Выполнен HTTP-запрос к домену {}, содержащему подозрительный домен верхнего уровня.",
"description": "Доменное имя {} использует подозрительный домен верхнего уровня ({}). Даже не являясь вредоносным, этот не универсальный домен верхнего уровня регулярно используется киберпреступниками или спонсируемыми государством злоумышленниками. Проверьте этот домен, выполнив поиск в интернете. Если с этим устройством связаны другие предупреждения, это очень подозрительно."
},
"ACT-01": {
"title": "Домен {} использует подозрительный сервер имен ({}).",
"description": "Доменное имя {} использует сервер имен, который явно отмечен как связанный с вредоносными действиями. Многие киберпреступники и спонсируемые государством злоумышленники пользуются такими регистраторами, поскольку они позволяют использовать криптовалюту и анонимные платежи. Рекомендуется исследовать этот домен и связанные с ним работающие приложения, выполнив экспертный анализ телефона."
},
"ACT-02": {
"title": "Домен {} был создан недавно ({} дней назад).",
"description": "Доменное имя {} новое. Даже это не является вредоносным по своей сути, злоумышленники довольно часто создают новую инфраструктуру для каждой кампании атаки, что может привести к использованию недавно зарегистрированных доменных имен."
},
"SSL-01": {
"title": "SSL-подключение к {} выполнено через нестандартный порт ({})",
"description": "SSL-подключение со смартфонов с использованием нестандартных портов является нетипичным. Даже если это действие является абсолютно легитимным, рекомендуется проверить репутацию {}, просмотрев его запись WHOIS, связанную автономную систему, дату создания, а также выполнив поиск в интернете."
},
"SSL-02": {
"title": "SSL-подключение к {} использует бесплатный сертификат.",
"description": "Бесплатные сертификаты, такие как Let's Encrypt, широко используются командными серверами, связанными со встраиваемым вредоносным кодом или фишинговыми веб-страницами. Рекомендуется проверить устройство, связанное с этим сертификатом, изучив его доменное имя, дату создания и репутацию в интернете."
},
"SSL-03": {
"title": "Сертификат, связанный с {}, является самоподписанным.",
"description": "Использование самоподписанных сертификатов типично для инфраструктуры злоумышленников. Рекомендуется проверить устройство {}, связанное с этим сертификатом, изучив его доменное имя (если имеется), запись WHOIS, дату создания и репутацию в интернете."
},
"SSL-04": {
"title": "Сертификат содержит доменное имя {}, относящееся к категории {}",
"description": "Один из обмениваемых сертификатов содержит доменное имя {}. Это доменное имя явно классифицировано как вредоносное. Ваше устройство определенно взломано и должно быть исследовано профессиональной группой."
},
"ADV-01": {
"title": "Проверьте предупреждения для {}",
"description": "Проверьте репутацию устройства {}. Оно кажется вредоносным, поскольку для него сработало {} предупрежд. во время сеанса."
},
"SNORT-01": {
"title": "Сработало правило Suricata: {}",
"description": "Сработало правило обнаружения в сети. Вероятно, ваше устройство взломано или ведет себя подозрительно."
}
},
"report": {
"numbers": [
"один",
"два",
"три",
"четыре",
"пять",
"шесть",
"семь",
"восемь",
"девять"
],
"suspect_title": "Подозрительные подключения",
"uncat_title": "Неклассифицированные подключения",
"whitelist_title": "Разрешенные подключения",
"protocol": "Протокол",
"domain": "Домен",
"dst_ip": "IP-адрес назначения",
"dst_port": "Номер порта назначения",
"device_name": "Имя устройства",
"device_mac": "MAC-адрес устройства",
"report_generated_on": "Дата формирования отчета",
"capture_duration": "Продолжительность сбора данных",
"packets_number": "Количество пакетов",
"capture_sha1": "Сбор данных SHA1",
"report_for_the_capture": "Отчет для сбора данных",
"report_footer": "Этот отчет был автоматически сформирован устройством TinyCheck. С любыми вопросами, сообщениями об ошибках или отзывами обращайтесь по адресу tinycheck@kaspersky.com.",
"high_msg": "Вероятно, ваше устройство взломано, поскольку у вас {} предупрежд. высокого уровня.",
"moderate_msg": "У вас {} предупрежд. среднего уровня. Возможно, ваше устройство взломано. Внимательно изучите их.",
"low_msg": "У вас {} предупрежд. низкого уровня, проверьте их.",
"none_msg": "Предупреждения отсутствуют, система выглядит защищенной. Не забывайте проверять неклассифицированные подключения, если они имеются."
}
}

128
analysis/locales/sk.json Normal file
View File

@ -0,0 +1,128 @@
{
"alerts": {
"PROTO-01": {
"title": "{} komunikácia smeruje mimo lokálnej siete do {}.",
"description": "Protokol {} sa bežne používa v interných sieťach. Skontrolujte, či hostiteľ {} nevygeneroval iné upozornenia, ktoré môžu naznačovať škodlivé správanie."
},
"PROTO-02": {
"title": "{} pripojenie k {} cez port väčší alebo rovný {}.",
"description": "Zistili sa {} pripojenia k {} na porte {}. Použitie neštandardného portu je niekedy vodítkom pre škodlivú aktivitu. Odporúčame vám skontrolovať reputáciu tohto hostiteľa pomocou vyhľadania na internete."
},
"PROTO-03": {
"title": "Komunikácia HTTP bola uskutočnená s hostiteľom {}",
"description": "Vaše zariadenie komunikovalo s hostiteľom {} pomocou nešifrovaného protokolu HTTP. Aj keď toto správanie nie je samo o sebe škodlivé, nie je bežné, aby aplikácie smartfónu spustené na pozadí vytvárali komunikáciu HTTP. Skontrolujte reputáciu hostiteľa pomocou vyhľadania na internete."
},
"PROTO-04": {
"title": "S hostiteľom {} sa komunikovalo cez HTTP cez neštandardný port ({}).",
"description": "Vaše zariadenie komunikovalo s hostiteľom {} cez port {} pomocou nešifrovaného protokolu HTTP. Toto správanie je dosť nezvyčajné. Overte si reputáciu hostiteľa pomocou vyhľadania na internete."
},
"PROTO-05": {
"title": "Server {} nebol vyriešený v požiadavke DNS počas relácie.",
"description": "To znamená, že server {} pravdepodobne nie je riešený žiadnym názvom domény alebo toto rozlíšenie už zariadenie uložilo do vyrovnávacej pamäte. Ak sa hostiteľ zobrazuje v iných upozorneniach, skontrolujte ho."
},
"IOC-01": {
"title": "Bolo vytvorené pripojenie k {} ({}), ktoré je označené ako {}.",
"description": "Hostiteľ {} bol explicitne zaradený na čiernu listinu kvôli škodlivej aktivite. Vaše zariadenie je pravdepodobne napadnuté a vyžaduje ďalšie preskúmanie odborníkmi na bezpečnosť IT."
},
"IOC-02": {
"title": "Komunikácia s {} v rámci CIDR {}, ktorý je označený ako {}.",
"description": "Server {} je hosťovaný v sieti známej škodlivou aktivitou. Aj keď toto správanie nie je vo svojej podstate škodlivé, mali by ste skontrolovať, či sa o tomto hostiteľovi nezmieňujú iné upozornenia. Ak máte pochybnosti, vyhľadajte tohto hostiteľa na internete, aby ste zistili, či je legitímny."
},
"IOC-03": {
"title": "DNS požiadavka bola vytvorená pre {}, ktorý je označený ako {}.",
"description": "Názov domény {} v zázname bol výslovne označený ako škodlivý. To znamená, že vaše zariadenie je pravdepodobne napadnuté a je potrebné ho ďalej preskúmať."
},
"IOC-04": {
"title": "DNS požiadavka bola vytvorená pre {}, ktorý je označený ako {}.",
"description": "Názov domény {} zobrazený v zázname bol explicitne označený ako tracker. Znamená to, že jedna z aktívnych aplikácií geograficky sleduje Vašu polohu."
},
"IOC-05": {
"title": "DNS požiadavka bola vytvorená pre doménu {} pomocou bezplatnej služby DNS.",
"description": "Názov domény {} používa bezplatnú službu DNS. Služby tohto typu často využívajú pri svojich operáciách počítačoví zločinci alebo útočníci podporovaní vládou. Je veľmi podozrivé, že aplikácia spustená na pozadí používa takúto službu. Preskúmajte to podrobnejšie."
},
"IOC-06": {
"title": "Bola vykonaná DNS požiadavka pre doménu {} obsahujúca podozrivú TLD.",
"description": "Názov domény {} používa podozrivú doménu najvyššej úrovne ({}). Aj keď nie je sama o sebe škodlivá, túto negenerickú TLD bežne používajú kyberzločinci a vládami sponzorované operácie. Overte túto doménu pomocou vyhľadania na internete. Ak je tento hostiteľ spomenutý v iných upozorneniach, považujte to za veľmi podozrivé."
},
"IOC-07": {
"title": "Certifikát priradený k {} aktivitám sa našiel v komunikácii s {}.",
"description": "Certifikát ({}) priradený k {} bol explicitne označený ako škodlivý. Znamená to, že vaše zariadenie je pravdepodobne napadnuté a potrebuje forenznú analýzu."
},
"IOC-08": {
"title": "Na {} bola odoslaná požiadavka HTTP, ktorá je označená ako {}.",
"description": "Názov domény {} zobrazený v zázname bol výslovne označený ako škodlivý. To znamená, že Vaše zariadenie je pravdepodobne napadnuté a vyžaduje si dôkladnú analýzu."
},
"IOC-09": {
"title": "Do domény {} bola uskutočnená požiadavka HTTP pomocou bezplatnej služby DNS.",
"description": "Názov domény {} používa bezplatnú službu DNS. Služby tohto typu často využívajú pri svojich operáciách počítačoví zločinci alebo útočníci podporovaní vládou. Je veľmi podozrivé, že aplikácia spustená na pozadí používa takúto službu. Preskúmajte to podrobnejšie."
},
"IOC-10": {
"title": "Do domény {}, ktorá obsahuje podozrivú TLD, bola odoslaná požiadavka HTTP.",
"description": "Názov domény {} používa podozrivú doménu najvyššej úrovne ({}). Túto negenerickú TLD, hoci sama o sebe nie je škodlivá, bežne používajú počítačoví zločinci a pri operáciách sponzorovaných vládou. Overte túto doménu pomocou vyhľadania na internete. Ak je tento hostiteľ uvedený v iných upozorneniach, považujte to za veľmi podozrivé."
},
"ACT-01": {
"title": "Doména {} používa podozrivý názvový server ({}).",
"description": "Názov domény {} používa názvový server, ktorý je explicitne spojený so škodlivou aktivitou. Mnoho kyberzločincov a štátom podporovaných útočníkov používa registrátorov tohto typu, pretože umožňujú použiť kryptomeny a anonymné platby. Odporúča sa ďalej skúmať túto doménu a súvisiacu spustenú aplikáciu pomocou forenznej analýzy telefónu."
},
"ACT-02": {
"title": "Doména {} bola vytvorená nedávno (pred {} dňami).",
"description": "Názov domény {} je nový. Aj keď to nie je vo svojej podstate škodlivé, útočníci často vytvoria novú infraštruktúru pre každú kampaň, čo môže viesť k použitiu novo registrovaných doménových mien."
},
"SSL-01": {
"title": "SSL pripojenie na neštandardnom porte ({}) k {}",
"description": "Je nezvyčajné, aby smartfóny vytvárali pripojenia SSL cez neštandardný port. Môže to byť legitímne, ale aj tak odporúčame skontrolovať reputáciu {}. Pozrite sa na jeho záznam WHOIS, súvisiaci autonómny systém, dátum jeho vytvorenia a vyhľadajte ho na internete."
},
"SSL-02": {
"title": "SSL pripojenie k {} používa bezplatný certifikát.",
"description": "Bezplatné certifikáty ako napr Let's Encrypt sú bežne používané príkazovými a riadiacimi servermi spojenými so škodlivými implantátmi a phishingovými webovými stránkami. Odporúčame overiť hostiteľa spojeného s týmto certifikátom. Pozrite sa na názov domény a dátum vytvorenia alebo si overte reputáciu hostiteľa na internete."
},
"SSL-03": {
"title": "Certifikát priradený k {} je podpísaný sám sebou.",
"description": "Používanie certifikátov s vlastným podpisom je v infraštruktúre útočníka rozšírené. Odporúčame skontrolovať hostiteľa {} priradeného k tomuto certifikátu. Ak to chcete urobiť, pozrite sa na názov jeho domény (ak ho má), záznam WHOIS, dátum vytvorenia a skontrolujte reputáciu hostiteľa na internete."
},
"SSL-04": {
"title": "Certifikát obsahuje názov domény {}, kategorizovaný ako {}",
"description": "Jeden z vymenených certifikátov obsahuje názov domény {}. Tento názov domény bol výslovne klasifikovaný ako škodlivý. Vaše zariadenie je určite napadnuté a malo by byť ďalej zanalyzované profesionálnym tímom."
},
"ADV-01": {
"title": "Skontrolujte upozornenia pre {}",
"description": "Skontrolujte prosím reputáciu hostiteľa {}, Zdá sa, že je to škodlivé, pretože to počas relácie vygenerovalo {} upozornení."
},
"SNORT-01": {
"title": "Spustilo sa pravidlo Suricata: {}",
"description": "Spustilo sa pravidlo zisťovania siete. Je pravdepodobné, že Vaše zariadenie bolo ohrozené alebo vykazuje podozrivé správanie."
}
},
"report": {
"numbers": [
"jednu",
"dva",
"tri",
"štyri",
"päť",
"šesť",
"sedem",
"osem",
"deväť"
],
"suspect_title": "Podozrivá komunikácia",
"uncat_title": "Nekategorizovaná komunikácia",
"whitelist_title": "Komunikácia na bielej listine",
"protocol": "Protokol",
"domain": "Doména",
"dst_ip": "Dst IP adresa",
"dst_port": "Dst číslo portu",
"device_name": "Názov zariadenia",
"device_mac": "MAC adresa zariadenia",
"report_generated_on": "Report vygenerovaný",
"capture_duration": "Trvanie záznamu",
"packets_number": "Počet paketov",
"capture_sha1": "Záznam SHA1",
"report_for_the_capture": "Report pre záznam",
"report_footer": "Tento prehľad bol automaticky vygenerovaný zariadením Tinycheck. V prípade akýchkoľvek otázok, hlásení chýb alebo spätnej väzby nás kontaktujte na tinycheck@kaspersky.com.",
"high_msg": "Vaše zariadenie je napadnuté a máte {} kritické/ú výstrahy/u.",
"moderate_msg": "Máte {} mierne/u výstrahy/u, Vaše zariadenie môže byť napadnuté. Pozrite si ich pozorne.",
"low_msg": "Máte iba {} nízke/u výstrahy/u, neváhajte ich skontrolovať.",
"none_msg": "Všetko vyzerá dobre, žiadne upozornenia. Neváhajte a skontrolujte nekategorizovanú komunikáciu, ak existuje."
}
}

View File

@ -10,7 +10,7 @@ import os
from functools import reduce from functools import reduce
# I'm not going to use an ORM for that. # I'm not going to use an ORM for that.
parent = "/".join(sys.path[0].split("/")[:-1]) parent = os.path.split(os.path.dirname(os.path.abspath(sys.argv[0])))[0]
conn = sqlite3.connect(os.path.join(parent, "tinycheck.sqlite3")) conn = sqlite3.connect(os.path.join(parent, "tinycheck.sqlite3"))
cursor = conn.cursor() cursor = conn.cursor()

1
app/backend/.npmrc Normal file
View File

@ -0,0 +1 @@
timeout=60000

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
{ {
"name": "tinycheck-backend", "name": "@kaspersky/tinycheck-backend",
"version": "0.1.0", "version": "0.1.0",
"private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve --copy --port=4201", "serve": "vue-cli-service serve --copy --port=4201",
"build": "vue-cli-service build", "build": "vue-cli-service build",

View File

@ -25,9 +25,6 @@
<li class="menu-item"> <li class="menu-item">
<span @click="$router.push('/device/db')">Manage database</span> <span @click="$router.push('/device/db')">Manage database</span>
</li> </li>
<!-- <li class="menu-item">
<span @click="$router.push('/device/user')">User configuration</a>
</li> -->
</ul> </ul>
</div> </div>
</div> </div>
@ -42,6 +39,9 @@
<li class="menu-item"> <li class="menu-item">
<span @click="$router.push('/iocs/search')">Search IOCs</span> <span @click="$router.push('/iocs/search')">Search IOCs</span>
</li> </li>
<li class="menu-item">
<span @click="$router.push('/iocs/misp')">MISP Instances</span>
</li>
</ul> </ul>
</div> </div>
</div> </div>
@ -95,4 +95,4 @@
.fade-leave-active { .fade-leave-active {
opacity: 0 opacity: 0
} }
</style> </style>

View File

@ -650,4 +650,128 @@ h4, h5 {
.upper { .upper {
text-transform: uppercase; text-transform: uppercase;
}
/*** MISP CSS ***/
.misp-form {
/* Using CSS Grid to lay out the elements in two-dimensions: */
display: grid;
/* specifying a 0.2em gutter/gap between adjacent elements: */
gap: 0.4em;
overflow:auto;
grid-template-columns: 10em 0.5em 1fr;
width: 100%;
border-radius:.1rem;
margin-bottom: .8rem;
}
.misp-label {
/* placing all <label> elements in the grid column 1 (the first): */
grid-column: 1;
text-align: left;
padding-top: .3em;
}
.misp-offline {
background-color: #e85600;
color: #FFF;
font-size: 11px;
border-radius: 3px;
padding:3px 6px 3px 6px;
cursor: help;
}
.misp-online {
background-color: #64c800;
color: #FFF;
font-size: 11px;
border-radius: 3px;
padding:3px 6px 3px 6px;
cursor: help;
}
.misp-name {
font-size: 1rem;
font-family: "Roboto-Bold";
color: #484848;
}
.misp-name:disabled {
border-style: none;
color:inherit;
background-color: inherit;
padding: unset;
}
.misp-input {
grid-column: 3;
align-self: center;
}
.misp-input:disabled {
border-style: none;
color:inherit;
background-color: inherit;
padding: unset;
}
.misp-button {
/* positioning the <button> element in the grid-area identified
by the name of 'submit': */
grid-area: submit;
}
.loading {
margin-bottom: 12px;
display: block;
}
.loading::after {
animation: loading .5s infinite linear;
background: 0 0;
border: .1rem solid #66758c;
border-radius: 50%;
border-right-color: transparent;
border-top-color: transparent;
content: "";
display: block;
height: .8rem;
left: 50%;
margin-left: -.4rem;
margin-top: -.4rem;
opacity: 1;
padding: 0;
position: absolute;
top: 50%;
width: .8rem;
z-index: 1;
}
.loading.loading-lg::after {
height: 1.6rem;
margin-left: -.8rem;
margin-top: -.8rem;
width: 1.6rem;
}
.tooltip::after{
background:rgba(48,55,66,.95);
border-radius:3px;
bottom:100%;
color:#fff;
content:attr(data-tooltip);
display:block;
font-size: 11px;
left:50%;
max-width:320px;
opacity:0;
overflow:hidden;
padding:3px 6px 3px 6px;
pointer-events:none;
position:absolute;
text-overflow:ellipsis;
transform:translate(-50%,.4rem);
transition:opacity .2s,transform .2s;
white-space:pre;
z-index:300
} }

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 805 KiB

After

Width:  |  Height:  |  Size: 674 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 784 KiB

After

Width:  |  Height:  |  Size: 660 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 KiB

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View File

@ -34,6 +34,12 @@ const routes = [
component: () => import('../views/iocs-manage.vue'), component: () => import('../views/iocs-manage.vue'),
props: true props: true
}, },
{
path: '/iocs/misp',
name: 'iocs-manage',
component: () => import('../views/iocs-misp.vue'),
props: true
},
{ {
path: '/iocs/search', path: '/iocs/search',
name: 'iocs-search', name: 'iocs-search',

View File

@ -35,6 +35,10 @@
<input type="checkbox" @change="switch_config('frontend', 'virtual_keyboard')" v-model="config.frontend.virtual_keyboard"> <input type="checkbox" @change="switch_config('frontend', 'virtual_keyboard')" v-model="config.frontend.virtual_keyboard">
<i class="form-icon"></i> Use virtual keyboard (for touch screen) <i class="form-icon"></i> Use virtual keyboard (for touch screen)
</label> </label>
<label class="form-switch">
<input type="checkbox" @change="switch_config('frontend', 'choose_net')" v-model="config.frontend.choose_net">
<i class="form-icon"></i> Allow the end-user to choose the network even if connected.
</label>
<label class="form-switch"> <label class="form-switch">
<input type="checkbox" @change="switch_config('frontend', 'reboot_option')" v-model="config.frontend.reboot_option"> <input type="checkbox" @change="switch_config('frontend', 'reboot_option')" v-model="config.frontend.reboot_option">
<i class="form-icon"></i> Allow the end-user to reboot the device from the interface. <i class="form-icon"></i> Allow the end-user to reboot the device from the interface.

View File

@ -0,0 +1,175 @@
<template>
<div class="backend-content" id="content">
<div class="column col-8 col-xs-12">
<h3 class="s-title">Manage MISP instances</h3>
<ul class="tab tab-block">
<li class="tab-item">
<a href="#" v-on:click="switch_tab('addmisp')" v-bind:class="{ active: tabs.addmisp }">Add instance</a>
</li>
<li class="tab-item">
<a href="#" v-on:click="switch_tab('instances')" v-bind:class="{ active: tabs.instances }">Existing instances</a>
</li>
</ul>
<div v-if="tabs.addmisp">
<div class="misp-form">
<label class="misp-label">Instance name</label><span></span>
<input class="form-input" type="text" ref="misp_name" placeholder="CYBERACME MISP" v-model="mispinst.name" required>
<label class="misp-label">Instance URL</label><span></span>
<input class="form-input" type="text" ref="misp_url" placeholder="https://misp.cyberacme.com" v-model="mispinst.url" required>
<label class="misp-label">Authentication key</label><span></span>
<input class="form-input" type="text" ref="misp_key" placeholder="OqHSMyAuth3ntic4t10nK3y0MyAuth3ntic4t10nK3y3iiH" v-model="mispinst.key" required>
<label class="misp-label" v-if="mispinst.url.startsWith('https://')">Verify certificate? </label><span v-if="mispinst.url.startsWith('https://')"></span>
<div style="flex:50%" v-if="mispinst.url.startsWith('https://')"><label class="form-switch">
<input type="checkbox" v-model="mispinst.ssl">
<i class="form-icon"></i>
</label></div>
</div>
<button class="btn-primary btn col-12" v-on:click="add_instance()">Add MISP instance</button>
<div class="form-group" v-if="added">
<div class="toast toast-success">
MISP instance added successfully. Redirecting to instances in 2 seconds.
</div>
</div>
<div class="form-group" v-if="error">
<div class="toast toast-error">
MISP instance not added. {{error}}
</div>
</div>
</div>
<div class="form-group" v-if="tabs.instances">
<div v-if="instances.length">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Server</th>
<th>Authkey</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-for="i in instances" v-bind:key="i.id">
<td>{{ i.name }}</td>
<td>{{ i.url.replace('https://', '') .replace('http://', '') }}</td>
<td>{{ i.apikey.slice(0,5) }} [...] {{ i.apikey.slice(35,40) }}</td>
<td>
<span v-if="i.connected" class="misp-online tooltip" :data-tooltip="i.lastsync"> ONLINE</span>
<span v-else class="misp-offline tooltip" :data-tooltip="i.lastsync"> OFFLINE</span>
</td>
<td><button class="btn btn-sm" v-on:click="delete_instance(i)">Delete</button></td>
</tr>
</tbody>
</table>
</div>
<div v-else>
<div class="empty">
<div v-if="loading">
<p class="empty-title h5">
<span class="loading loading-lg"></span>
</p>
<p class="empty-subtitle">Testing and loading your MISP instances.</p>
</div>
<div v-else>
<p class="empty-title h5">No MISP instance found.</p>
<p class="empty-subtitle">Do not hesitate to add a MISP instance.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'managemisp',
data() {
return {
error:false,
loading:false,
added:false,
mispinst:{ name:'', url:'',key:'', ssl:false },
instances:[],
tabs: { "addmisp" : true, "instances" : false },
jwt:""
}
},
props: { },
methods: {
add_instance: function()
{
this.added = false;
this.error = false;
if (this.mispinst.name && this.mispinst.url && this.mispinst.key)
{
axios.post(`/api/misp/add`, { data: { instance: this.mispinst } }, { headers: {'X-Token': this.jwt} }).then(response => {
if(response.data.status){
this.added = true;
setTimeout(function (){
this.switch_tab('instances')
this.mispinst = { name:'', url:'',key:'', ssl:false }
this.added = false
}.bind(this), 2000);
} else {
this.error = response.data.message;
}
})
.catch(err => (console.log(err)))
}
},
delete_instance(elem)
{
axios.get(`/api/misp/delete/${elem.id}`, { timeout: 10000, headers: {'X-Token': this.jwt} })
.then(response => {
if(response.data.status){
this.instances = this.instances.filter(function(el) { return el != elem; });
}
})
.catch(err => (console.log(err)))
},
get_misp_instances()
{
this.loading = true;
this.instances = []
axios.get(`/api/misp/get_all`, { timeout: 10000, headers: {'X-Token': this.jwt} })
.then(response => {
if(response.data.results){
this.instances = response.data.results;
this.instances.forEach(e => {
var lastsync = parseInt((Date.now()/1000 - e.lastsync) / 86400)
e.lastsync = (!lastsync)? "Synchronized today" : `Synchronized ${lastsync} day(s) ago`
} )
}
this.loading = false
})
.catch(err => (console.log(err)))
},
switch_tab: function(tab) {
Object.keys(this.tabs).forEach(key => {
if( key == tab ){
this.tabs[key] = true
if (key == "instances") this.get_misp_instances();
} else {
this.tabs[key] = false
}
});
},
get_jwt(){
axios.get(`/api/get-token`, { timeout: 10000 })
.then(response => {
if(response.data.token){
this.jwt = response.data.token
}
})
.catch(err => (console.log(err)))
}
},
created: function() {
this.get_jwt();
}
}
</script>

View File

@ -13,27 +13,37 @@
<thead> <thead>
<tr> <tr>
<th>Indicator</th> <th>Indicator</th>
<th>Type</th>
<th>Tag</th> <th>Tag</th>
<th>TLP</th> <th>TLP</th>
<th> </th> <th>Source</th>
<th>Action</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="r in results" :key="r.tlp"> <tr v-for="r in results" :key="r.tlp">
<td>{{ r.value }}</td> <td>{{ r.value }}</td>
<td class="capi">{{ r.type }}</td>
<td class="upper">{{ r.tag }}</td> <td class="upper">{{ r.tag }}</td>
<td><label :class="['tlp-' + r.tlp]">{{ r.tlp }}</label></td> <td><label :class="['tlp-' + r.tlp]">{{ r.tlp }}</label></td>
<td class="capi">{{ r.source }}</td>
<td><button class="btn btn-sm" v-on:click="remove(r)">Delete</button></td> <td><button class="btn btn-sm" v-on:click="remove(r)">Delete</button></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<div v-else-if="first_search==false"> <div v-else-if="first_search==false">
<div class="empty"> <div v-if="loading">
<p class="empty-title h5">IOC<span v-if="this.iocs.match(/[^\r\n]+/g).length>1">s</span> not found.</p> <div class="empty">
<p class="empty-subtitle">Try wildcard search to expend your search.</p> <p class="empty-title h5">
<span class="loading loading-lg"></span>
</p>
<p class="empty-subtitle">Finding your IOC(s)...</p>
</div>
</div>
<div v-else>
<div class="empty">
<p class="empty-title h5">IOC<span v-if="this.iocs.match(/[^\r\n]+/g).length>1">s</span> not found.</p>
<p class="empty-subtitle">Try wildcard search to expend your search.</p>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -49,7 +59,8 @@ export default {
return { return {
results: [], results: [],
first_search: true, first_search: true,
jwt:"" jwt:"",
loading:false
} }
}, },
props: { }, props: { },
@ -57,6 +68,7 @@ export default {
search_iocs: function() { search_iocs: function() {
this.results = [] this.results = []
this.first_search = false this.first_search = false
this.loading = true;
this.iocs.match(/[^\r\n]+/g).forEach(ioc => { this.iocs.match(/[^\r\n]+/g).forEach(ioc => {
ioc = ioc.trim() ioc = ioc.trim()
if("alert " != ioc.slice(0,6)) { if("alert " != ioc.slice(0,6)) {
@ -72,6 +84,7 @@ export default {
if(response.data.results.length>0){ if(response.data.results.length>0){
this.results = [].concat(this.results, response.data.results); this.results = [].concat(this.results, response.data.results);
} }
this.loading = false;
}) })
.catch(err => (console.log(err))) .catch(err => (console.log(err)))
}); });

1
app/frontend/.npmrc Normal file
View File

@ -0,0 +1 @@
timeout=60000

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
{ {
"name": "tinycheck-new", "name": "@kaspersky/tinycheck-new",
"version": "0.1.0", "version": "0.1.0",
"private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve --copy --port=4202", "serve": "vue-cli-service serve --copy --port=4202",
"build": "vue-cli-service build", "build": "vue-cli-service build",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 805 KiB

After

Width:  |  Height:  |  Size: 674 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 784 KiB

After

Width:  |  Height:  |  Size: 660 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,4 +1 @@
<svg width="112" height="195" viewBox="0 0 112 195" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg xmlns="http://www.w3.org/2000/svg" width="112" height="195" fill="none" viewBox="0 0 112 195"><line x1="3.5" x2="3.5" y1="3.5" y2="191.5" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="7"/><rect width="105" height="195" x="7" fill="#F7F8F9"/></svg>
<line x1="3.5" y1="3.5" x2="3.50001" y2="191.5" stroke="black" stroke-width="7" stroke-linecap="round" stroke-linejoin="round"/>
<rect x="7" width="105" height="195" fill="#F7F8F9"/>
</svg>

Before

Width:  |  Height:  |  Size: 294 B

After

Width:  |  Height:  |  Size: 281 B

View File

@ -1,16 +1 @@
<svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="loader-1" width="40" height="40" x="0" y="0" enable-background="new 0 0 40 40" version="1.1" viewBox="0 0 40 40" xml:space="preserve"><path fill="#000" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946 s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634 c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z" opacity=".2"/><path fill="#f7f8f9" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0 C22.32,8.481,24.301,9.057,26.013,10.047z"><animateTransform attributeName="transform" attributeType="xml" dur="0.5s" from="0 20 20" repeatCount="indefinite" to="360 20 20" type="rotate"/></path></svg>
width="40px" height="40px" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve">
<path opacity="0.2" fill="#000" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946
s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634
c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z"/>
<path fill="#f7f8f9" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0
C22.32,8.481,24.301,9.057,26.013,10.047z">
<animateTransform attributeType="xml"
attributeName="transform"
type="rotate"
from="0 20 20"
to="360 20 20"
dur="0.5s"
repeatCount="indefinite"/>
</path>
</svg>

Before

Width:  |  Height:  |  Size: 970 B

After

Width:  |  Height:  |  Size: 874 B

View File

@ -1,5 +1 @@
<svg width="106" height="106" viewBox="0 0 106 106" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg xmlns="http://www.w3.org/2000/svg" width="106" height="106" fill="none" viewBox="0 0 106 106"><circle cx="53" cy="53" r="53" fill="#40D8A1"/><path stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="10" d="M29 52.5L47.5 70.5"/><line x1="79" x2="48.071" y1="40.071" y2="71" stroke="#fff" stroke-linecap="round" stroke-width="10"/></svg>
<circle cx="53" cy="53" r="53" fill="#40D8A1"/>
<path d="M29 52.5L47.5 70.5" stroke="white" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
<line x1="79" y1="40.0711" x2="48.0711" y2="71" stroke="white" stroke-width="10" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 377 B

After

Width:  |  Height:  |  Size: 363 B

View File

@ -1,6 +1 @@
<svg width="548" height="199" viewBox="0 0 548 199" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg xmlns="http://www.w3.org/2000/svg" width="548" height="199" fill="none" viewBox="0 0 548 199"><rect width="142" height="145" x="403" y="27" fill="#fff" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="6" rx="8"/><path fill="#000" d="M0 30C0 13.4315 13.4315 0 30 0H428C432.418 0 436 3.58172 436 8V191C436 195.418 432.418 199 428 199H30C13.4315 199 0 185.569 0 169V30Z"/><rect width="26" height="26" x="477" y="55" fill="#fff" stroke="#000" stroke-width="6"/><rect width="26" height="26" x="477" y="117" fill="#fff" stroke="#000" stroke-width="6"/></svg>
<rect x="403" y="27" width="142" height="145" rx="8" fill="white" stroke="black" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M0 30C0 13.4315 13.4315 0 30 0H428C432.418 0 436 3.58172 436 8V191C436 195.418 432.418 199 428 199H30C13.4315 199 0 185.569 0 169V30Z" fill="black"/>
<rect x="477" y="55" width="26" height="26" fill="white" stroke="black" stroke-width="6"/>
<rect x="477" y="117" width="26" height="26" fill="white" stroke="black" stroke-width="6"/>
</svg>

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 583 B

View File

@ -1,11 +1 @@
<?xml version="1.0" encoding="utf-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin:auto;background:0 0;display:block;shape-rendering:auto" width="200" height="200" preserveAspectRatio="xMidYMid" viewBox="0 0 100 100"><circle cx="50" cy="50" r="0" fill="none" stroke="#f3f3f3" stroke-width="2"><animate attributeName="r" begin="-0.7462686567164178s" calcMode="spline" dur="1.4925373134328357s" keySplines="0 0.2 0.8 1" keyTimes="0;1" repeatCount="indefinite" values="0;30"/><animate attributeName="opacity" begin="-0.7462686567164178s" calcMode="spline" dur="1.4925373134328357s" keySplines="0.2 0 0.8 1" keyTimes="0;1" repeatCount="indefinite" values="1;0"/></circle><circle cx="50" cy="50" r="0" fill="none" stroke="#d8dddf" stroke-width="2"><animate attributeName="r" calcMode="spline" dur="1.4925373134328357s" keySplines="0 0.2 0.8 1" keyTimes="0;1" repeatCount="indefinite" values="0;30"/><animate attributeName="opacity" calcMode="spline" dur="1.4925373134328357s" keySplines="0.2 0 0.8 1" keyTimes="0;1" repeatCount="indefinite" values="1;0"/></circle></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<circle cx="50" cy="50" r="0" fill="none" stroke="#f3f3f3" stroke-width="2">
<animate attributeName="r" repeatCount="indefinite" dur="1.4925373134328357s" values="0;30" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline" begin="-0.7462686567164178s"></animate>
<animate attributeName="opacity" repeatCount="indefinite" dur="1.4925373134328357s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline" begin="-0.7462686567164178s"></animate>
</circle>
<circle cx="50" cy="50" r="0" fill="none" stroke="#d8dddf" stroke-width="2">
<animate attributeName="r" repeatCount="indefinite" dur="1.4925373134328357s" values="0;30" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline"></animate>
<animate attributeName="opacity" repeatCount="indefinite" dur="1.4925373134328357s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline"></animate>
</circle>
<!-- [ldio] generated by https://loading.io/ --></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -2,9 +2,11 @@
<div class="controls" v-if="display"> <div class="controls" v-if="display">
<i class="off-icon" v-on:click="action('shutdown')" v-if="off_available"></i> <i class="off-icon" v-on:click="action('shutdown')" v-if="off_available"></i>
<i class="quit-icon" v-on:click="action('quit')" v-if="quit_available"></i> <i class="quit-icon" v-on:click="action('quit')" v-if="quit_available"></i>
<i class="home-icon" @click="$router.push({ name: 'loader' })"></i>
<i class="update-icon" v-if="update_available&&update_possible" @click="$router.push({ name: 'update' })"></i> <i class="update-icon" v-if="update_available&&update_possible" @click="$router.push({ name: 'update' })"></i>
</div> </div>
</template> </template>
<script> <script>
import axios from 'axios' import axios from 'axios'
@ -51,7 +53,7 @@ export default {
load_config: function() { load_config: function() {
axios.get(`/api/misc/config`, { timeout: 60000 }) axios.get(`/api/misc/config`, { timeout: 60000 })
.then(response => { .then(response => {
this.quit_available = response.data.quit_option this.quit_available = (response.data.quit_option && (["localhost", "127.0.0.1"].some(h => window.location.host.includes(h) )))
this.off_available = response.data.shutdown_option this.off_available = response.data.shutdown_option
}) })
.catch(error => { console.log(error) }); .catch(error => { console.log(error) });
@ -71,4 +73,4 @@ export default {
this.check_update(); this.check_update();
} }
} }
</script> </script>

View File

@ -50,8 +50,11 @@
"low_msg": "Només teniu {nb} alertes baixes, <br /> Si us plau comproveu-les.", "low_msg": "Només teniu {nb} alertes baixes, <br /> Si us plau comproveu-les.",
"save_report": "Desa l'informe", "save_report": "Desa l'informe",
"report_of": "Informe de", "report_of": "Informe de",
"ip_address": "Adreça IP", "ip_address": "Adreça IP:",
"mac_address": "Adreça MAC", "mac_address": "Adreça MAC:",
"pcap_sha1": "SHA1:",
"capture_started": "La captura va començar a:",
"capture_ended": "La captura va acabar el:",
"high": "alt", "high": "alt",
"moderat": "moderat", "moderat": "moderat",
"low": "baix" "low": "baix"

View File

@ -0,0 +1,92 @@
{
"home": {
"welcome_msg": "欢迎使用 TinyCheck.",
"help_msg": "我们将帮助您检查您的设备。",
"start_btn": "开始!"
},
"analysis": {
"question": "您是否希望对被捕获的通信进行分析?",
"no_btn": "不,只保存数据",
"yes_btn": "好的!",
"please_wait_msg": "请耐心等待分析结果...",
"some_time_msg": "是的,这需要花点时间..."
},
"capture": {
"intercept_coms_msg": "正在截获通信: ",
"stop_btn": "停止捕获"
},
"generate-ap": {
"network_name": "网络名称",
"network_password": "网络密码",
"tap_msg": "点击白色帧,创建新网络",
"generate_ap_msg": "我们刚刚为您创建了新的临时网络。",
"error_msg1": "很不幸的是,我们在 <br /> 创建网络AP的过程中遇到了问题。",
"error_msg2": "请确认您的设备上有两个Wi-FI网卡 <br /> 并重启设备以重试。",
"restart_btn": "重启设备"
},
"report": {
"show_full_report": "显示完整报告",
"start_new_capture": "开始新的捕获",
"save_capture": "保存捕获",
"numbers": [
"零",
"一",
"二",
"三",
"四",
"五",
"六",
"七",
"八",
"九",
"十",
"十一"
],
"stalkerware_msg": "您的设备已被跟踪软件 <br /> 入侵,请检查完整报告.",
"location_msg": "一个应用程序正在将您的<br /> 实时地理位置信息分享给第三方。",
"fine_msg": "一切正常,没有警报。",
"high_msg": "您有 {nb} 条高级警报,<br /> 看起来您的设备已被入侵。",
"moderate_msg": "您有 {nb} 条中级警报, <br /> 您的设备有可能已被入侵。",
"low_msg": "您只有 {nb} 条低级警报,<br /> 请检查它们。",
"save_report": "保存报告",
"report_of": "报告设备名:",
"ip_address": "IP 地址:",
"mac_address": "MAC 地址:",
"pcap_sha1": "SHA1 ",
"capture_started": "捕获开始时间:",
"capture_ended": "捕获结束时间:",
"high": "高",
"moderate": "中",
"low": "低"
},
"wifi-select": {
"already_connected_question": "您似乎已经连接了一个Wi-Fi网络。<br /> 您希望使用当前的连接吗?",
"no_btn": "不,使用其他连接",
"yes_btn": "是的,使用此连接。",
"wifi_name": "Wi-Fi 名称",
"refresh_btn": "刷新网络列表",
"not_connected": "您似乎没有连接至互联网。",
"please_config": "请配置 Wi-Fi 连接。",
"lets_do_btn": "好的,开始配置",
"no_internet": "离线使用",
"wifi_connected": "Wi-Fi 已连接",
"wifi_not_connected": "Wi-Fi 未连接,请重试。",
"tap_keyboard": "点击虚拟键盘开始",
"wifi_password": "Wi-Fi 密码",
"connect_to_it": "连接此网络"
},
"save-capture": {
"please_connect": "请连接U盘以保存捕获。",
"we_are_saving": "我们正在保存您的捕获。",
"tap_msg": "您可以点击U盘以开始新的捕获。",
"capture_download": "即将开始保存捕获数据...",
"start_capture_btn": "开始进行新的捕获"
},
"update": {
"tinycheck_needs": "TinyCheck 需要更新到新版本",
"please_click": "请点击此按钮进行更新。",
"the_process": "此过程需要花几分钟,请耐心等待...",
"update_finished": "更新已完成,需要刷新界面...",
"update_it": "现在更新"
}
}

View File

@ -0,0 +1,92 @@
{
"home": {
"welcome_msg": "Willkommen bei TinyCheck!",
"help_msg": "Wir helfen Ihnen bei der Überprüfung Ihres Geräts.",
"start_btn": "Fangen wir an!"
},
"analysis": {
"question": "Möchten Sie die erfassten Kommunikationsverbindungen analysieren?",
"no_btn": "Nein, nur speichern",
"yes_btn": "Ja, analysieren",
"please_wait_msg": "Bitte warten Sie, während die Analyse läuft …",
"some_time_msg": "Dies kann eine Weile dauern …"
},
"capture": {
"intercept_coms_msg": "Abfangen der Kommunikationsverbindungen von ",
"stop_btn": "Aufnahme beenden"
},
"generate-ap": {
"network_name": "Netzwerkname",
"network_password": "Netzwerkpasswort",
"tap_msg": "Tippen Sie auf den weißen Rahmen, um ein neues Netzwerk zu erstellen.",
"generate_ap_msg": "Wir erstellen ein temporäres Netzwerk für Sie.",
"error_msg1": "Leider sind während der AP-Erstellung <br>einige Fehler aufgetreten.",
"error_msg2": "Bitte stellen Sie sicher, dass Ihr Gerät zwei WLAN-Schnittstellen besitzt,<br> und starten Sie es neu, um es erneut zu versuchen.",
"restart_btn": "Gerät neu starten"
},
"report": {
"show_full_report": "Vollständigen Bericht anzeigen",
"start_new_capture": "Neue Aufnahme starten",
"save_capture": "Aufnahme speichern",
"numbers": [
"null",
"eine",
"zwei",
"drei",
"vier",
"fünf",
"sechs",
"sieben",
"acht",
"neun",
"zehn",
"elf"
],
"stalkerware_msg": "Ihr Gerät ist durch Stalkerware<br>kompromittiert; bitte sehen Sie sich den Bericht an.",
"location_msg": "Eine Anwendung teilt Ihren<br> aktuellen Standort mit Dritten.",
"fine_msg": "Alles sieht gut aus kein Warnungen.",
"high_msg": "Sie haben {nb} Warnung der Stufe \"Hoch\":<br>Ihr Gerät scheint kompromittiert zu sein.",
"moderate_msg": "Sie haben {nb} Warnungen der Stufe \"Mittel\":<br>Ihr Gerät könnte kompromittiert sein.",
"low_msg": "Sie haben nur {nb} Warnungen der Stufe \"Niedrig\":<br> Überprüfen Sie sie gerne.",
"save_report": "Bericht speichern",
"report_of": "Bericht zu",
"ip_address": "IP-Adresse:",
"mac_address": "MAC-Adresse:",
"pcap_sha1": "SHA1:",
"capture_started": "Capture begann mit:",
"capture_ended": "Capture endete an:",
"high": "Hoch",
"moderate": "Mittel",
"low": "Niedrig"
},
"wifi-select": {
"already_connected_question": "Sie scheinen bereits mit einem Netzwerk verbunden zu sein.<br>Möchten Sie die aktuelle Verbindung nutzen?",
"no_btn": "Nein, eine andere nutzen",
"yes_btn": "Ja, diese nutzen.",
"wifi_name": "WLAN-Name",
"refresh_btn": "Netzwerkliste aktualisieren",
"not_connected": "Sie scheinen nicht mit dem Internet verbunden zu sein.",
"please_config": "Bitte konfigurieren Sie die WLAN-Verbindung.",
"lets_do_btn": "OK, jetzt machen",
"no_internet": "Verwendung ohne Internet",
"wifi_connected": "WLAN verbunden",
"wifi_not_connected": "WLAN nicht verbunden. Bitte versuchen Sie es erneut.",
"tap_keyboard": "Tippen Sie auf die virtuelle Tastatur, um zu starten",
"wifi_password": "WLAN-Passwort",
"connect_to_it": "Damit verbinden"
},
"save-capture": {
"please_connect": "Bitte schließen Sie einen USB-Stick an, um Ihre Aufnahme zu speichern.",
"we_are_saving": "Wir speichern Ihre Aufnahme.",
"tap_msg": "Sie können den USB-Stick antippen, um eine neue Aufnahme zu starten.",
"capture_download": "Der Download der Aufnahme beginnt …",
"start_capture_btn": "Noch eine Aufnahme starten"
},
"update": {
"tinycheck_needs": "Ein neues Update von TinyCheck ist verfügbar",
"please_click": "Klicken Sie auf die Schaltfläche unten, um es zu aktualisieren",
"the_process": "Das Update kann einige Minuten dauern, bitte warten Sie ...",
"update_finished": "Update abgeschlossen, Sie werden weitergeleitet ...",
"update_it": "Aktualisieren Sie TinyCheck"
}
}

View File

@ -50,8 +50,11 @@
"low_msg": "You have only {nb} low alerts,<br /> don't hesitate to check them.", "low_msg": "You have only {nb} low alerts,<br /> don't hesitate to check them.",
"save_report": "Save the report", "save_report": "Save the report",
"report_of": "Report of", "report_of": "Report of",
"ip_address": "IP address", "ip_address": "IP address:",
"mac_address": "MAC address", "mac_address": "MAC address:",
"pcap_sha1": "SHA1:",
"capture_started": "Capture started on:",
"capture_ended": "Capture ended on:",
"high": "high", "high": "high",
"moderate": "moderate", "moderate": "moderate",
"low": "low" "low": "low"

View File

@ -46,12 +46,15 @@
"location_msg": "Una aplicación está compartiendo su <br /> geolocalización actual con un tercero.", "location_msg": "Una aplicación está compartiendo su <br /> geolocalización actual con un tercero.",
"fine_msg": "Todo parece correcto, cero alertas", "fine_msg": "Todo parece correcto, cero alertas",
"high_msg": "Tiene {nb} alerta máxima, <br /> tu dispositivo parece estar comprometido", "high_msg": "Tiene {nb} alerta máxima, <br /> tu dispositivo parece estar comprometido",
"mild_msg": "Tiene {nb} alertas moderadas, <br /> tu dispositivo puede estar comprometido", "moderate_msg": "Tiene {nb} alertas moderadas, <br /> tu dispositivo puede estar comprometido",
"low_msg": "Solo tiene {nb} alertas bajas, <br /> por favor revíselas", "low_msg": "Solo tiene {nb} alertas bajas, <br /> por favor revíselas",
"save_report": "Guardar el informe", "save_report": "Guardar el informe",
"report_of": "Informe de", "report_of": "Informe de",
"ip_address": "dirección IP", "ip_address": "Dirección IP:",
"mac_address": "dirección MAC", "mac_address": "Dirección MAC:",
"pcap_sha1": "SHA1:",
"capture_started": "Captura comenzó a:",
"capture_ended": "Captura terminó a:",
"high": "alta", "high": "alta",
"moderate": "moderada", "moderate": "moderada",
"low": "bajo" "low": "bajo"
@ -63,9 +66,9 @@
"wifi_name": "Nombre de Wi-Fi", "wifi_name": "Nombre de Wi-Fi",
"refresh_btn": "Actualizar lista de redes", "refresh_btn": "Actualizar lista de redes",
"not_connected": "Parece que no estás conectado a Internet", "not_connected": "Parece que no estás conectado a Internet",
"no_internet": "Úselo sin conexión",
"please_config": "Configure la conexión Wi-Fi.", "please_config": "Configure la conexión Wi-Fi.",
"lets_do_btn": "Ok, hagámoslo", "lets_do_btn": "Ok, hagámoslo",
"no_internet": "Úselo sin conexión",
"wifi_connected": "Wi-Fi conectado", "wifi_connected": "Wi-Fi conectado",
"wifi_not_connected": "Wi-Fi no conectado. Vuelve a intentarlo", "wifi_not_connected": "Wi-Fi no conectado. Vuelve a intentarlo",
"tap_keyboard": "Toque en el teclado virtual para comenzar", "tap_keyboard": "Toque en el teclado virtual para comenzar",

View File

@ -52,6 +52,9 @@
"report_of": "Rapport de", "report_of": "Rapport de",
"ip_address": "Adresse IP :", "ip_address": "Adresse IP :",
"mac_address": "Adresse MAC :", "mac_address": "Adresse MAC :",
"pcap_sha1": "SHA1 :",
"capture_started": "Capture débutée le :",
"capture_ended": "Capture finie le :",
"high": "elevee", "high": "elevee",
"moderate": "moyenne", "moderate": "moyenne",
"low": "basse" "low": "basse"

View File

@ -0,0 +1,92 @@
{
"home": {
"welcome_msg": "Benvenuto in TinyCheck.",
"help_msg": "Verrà fornita assistenza per il controllo del dispositivo.",
"start_btn": "Cominciamo!"
},
"analysis": {
"question": "Analizzare le comunicazioni acquisite?",
"no_btn": "No, è sufficiente salvarle",
"yes_btn": "Sì, va bene",
"please_wait_msg": "Analisi in corso. Attendere...",
"some_time_msg": "Sì, l'operazione può richiedere un po' di tempo..."
},
"capture": {
"intercept_coms_msg": "Intercettazione delle comunicazioni di ",
"stop_btn": "Interrompi acquisizione"
},
"generate-ap": {
"network_name": "Nome della rete",
"network_password": "Password della rete",
"tap_msg": "Toccare il riquadro bianco per generare una nuova rete.",
"generate_ap_msg": "Viene generata una rete temporanea.",
"error_msg1": "Si sono verificati alcuni problemi <br>durante la creazione del punto di accesso.",
"error_msg2": "Verificare di disporre di due interfacce Wi-Fi nel dispositivo<br> e riprovare eseguendo il riavvio.",
"restart_btn": "Riavvia il dispositivo"
},
"report": {
"show_full_report": "Mostra il rapporto completo",
"start_new_capture": "Avvia una nuova acquisizione",
"save_capture": "Salva acquisizione",
"numbers": [
"zero",
"uno",
"due",
"tre",
"quattro",
"cinque",
"sei",
"sette",
"otto",
"nove",
"dieci",
"undici"
],
"stalkerware_msg": "Il dispositivo è compromesso da<br>uno stalkerware, controllare il rapporto.",
"location_msg": "Un'applicazione condivide la<br /> geolocalizzazione attuale con terze parti.",
"fine_msg": "Sembra tutto a posto, <br /> non sono presenti avvisi.",
"high_msg": "È presente {nb} avviso con priorità elevata,<br /> il dispositivo sembra compromesso.",
"moderate_msg": "Sono presenti {nb} avvisi con priorità moderata, è possibile che il dispositivo sia compromesso.",
"low_msg": "Sono presenti solo {nb} avvisi con priorità bassa<br /> da controllare.",
"save_report": "Salva il rapporto",
"report_of": "Rapporto di",
"ip_address": "Indirizzo IP:",
"mac_address": "Indirizzo MAC:",
"pcap_sha1": "SHA1:",
"capture_started": "Cattura è iniziata su:",
"capture_ended": "Cattura terminata su:",
"high": "elevata",
"moderate": "moderata",
"low": "bassa"
},
"wifi-select": {
"already_connected_question": "Sembra che sia già stata stabilita una connessione a una rete.<br>Utilizzare la connessione attuale?",
"no_btn": "No, utilizzane un'altra",
"yes_btn": "Sì, utilizzala.",
"wifi_name": "Nome Wi-Fi",
"refresh_btn": "Aggiorna elenco delle reti",
"not_connected": "Sembra che non sia stata stabilita la connessione a Internet.",
"please_config": "Configurare la connessione Wi-Fi.",
"lets_do_btn": "Ok, va bene.",
"no_internet": "Utilizzare senza Internet",
"wifi_connected": "Wi-Fi connesso",
"wifi_not_connected": "Wi-Fi non connesso. Riprovare.",
"tap_keyboard": "Toccare la tastiera virtuale per iniziare",
"wifi_password": "Password Wi-Fi",
"connect_to_it": "Stabilisci connessione"
},
"save-capture": {
"please_connect": "Collegare una chiave USB per salvare l'acquisizione.",
"we_are_saving": "Salvataggio dell'acquisizione in corso.",
"tap_msg": "È possible toccare la chiave USB per avviare una nuova acquisizione.",
"capture_download": "Il download dell'acquisizione sta per iniziare...",
"start_capture_btn": "Avvia un'altra acquisizione"
},
"update": {
"tinycheck_needs": "È disponibile un nuovo aggiornamento di TinyCheck",
"please_click": "Fare clic sul pulsante in basso per aggiornarlo",
"the_process": "L'aggiornamento potrebbe richiedere diversi minuti, attendere ...",
"update_finished": "Aggiornamento completato, verrai reindirizzato ...",
"update_it": "Aggiorna TinyCheck"
}
}

View File

@ -0,0 +1,92 @@
{
"home": {
"welcome_msg": "Bem vindo(a) ao TinyCheck.",
"help_msg": "Ajudaremos você a verificar o dispositivo.",
"start_btn": "Vamos começar!"
},
"analysis": {
"question": "Deseja analisar as comunicações capturadas?",
"no_btn": "Não, somente salvá-las",
"yes_btn": "Sim, vamos lá",
"please_wait_msg": "Aguarde enquanto realizamos a análise...",
"some_time_msg": "Sim, isso pode demorar um pouco..."
},
"capture": {
"intercept_coms_msg": "Interceptando as comunicações de ",
"stop_btn": "Parar a captura"
},
"generate-ap": {
"network_name": "Nome da rede",
"network_password": "Senha da rede",
"tap_msg": "Toque no quadro branco para criar uma nova rede.",
"generate_ap_msg": "Geramos uma rede temporária para você.",
"error_msg1": "Infelizmente, tivemos alguns problemas <br> durante a criação do AP.",
"error_msg2": "Verifique se você possui duas interfaces Wi-Fi no dispositivo<br> e tente novamente, reiniciando-o.",
"restart_btn": "Reiniciar o dispositivo"
},
"report": {
"show_full_report": "Mostrar o relatório completo",
"start_new_capture": "Iniciar nova captura",
"save_capture": "Salvar a captura",
"numbers": [
"zero",
"um",
"dois",
"três",
"quatro",
"cinco",
"seis",
"sete",
"oito",
"nove",
"dez",
"onze"
],
"stalkerware_msg": "Seu dispositivo foi comprometido por<br /> um stalkerware. Verifique o relatório.",
"location_msg": "Um aplicativo está compartilhando sua <br /> geolocalização com um terceiro.",
"fine_msg": "Tudo parece estar bem, zero alertas.",
"high_msg": "Você tem {nb} alerta crítico,<br /> o dispositivo parece estar comprometido.",
"moderate_msg": "Você tem {nb} alertas moderados,<br /> o dispositivo pode estar comprometido.",
"low_msg": "Você tem apenas {nb} alertas leves,<br /> não deixe de verificá-los.",
"save_report": "Salvar o relatório",
"report_of": "Relatório de",
"ip_address": "Endereço IP:",
"mac_address": "Endereço MAC:",
"pcap_sha1": "SHA1:",
"capture_started": "Captura iniciada em:",
"capture_ended": "Captura terminou em:",
"high": "crítico",
"moderate": "moderado",
"low": "leve"
},
"wifi-select": {
"already_connected_question": "Parece que você já está conectado a uma rede.<br> Deseja usar a conexão atual?",
"no_btn": "Não, usar outra",
"yes_btn": "Sim, usar a conexão atual.",
"wifi_name": "Nome da rede Wi-Fi",
"refresh_btn": "Atualizar lista de redes",
"not_connected": "Você não está conectado à Internet.",
"please_config": "Configure a conexão Wi-Fi.",
"lets_do_btn": "Certo, vamos lá.",
"no_internet": "Use sem internet",
"wifi_connected": "Wi-Fi conectado",
"wifi_not_connected": "Wi-Fi desconectado. Tente novamente.",
"tap_keyboard": "Toque no teclado virtual para começar",
"wifi_password": "Senha do Wi-Fi",
"connect_to_it": "Conectar"
},
"save-capture": {
"please_connect": "Conecte uma chave USB para salvar a captura.",
"we_are_saving": "Estamos salvando a captura.",
"tap_msg": "Toque na chave USB para iniciar uma nova captura.",
"capture_download": "O download da captura vai começar...",
"start_capture_btn": "Iniciar nova captura"
},
"update": {
"tinycheck_needs": "Uma nova atualização do TinyCheck está disponível",
"please_click": "Clique no botão abaixo para atualizá-lo",
"the_process": "A atualização pode demorar vários minutos, aguarde ...",
"update_finished": "Atualização concluída, você será redirecionado ...",
"update_it": "Atualizar TinyCheck"
}
}

View File

@ -0,0 +1,92 @@
{
"home": {
"welcome_msg": "Добро пожаловать в TinyCheck.",
"help_msg": "Мы поможем вам проверить ваше устройство.",
"start_btn": "Итак, приступим!"
},
"analysis": {
"question": "Хотите проанализировать зафиксированные подключения?",
"no_btn": "Нет, только сохранить",
"yes_btn": "Да, проанализировать",
"please_wait_msg": "Подождите, идет анализ...",
"some_time_msg": "Это может занять некоторое время..."
},
"capture": {
"intercept_coms_msg": "Перехват подключений ",
"stop_btn": "Остановить сбор данных"
},
"generate-ap": {
"network_name": "Имя сети",
"network_password": "Пароль сети",
"tap_msg": "Нажмите на белую рамку, чтобы создать новую сеть.",
"generate_ap_msg": "Создастся временная сеть.",
"error_msg1": "<br>При создании точки доступа возникли проблемы.",
"error_msg2": "Убедитесь, что на вашем устройстве<br> есть два порта Wi-Fi, и повторите попытку, перезагрузив устройство.",
"restart_btn": "Перезагрузить устройство"
},
"report": {
"show_full_report": "Показать полный отчет",
"start_new_capture": "Начать новый сбор данных",
"save_capture": "Сохранить сбор данных",
"numbers": [
"ноль",
"один",
"два",
"три",
"четыре",
"пять",
"шесть",
"семь",
"восемь",
"девять",
"десять",
"одиннадцать"
],
"stalkerware_msg": "Ваше устройство взломано вредоносным<br /> ПО для слежки. Проверьте отчет.",
"location_msg": "Приложение передает вашу<br /> текущую геолокацию третьему лицу.",
"fine_msg": "Предупреждения отсутствуют,<br /> система выглядит защищенной.",
"high_msg": "У вас {nb} предупреждение высокого уровня.<br /> Вероятно,ваше устройство взломано.",
"moderate_msg": "У вас {nb} предупреждение среднего уровня.<br /> Возможно, ваше устройство взломано.",
"low_msg": "У вас {nb} предупреждение низкого уровня<br />, проверьте их.",
"save_report": "Сохранить отчет",
"report_of": "Отчет",
"ip_address": "IP-адрес:",
"mac_address": "MAC-адрес:",
"pcap_sha1": " SHA1:",
"capture_started": "Захват начался:",
"capture_ended": "захват закончился:",
"high": "высокий",
"moderate": "средний",
"low": "низкий"
},
"wifi-select": {
"already_connected_question": "Похоже, вы уже подключились к сети. <br>Использовать текущее подключение?",
"no_btn": "Нет, использовать другое.",
"yes_btn": "Да, использовать это.",
"wifi_name": "Имя сети Wi-Fi",
"refresh_btn": "Обновить список сетей",
"not_connected": "Похоже, вы не подключились к интернету.",
"please_config": "Настройте подключение по Wi-Fi.",
"lets_do_btn": "Да, настроить.",
"no_internet": "Использование без интернета",
"wifi_connected": "Подключено к сети Wi-Fi",
"wifi_not_connected": "Не подключено к сети Wi-Fi. Повторите попытку.",
"tap_keyboard": "Коснитесь виртуальной клавиатуры, чтобы начать",
"wifi_password": "Пароль Wi-Fi",
"connect_to_it": "Подключиться"
},
"save-capture": {
"please_connect": "Подсоедините USB-ключ, чтобы сохранить результат сбора данных.",
"we_are_saving": "Сохранение собранных данных.",
"tap_msg": "Коснитесь USB-ключа, чтобы начать новый сбор данных.",
"capture_download": "Начинается загрузка собранных данных...",
"start_capture_btn": "Начать новый сбор данных"
},
"update": {
"tinycheck_needs": "Доступно новое обновление TinyCheck",
"please_click": "Нажмите кнопку ниже, чтобы обновить его",
"the_process": "Обновление может занять несколько минут, подождите...",
"update_finished": "Обновление завершено, вы будете перенаправлены...",
"update_it": "Обновить TinyCheck"
}
}

View File

@ -0,0 +1,92 @@
{
"home": {
"welcome_msg": "Vitajte v TinyCheck.",
"help_msg": "Pomôžeme Vám skontrolovať Vaše zariadenie.",
"start_btn": "Poďme nato!"
},
"analysis": {
"question": "Chcete analyzovať zachytenú komunikáciu?",
"no_btn": "Nie, iba ju uložiť",
"yes_btn": "Áno, poďme na to",
"please_wait_msg": "Počkajte prosím, prebieha analýza...",
"some_time_msg": "Áno, môže to chvíľu trvať..."
},
"capture": {
"intercept_coms_msg": "Zaznamenávanie komunikácie z/zo ",
"stop_btn": "Zastaviť záznam"
},
"generate-ap": {
"network_name": "Názov siete",
"network_password": "Sieťové heslo",
"tap_msg": "Ťuknutím na biely rám vytvoríte novú sieť.",
"generate_ap_msg": "Generujeme pre Vás pominuteľnú sieť.",
"error_msg1": "Bohužiaľ, máme nejaké problémy <br />počas tvorby AP.",
"error_msg2": "Overte si, či máte v zariadení dve rozhrania WiFi<br /> a skúste to znova reštartovať",
"restart_btn": "Reštart zariadenia"
},
"report": {
"show_full_report": "Zobraziť celú správu",
"start_new_capture": "Spustiť nový záznam",
"save_capture": "Uložiť záznam",
"numbers": [
"nula",
"jednu",
"dva",
"tri",
"štyri",
"päť",
"šesť",
"sedem",
"osem",
"deväť",
"desať",
"jedenásť"
],
"stalkerware_msg": "Vaše zariadenie je ohrozené<br /> stalkerwarom. Prosím, skontrolujte správu.",
"location_msg": "Aplikácia zdieľa Vašu<br /> súčasnú polohu s treťou stranou.",
"fine_msg": "Všetko vyzerá dobre, žiadne výstrahy.",
"high_msg": "Máte {nb} kritické/ú výstrahy/u.<br />Zdá sa, že Vaše zariadenie je ohrozené.",
"moderate_msg": "Máte {nb} mierne/u výstrahy/u,<br />Vaše zariadenie môže byť ohrozené.",
"low_msg": "Máte iba {nb} nízke/u výstrahy/u,<br /> neváhajte ich skontrolovať.",
"save_report": "Uložiť report",
"report_of": "Report z/zo",
"ip_address": "IP adresa:",
"mac_address": "MAC adresa:",
"pcap_sha1": "SHA1:",
"capture_started": "Záznam začal:",
"capture_ended": "Záznam skončil:",
"high": "vysoký",
"moderate": "mierny",
"low": "nízky"
},
"wifi-select": {
"already_connected_question": "Zdá sa, že ste už pripojený k sieti.<br />Chcete použiť aktuálne pripojenie?",
"no_btn": "Nie, použi inú",
"yes_btn": "Áno, použite ju.",
"wifi_name": "Názov Wi-Fi",
"refresh_btn": "Obnoviť zoznam sieti",
"not_connected": "Zdá sa, že nie ste pripojený na internet.",
"please_config": "Prosím nakonfigurujte Wi-Fi pripojenie.",
"lets_do_btn": "Ok, poďme na to.",
"no_internet": "Použiť offline",
"wifi_connected": "Wi-Fi pripojená",
"wifi_not_connected": "Wi-Fi nie je pripojené. Prosím, zopakujte to znova.",
"tap_keyboard": "Ťuknutím na virtuálnu klávesnicu môžete začať",
"wifi_password": "Heslo Wi-Fi",
"connect_to_it": "Pripojiť"
},
"save-capture": {
"please_connect": "Prosím pripojte USB kľúč, aby ste si uložili záznam.",
"we_are_saving": "Ukladáme záznam.",
"tap_msg": "Môžete ťuknúť na USB kľúč, ak chcete spustiť nový záznam.",
"capture_download": "Sťahovanie záznamu sa spúšťa...",
"start_capture_btn": "Spustiť ďalší záznam"
},
"update": {
"tinycheck_needs": "TinyCheck je potrebné aktualizovať na ďalšiu verziu",
"please_click": "Kliknite na tlačidlo nižšie a aktualizujte ho.",
"the_process": "Proces môže trvať niekoľko minút, prosím čakajte...",
"update_finished": "Aktualizácia dokončená, poďme obnoviť rozhranie...",
"update_it": "Aktualizovať teraz"
}
}

View File

@ -8,6 +8,13 @@ export const i18n = new VueI18n({
fallbackLocale: 'en', fallbackLocale: 'en',
messages: { messages: {
'en': require('@/locales/en.json'), 'en': require('@/locales/en.json'),
'fr': require('@/locales/fr.json') 'fr': require('@/locales/fr.json'),
'es': require('@/locales/es.json'),
'cat': require('@/locales/cat.json'),
'ru': require('@/locales/ru.json'),
'pt': require('@/locales/pt.json'),
'it': require('@/locales/it.json'),
'de': require('@/locales/de.json'),
'sk': require('@/locales/sk.json')
} }
}) })

View File

@ -54,7 +54,8 @@ export default {
this.running = false; this.running = false;
router.replace({ name: 'report', router.replace({ name: 'report',
params: { alerts : response.data.alerts, params: { alerts : response.data.alerts,
device : response.data.device, device : response.data.device,
pcap : response.data.pcap,
capture_token : this.capture_token } }); capture_token : this.capture_token } });
} }
}) })

View File

@ -24,6 +24,8 @@ export default {
var internet = this.internet var internet = this.internet
if (window.config.iface_out.charAt(0) == 'e'){ if (window.config.iface_out.charAt(0) == 'e'){
router.push({ name: 'generate-ap' }); router.push({ name: 'generate-ap' });
} else if (!window.config.choose_net && this.internet){
router.push({ name: 'generate-ap' });
} else { } else {
router.push({ name: 'wifi-select', router.push({ name: 'wifi-select',
params: { saved_ssid: saved_ssid, params: { saved_ssid: saved_ssid,

View File

@ -46,8 +46,14 @@
</div> </div>
<div v-else-if="show_report" class="report-wrapper"> <div v-else-if="show_report" class="report-wrapper">
<div class="device-ctx"> <div class="device-ctx">
<h3 style="margin: 0;">{{ $t("report.report_of") }} {{device.name}}</h3> <h3 style="margin: 0; padding-left:10px;">{{ $t("report.report_of") }} {{device.name}}</h3>
{{ $t("report.ip_address") }} {{device.ip_address}}<br />{{ $t("report.mac_address") }} {{device.mac_address}} <div class="device-ctx-legend">
{{ $t("report.pcap_sha1") }} {{ pcap.SHA1 }}<br />
{{ $t("report.capture_started") }} {{ pcap["First packet time"].split(",")[0] }}<br />
{{ $t("report.capture_ended") }} {{ pcap["Last packet time"].split(",")[0] }}<br />
<!-- {{ $t("report.ip_address") }} {{device.ip_address}}<br /> -->
{{ $t("report.mac_address") }} {{device.mac_address}}
</div>
</div> </div>
<ul class="alerts"> <ul class="alerts">
<li class="alert" v-for="alert in alerts.high" :key="alert.message"> <li class="alert" v-for="alert in alerts.high" :key="alert.message">
@ -94,6 +100,7 @@
<script> <script>
import router from '../router' import router from '../router'
import axios from 'axios'
export default { export default {
name: 'report', name: 'report',
@ -104,6 +111,7 @@ export default {
}, },
props: { props: {
device: Object, device: Object,
pcap: Object,
alerts: Array, alerts: Array,
capture_token: String capture_token: String
}, },
@ -113,7 +121,11 @@ export default {
router.replace({ name: 'save-capture', params: { capture_token: capture_token } }); router.replace({ name: 'save-capture', params: { capture_token: capture_token } });
}, },
new_capture: function() { new_capture: function() {
router.push({ name: 'generate-ap' }) axios.get('/api/misc/delete-captures', { timeout: 30000 })
.then(() => {
router.push({ name: 'generate-ap' })
})
.catch(err => (console.log(err)))
}, },
grep_keyword: function(kw, level){ grep_keyword: function(kw, level){
try { try {

View File

@ -39,6 +39,10 @@
}) })
.catch(err => (console.log(err))) .catch(err => (console.log(err)))
}, },
delete_captures: function() {
axios.get('/api/misc/delete-captures', { timeout: 30000 })
.catch(err => (console.log(err)))
},
goto_home: function() { goto_home: function() {
var list_ssids = this.list_ssids var list_ssids = this.list_ssids
var internet = this.internet var internet = this.internet
@ -46,7 +50,8 @@
} }
}, },
created: function() { created: function() {
setTimeout(function () { this.internet_check(); }.bind(this), 1000); this.delete_captures();
setTimeout(function () { this.internet_check(); }.bind(this), 5000);
} }
} }
</script> </script>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 775 KiB

After

Width:  |  Height:  |  Size: 540 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 KiB

After

Width:  |  Height:  |  Size: 324 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 KiB

After

Width:  |  Height:  |  Size: 185 KiB

View File

@ -1,17 +1,17 @@
ipwhois pymisp==2.4.165.1
M2Crypto sqlalchemy==1.4.48
pyOpenSSL ipwhois==1.2.0
pydig netaddr==0.8.0
netaddr flask==2.2.5
pyyaml flask_httpauth==4.8.0
flask pyjwt==2.4.0
flask_httpauth psutil==5.8.0
pyjwt pydig==0.4.0
sqlalchemy pyudev==0.24.0
psutil pyyaml==5.3.1
pyudev wifi==0.3.8
wifi qrcode==7.3.1
qrcode netifaces==0.11.0
netifaces weasyprint==59.0
weasyprint python-whois==0.8.0
python-whois six==1.16.0

View File

@ -1,19 +1,30 @@
CREATE TABLE "iocs" ( CREATE TABLE "iocs" (
"id" INTEGER UNIQUE, "id" INTEGER UNIQUE,
"value" TEXT NOT NULL, "value" TEXT NOT NULL,
"type" TEXT NOT NULL, "type" TEXT NOT NULL,
"tlp" TEXT NOT NULL, "tlp" TEXT NOT NULL,
"tag" TEXT NOT NULL, "tag" TEXT NOT NULL,
"source" TEXT NOT NULL, "source" TEXT NOT NULL,
"added_on" NUMERIC NOT NULL, "added_on" TEXT NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT) PRIMARY KEY("id" AUTOINCREMENT)
); );
CREATE TABLE "whitelist" ( CREATE TABLE "whitelist" (
"id" INTEGER UNIQUE, "id" INTEGER UNIQUE,
"element" TEXT NOT NULL UNIQUE, "element" TEXT NOT NULL UNIQUE,
"type" TEXT NOT NULL, "type" TEXT NOT NULL,
"source" TEXT NOT NULL, "source" TEXT NOT NULL,
"added_on" INTEGER NOT NULL, "added_on" TEXT NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE "misp" (
"id" INTEGER UNIQUE,
"name" TEXT,
"url" TEXT NOT NULL,
"apikey" TEXT NOT NULL,
"verifycert" INTEGER NOT NULL DEFAULT 0,
"added_on" TEXT NOT NULL,
"last_sync" TEXT NOT NULL DEFAULT 0,
PRIMARY KEY("id" AUTOINCREMENT) PRIMARY KEY("id" AUTOINCREMENT)
); );

File diff suppressed because one or more lines are too long

View File

@ -51,7 +51,9 @@ frontend:
virtual_keyboard: true virtual_keyboard: true
user_lang: userlang user_lang: userlang
update: updateoption update: updateoption
choose_net: false
http_port: 80
# NETWORK - # NETWORK -
# Some elements related to the network configuration, such as # Some elements related to the network configuration, such as
# the interfaces (updated during the install), the list of SSIDs # the interfaces (updated during the install), the list of SSIDs
@ -59,7 +61,7 @@ frontend:
# #
network: network:
in: iface_in in: iface_in
internet_check: http://example.com internet_check: https://8.8.8.8
out: iface_out out: iface_out
ssids: ssids:
- wireless - wireless
@ -76,6 +78,6 @@ network:
watchers: watchers:
iocs: iocs:
- https://raw.githubusercontent.com/KasperskyLab/TinyCheck/main/assets/iocs.json - https://raw.githubusercontent.com/KasperskyLab/TinyCheck/main/assets/iocs.json
- https://raw.githubusercontent.com/Te-k/stalkerware-indicators/master/indicators-for-tinycheck.json - https://raw.githubusercontent.com/AssoEchap/stalkerware-indicators/master/generated/indicators-for-tinycheck.json
whitelists: whitelists:
- https://raw.githubusercontent.com/KasperskyLab/TinyCheck/main/assets/whitelist.json - https://raw.githubusercontent.com/KasperskyLab/TinyCheck/main/assets/whitelist.json

View File

@ -3,10 +3,10 @@
CURRENT_USER="${SUDO_USER}" CURRENT_USER="${SUDO_USER}"
SCRIPT_PATH="$( cd "$(dirname "$0")" ; pwd -P )" SCRIPT_PATH="$( cd "$(dirname "$0")" ; pwd -P )"
HOST="$( hostname )" HOST="$( hostname )"
IFACES="$( ifconfig -a | grep -Eo '[a-z0-9]{4,14}\: ' | grep -oE [a-z0-9]+ )" IFACES="$( ip a s | grep -Eo '[a-z0-9]{4,15}\: ' | grep -oE [a-z0-9]+ )"
IFACE_OUT="" IFACE_OUT=""
IFACE_IN="" IFACE_IN=""
LOCALES=(en fr cat es) LOCALES=(en fr cat es ru pt de it)
welcome_screen() { welcome_screen() {
cat << "EOF" cat << "EOF"
@ -29,7 +29,7 @@ check_operating_system() {
error="\e[91m [✘] Need to be run on a Debian-like operating system, exiting.\e[39m" error="\e[91m [✘] Need to be run on a Debian-like operating system, exiting.\e[39m"
if [[ -f "/etc/os-release" ]]; then if [[ -f "/etc/os-release" ]]; then
if [[ $(cat /etc/os-release | grep "ID_LIKE=debian") ]]; then if [[ $(cat /etc/os-release | grep -e "ID_LIKE=\"\?debian" -e "ID=debian") ]]; then
echo -e "\e[92m [✔] Debian-like operating system\e[39m" echo -e "\e[92m [✔] Debian-like operating system\e[39m"
else else
echo -e "$error" echo -e "$error"
@ -51,7 +51,7 @@ set_userlang() {
if [[ " ${LOCALES[@]} " =~ " ${lang} " ]]; then if [[ " ${LOCALES[@]} " =~ " ${lang} " ]]; then
sed -i "s/userlang/${lang}/g" /usr/share/tinycheck/config.yaml sed -i "s/userlang/${lang}/g" /usr/share/tinycheck/config.yaml
echo -e "\e[92m [✔] User language settled!\e[39m" echo -e "\e[92m [✔] User language settled!\e[39m"
else else
echo -e "\e[91m [✘] You must choose between the languages proposed, let's retry.\e[39m" echo -e "\e[91m [✘] You must choose between the languages proposed, let's retry.\e[39m"
set_userlang set_userlang
fi fi
@ -69,7 +69,7 @@ set_credentials() {
read -s password2 read -s password2
echo "" echo ""
if [ $password1 = $password2 ]; then if [ "$password1" == "$password2" ]; then
password=$(echo -n "$password1" | sha256sum | cut -d" " -f1) password=$(echo -n "$password1" | sha256sum | cut -d" " -f1)
sed -i "s/userlogin/$login/g" /usr/share/tinycheck/config.yaml sed -i "s/userlogin/$login/g" /usr/share/tinycheck/config.yaml
sed -i "s/userpassword/$password/g" /usr/share/tinycheck/config.yaml sed -i "s/userpassword/$password/g" /usr/share/tinycheck/config.yaml
@ -131,7 +131,7 @@ create_services() {
# Create services to launch the two servers. # Create services to launch the two servers.
echo -e "\e[39m[+] Creating services\e[39m" echo -e "\e[39m[+] Creating services\e[39m"
echo -e "\e[92m [✔] Creating frontend service\e[39m" echo -e "\e[92m [✔] Creating frontend service\e[39m"
cat >/lib/systemd/system/tinycheck-frontend.service <<EOL cat >/lib/systemd/system/tinycheck-frontend.service <<EOL
[Unit] [Unit]
@ -200,10 +200,10 @@ WantedBy=multi-user.target
EOL EOL
echo -e "\e[92m [✔] Enabling services\e[39m" echo -e "\e[92m [✔] Enabling services\e[39m"
systemctl enable tinycheck-frontend &> /dev/null systemctl enable tinycheck-frontend &> /dev/null
systemctl enable tinycheck-backend &> /dev/null systemctl enable tinycheck-backend &> /dev/null
systemctl enable tinycheck-kiosk &> /dev/null systemctl enable tinycheck-kiosk &> /dev/null
systemctl enable tinycheck-watchers &> /dev/null systemctl enable tinycheck-watchers &> /dev/null
} }
configure_dnsmask() { configure_dnsmask() {
@ -221,7 +221,7 @@ configure_dnsmask() {
interface=${IFACE_IN} interface=${IFACE_IN}
dhcp-range=192.168.100.2,192.168.100.3,255.255.255.0,24h dhcp-range=192.168.100.2,192.168.100.3,255.255.255.0,24h
EOL EOL
else else
echo -e "\e[91m [✘] /etc/dnsmasq.conf doesn't exist, configuration not updated.\e[39m" echo -e "\e[91m [✘] /etc/dnsmasq.conf doesn't exist, configuration not updated.\e[39m"
fi fi
} }
@ -229,7 +229,7 @@ EOL
configure_dhcpcd() { configure_dhcpcd() {
# Configure DHCPCD by appending few lines to his configuration. # Configure DHCPCD by appending few lines to his configuration.
# Allows to prevent the interface to stick to wpa_supplicant config. # Allows to prevent the interface to stick to wpa_supplicant config.
echo -e "\e[39m[+] Configuring dhcpcd\e[39m" echo -e "\e[39m[+] Configuring dhcpcd\e[39m"
echo -e "\e[92m [✔] Changing dhcpcd configuration\e[39m" echo -e "\e[92m [✔] Changing dhcpcd configuration\e[39m"
if [[ -f "/etc/dhcpcd.conf" ]]; then if [[ -f "/etc/dhcpcd.conf" ]]; then
@ -241,7 +241,7 @@ interface ${IFACE_IN}
static ip_address=192.168.100.1/24 static ip_address=192.168.100.1/24
nohook wpa_supplicant nohook wpa_supplicant
EOL EOL
else else
echo -e "\e[91m [✘] /etc/dhcpcd.conf doesn't exist, configuration not updated.\e[39m" echo -e "\e[91m [✘] /etc/dhcpcd.conf doesn't exist, configuration not updated.\e[39m"
fi fi
} }
@ -264,12 +264,16 @@ change_hostname() {
install_package() { install_package() {
# Install associated packages by using aptitude. # Install associated packages by using aptitude.
if [[ $1 == "dnsmasq" || $1 == "hostapd" || $1 == "tshark" || $1 == "sqlite3" || $1 == "suricata" || $1 == "unclutter" ]]; then if [[ $1 == "dnsmasq" || $1 == "hostapd" || $1 == "tshark" || $1 == "sqlite3" || $1 == "unclutter" || $1 == "swig" || $1 == "curl" ]]; then
apt-get install $1 -y apt-get install $1 -y
elif [[ $1 == "suricata" ]];then
add-apt-repository ppa:oisf/suricata-stable
apt-get install suricata -y
elif [[ $1 == "zeek" ]]; then elif [[ $1 == "zeek" ]]; then
distrib=$(cat /etc/os-release | grep -E "^ID=" | cut -d"=" -f2) distrib=$(cat /etc/os-release | grep -E "^ID=" | cut -d"=" -f2)
version=$(cat /etc/os-release | grep "VERSION_ID" | cut -d"\"" -f2) version=$(cat /etc/os-release | grep "VERSION_ID" | cut -d"\"" -f2)
if [[ $distrib == "debian" || $distrib == "ubuntu" ]]; then if [[ $distrib == "debian" ]]; then
echo "deb http://download.opensuse.org/repositories/security:/zeek/Debian_$version/ /" > /etc/apt/sources.list.d/security:zeek.list echo "deb http://download.opensuse.org/repositories/security:/zeek/Debian_$version/ /" > /etc/apt/sources.list.d/security:zeek.list
wget -nv "https://download.opensuse.org/repositories/security:zeek/Debian_$version/Release.key" -O Release.key wget -nv "https://download.opensuse.org/repositories/security:zeek/Debian_$version/Release.key" -O Release.key
elif [[ $distrib == "ubuntu" ]]; then elif [[ $distrib == "ubuntu" ]]; then
@ -282,25 +286,47 @@ install_package() {
apt-key add - < Release.key apt-key add - < Release.key
rm Release.key && sudo apt-get update rm Release.key && sudo apt-get update
apt-get install zeek -y apt-get install zeek -y
elif [[ $1 == "nodejs" ]]; then elif [[ $1 == "node" ]]; then
curl -sL https://deb.nodesource.com/setup_12.x | bash curl -sL https://deb.nodesource.com/setup_14.x | bash -
apt-get install -y nodejs apt-get install -y nodejs
elif [[ $1 == "dig" ]]; then elif [[ $1 == "dig" ]]; then
apt-get install -y dnsutils apt-get install -y dnsutils
elif [[ $1 == "pip" ]]; then
apt-get install -y python3-pip
elif [[ $1 == "dhcpcd" ]]; then
apt-get install -y dhcpcd5
fi
}
check_dnsmasq() {
readlink /etc/resolv.conf
status=$?
if [[ $status -eq 0 && -f "/usr/sbin/dnsmasq" ]]; then
systemctl disable systemd-resolved
systemctl stop systemd-resolved
unlink /etc/resolv.conf
echo "nameserver 8.8.8.8" | tee /etc/resolv.conf
install_package dnsmasq
else
install_package dnsmasq
fi fi
} }
check_dependencies() { check_dependencies() {
# Check binary dependencies associated to the project. # Check binary dependencies associated to the project.
# If not installed, call install_package with the package name. # If not installed, call install_package with the package name.
check_dnsmasq
bins=("/usr/sbin/hostapd" bins=("/usr/sbin/hostapd"
"/usr/sbin/dnsmasq"
"/opt/zeek/bin/zeek" "/opt/zeek/bin/zeek"
"/usr/bin/tshark" "/usr/bin/tshark"
"/usr/bin/dig" "/usr/bin/dig"
"/usr/bin/suricata" "/usr/bin/suricata"
"/usr/bin/unclutter" "/usr/bin/unclutter"
"/usr/bin/sqlite3") "/usr/bin/sqlite3"
"/usr/bin/pip"
"/usr/bin/swig"
"/usr/sbin/dhcpcd"
"/usr/bin/curl")
echo -e "\e[39m[+] Checking dependencies...\e[39m" echo -e "\e[39m[+] Checking dependencies...\e[39m"
for bin in "${bins[@]}" for bin in "${bins[@]}"
@ -312,8 +338,7 @@ check_dependencies() {
install_package ${bin##*/} install_package ${bin##*/}
fi fi
done done
echo -e "\e[39m[+] Install NodeJS...\e[39m" install_package node
install_package nodejs
echo -e "\e[39m[+] Install Python packages...\e[39m" echo -e "\e[39m[+] Install Python packages...\e[39m"
python3 -m pip install -r "$SCRIPT_PATH/assets/requirements.txt" python3 -m pip install -r "$SCRIPT_PATH/assets/requirements.txt"
} }
@ -327,6 +352,7 @@ compile_vuejs() {
create_desktop() { create_desktop() {
# Create desktop icon to lauch TinyCheck in a browser # Create desktop icon to lauch TinyCheck in a browser
if [[ -d "/home/$CURRENT_USER/Desktop/" ]]; then
echo -e "\e[39m[+] Create Desktop icon under /home/${CURRENT_USER}/Desktop\e[39m" echo -e "\e[39m[+] Create Desktop icon under /home/${CURRENT_USER}/Desktop\e[39m"
cat >"/home/$CURRENT_USER/Desktop/tinycheck.desktop" <<EOL cat >"/home/$CURRENT_USER/Desktop/tinycheck.desktop" <<EOL
#!/usr/bin/env xdg-open #!/usr/bin/env xdg-open
@ -335,11 +361,12 @@ create_desktop() {
Version=1.0 Version=1.0
Type=Application Type=Application
Terminal=false Terminal=false
Exec=chromium-browser http://localhost Exec=bash /usr/share/tinycheck/kiosk.sh
Name=TinyCheck Name=TinyCheck
Comment=Launcher for the TinyCheck frontend Comment=Launcher for the TinyCheck frontend
Icon=/usr/share/tinycheck/app/frontend/src/assets/icon.png Icon=/usr/share/tinycheck/app/frontend/src/assets/icon.png
EOL EOL
fi
} }
cleaning() { cleaning() {
@ -354,46 +381,47 @@ cleaning() {
systemctl disable suricata.service &> /dev/null systemctl disable suricata.service &> /dev/null
# Removing some useless dependencies. # Removing some useless dependencies.
sudo apt autoremove -y &> /dev/null sudo apt autoremove -y &> /dev/null
} }
check_interfaces(){ check_interfaces(){
# Get the current connected interface name. # Get the current connected interface name.
ciface="$(route | grep default | head -1 | grep -Eo '[a-z0-9]+$')" ciface="$(ip r l default |grep -Po '(?<=(dev ))(\S+)')"
# Setup of iface_out which can be any interface, # Setup of iface_out which can be any interface,
# but needs to be connected now or in the future. # but needs to be connected now or in the future.
echo -n "[?] The interface $ciface is connected. Do you want to use it as a bridge to Internet (network/out) ? [Yes/No] " echo -n "[?] The interface $ciface is connected. Do you want to use it as a bridge to Internet (network/out) ? [Yes/No] "
read answer read answer
if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]] if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]
then then
IFACES=( "${IFACES[@]/$ciface}" ) IFACES=( "${IFACES[@]/$ciface}" )
IFACE_OUT=$ciface IFACE_OUT=$ciface
echo -e "\e[92m [✔] $ciface settled as a bridge to the Internet\e[39m" echo -e "\e[92m [✔] $ciface settled as a bridge to the Internet\e[39m"
else else
IFACES=( "${IFACES[@]/$ciface}" ) IFACES=( "${IFACES[@]/$ciface}" )
for iface in $IFACES; for iface in $IFACES;
do do
config="$(ifconfig $iface)" config="$(ip a s $iface)"
echo -n "[?] Do you want to use $iface as a bridge to Internet (network/out) ? [Y/n] " echo -n "[?] Do you want to use $iface as a bridge to Internet (network/out) ? [Y/n] "
read answer read answer
if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]] if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]
then then
IFACE_OUT=$iface IFACE_OUT=$iface
IFACES=( "${IFACES[@]/$iface}" ) IFACES=( "${IFACES[@]/$iface}" )
echo -e "\e[92m [✔] $iface settled as a bridge to the Internet\e[39m" echo -e "\e[92m [✔] $iface settled as a bridge to the Internet\e[39m"
break break
fi fi
done done
fi fi
# Setup of iface_in which can be a only a # Setup of iface_in which can be a only a
# Wi-Fi interface with AP mode available. # Wi-Fi interface with AP mode available.
for iface in $IFACES; for iface in $IFACES;
do do
if echo "$iface" | grep -Eq "(wlan[0-9]|wl[a-z0-9]{20})"; then if echo "$iface" | grep -Eq "(wlan[0-9]|wl[a-z0-9]{,20})"; then
config="$(ifconfig $iface)" # Get the iface logic configuration config="$(ip a s $iface)" # Get the iface logic configuration
if echo "$config" | grep -qv "inet "; then # Test if not currently connected if echo "$config" | grep -qv "inet "; then # Test if not currently connected
hw="$(iw $iface info | grep wiphy | cut -d" " -f2)" # Get the iface hardware id. hw="$(iw $iface info | grep wiphy | cut -d" " -f2)" # Get the iface hardware id.
info="$(iw phy$hw info)" # Get the iface hardware infos. info="$(iw phy$hw info)" # Get the iface hardware infos.
@ -436,14 +464,20 @@ change_configs() {
} }
feeding_iocs() { feeding_iocs() {
echo -e "\e[39m[+] Feeding your TinyCheck instance with fresh IOCs and whitelist." echo -e "\e[39m[+] Feeding your TinyCheck instance with fresh IOCs and whitelist, please wait."
python3 /usr/share/tinycheck/server/backend/watchers.py python3 /usr/share/tinycheck/server/backend/watchers.py 2>/dev/null
} }
reboot_box() { reboot_box() {
echo -e "\e[92m[+] The system is going to reboot\e[39m" echo -e "\e[92m[+] The system is going to reboot, OK ?\e[39m"
sleep 5 read answer
reboot if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]
then
sleep 5
reboot
else
exit
fi
} }
if [[ $EUID -ne 0 ]]; then if [[ $EUID -ne 0 ]]; then
@ -480,4 +514,4 @@ else
feeding_iocs feeding_iocs
cleaning cleaning
reboot_box reboot_box
fi fi

View File

@ -1,11 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from flask import Blueprint, jsonify, Response from flask import Blueprint, jsonify, Response, request
from app.decorators import require_header_token, require_get_token from app.decorators import require_header_token, require_get_token
from app.classes.iocs import IOCs from app.classes.iocs import IOCs
import json import json
from urllib.parse import unquote
ioc_bp = Blueprint("ioc", __name__) ioc_bp = Blueprint("ioc", __name__)
ioc = IOCs() ioc = IOCs()
@ -19,10 +20,26 @@ def add(ioc_type, ioc_tag, ioc_tlp, ioc_value):
:return: status of the operation in JSON :return: status of the operation in JSON
""" """
source = "backend" source = "backend"
if ioc_type == "snort":
ioc_value = unquote("/".join(request.full_path.split("/")[7:]))
res = IOCs.add(ioc_type, ioc_tag, ioc_tlp, ioc_value, source) res = IOCs.add(ioc_type, ioc_tag, ioc_tlp, ioc_value, source)
return jsonify(res) return jsonify(res)
@ioc_bp.route('/add_post', methods=['POST'])
@require_header_token
def add_post():
"""
Parse and add an IOC to the database using the post method.
:return: status of the operation in JSON
"""
data = json.loads(request.data)
ioc = data["data"]["ioc"]
res = IOCs.add(ioc["ioc_type"], ioc["ioc_tag"], ioc["ioc_tlp"], ioc["ioc_value"], ioc["ioc_source"])
return jsonify(res)
@ioc_bp.route('/delete/<ioc_id>', methods=['GET']) @ioc_bp.route('/delete/<ioc_id>', methods=['GET'])
@require_header_token @require_header_token
def delete(ioc_id): def delete(ioc_id):

View File

@ -0,0 +1,44 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Blueprint, jsonify, Response, request
from app.decorators import require_header_token, require_get_token
from app.classes.misp import MISP
import json
misp_bp = Blueprint("misp", __name__)
misp = MISP()
@misp_bp.route('/add', methods=['POST'])
@require_header_token
def add_instance():
"""
Parse and add a MISP instance to the database.
:return: status of the operation in JSON
"""
data = json.loads(request.data)
res = misp.add_instance(data["data"]["instance"])
return jsonify(res)
@misp_bp.route('/delete/<misp_id>', methods=['GET'])
@require_header_token
def delete_instance(misp_id):
"""
Delete a MISP instance by its id to the database.
:return: status of the operation in JSON
"""
res = misp.delete_instance(misp_id)
return jsonify(res)
@misp_bp.route('/get_all', methods=['GET'])
@require_header_token
def get_all():
"""
Retreive a list of all MISP instances.
:return: list of MISP instances in JSON.
"""
res = misp.get_instances()
return jsonify({"results": [i for i in res]})

View File

@ -56,7 +56,12 @@ class IOCs(object):
db.session.commit() db.session.commit()
return {"status": True, return {"status": True,
"message": "IOC added", "message": "IOC added",
"ioc": escape(ioc_value)} "ioc": escape(ioc_value),
"type": escape(ioc_type),
"tlp": escape(ioc_tlp),
"tag": escape(ioc_tag),
"source": escape(source),
"added_on": escape(added_on)}
else: else:
return {"status": False, return {"status": False,
"message": "Wrong IOC format", "message": "Wrong IOC format",
@ -111,7 +116,8 @@ class IOCs(object):
"type": ioc["type"], "type": ioc["type"],
"tag": ioc["tag"], "tag": ioc["tag"],
"tlp": ioc["tlp"], "tlp": ioc["tlp"],
"value": ioc["value"]} "value": ioc["value"],
"source": ioc["source"]}
@staticmethod @staticmethod
def get_types(): def get_types():

View File

@ -0,0 +1,159 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from app import db
from app.db.models import MISPInst
from app.definitions import definitions as defs
from sqlalchemy.sql import exists
from urllib.parse import unquote
from flask import escape
from pymisp import PyMISP
import re
import time
import sys
class MISP(object):
def __init__(self):
return None
def add_instance(self, instance):
"""
Parse and add a MISP instance to the database.
:return: status of the operation in JSON
"""
url = instance["url"]
name = instance["name"]
apikey = instance["key"]
verify = instance["ssl"]
last_sync = int(time.time()-31536000) # One year
sameinstances = db.session.query(MISPInst).filter(
MISPInst.url == url, MISPInst.apikey == apikey)
if sameinstances.count():
return {"status": False,
"message": "This MISP instance already exists"}
if name:
if self.test_instance(url, apikey, verify):
added_on = int(time.time())
db.session.add(MISPInst(name, escape(
url), apikey, verify, added_on, last_sync))
db.session.commit()
return {"status": True,
"message": "MISP instance added"}
else:
return {"status": False,
"message": "Please verify the connection to the MISP instance"}
else:
return {"status": False,
"message": "Please provide a name for your instance"}
@staticmethod
def delete_instance(misp_id):
"""
Delete a MISP instance by its id in the database.
:return: status of the operation in JSON
"""
if db.session.query(exists().where(MISPInst.id == misp_id)).scalar():
db.session.query(MISPInst).filter_by(id=misp_id).delete()
db.session.commit()
return {"status": True,
"message": "MISP instance deleted"}
else:
return {"status": False,
"message": "MISP instance not found"}
def get_instances(self):
"""
Get MISP instances from the database
:return: generator of the records.
"""
for misp in db.session.query(MISPInst).all():
misp = misp.__dict__
yield {"id": misp["id"],
"name": misp["name"],
"url": misp["url"],
"apikey": misp["apikey"],
"verifycert": True if misp["verifycert"] else False,
"connected": self.test_instance(misp["url"], misp["apikey"], misp["verifycert"]),
"lastsync": misp["last_sync"]}
@staticmethod
def test_instance(url, apikey, verify):
"""
Test the connection of the MISP instance.
:return: generator of the records.
"""
try:
PyMISP(url, apikey, verify)
return True
except:
return False
@staticmethod
def update_sync(misp_id):
"""
Update the last synchronization date by the actual date.
:return: bool, True if updated.
"""
try:
misp = MISPInst.query.get(int(misp_id))
misp.last_sync = int(time.time())
db.session.commit()
return True
except:
return False
@staticmethod
def get_iocs(misp_id):
"""
Get all IOCs from specific MISP instance
:return: generator containing the IOCs.
"""
misp = MISPInst.query.get(int(misp_id))
if misp is not None:
if misp.url and misp.apikey:
try:
# Connect to MISP instance and get network activity attributes.
m = PyMISP(misp.url, misp.apikey, misp.verifycert)
r = m.search("attributes", category="Network activity", date_from=int(misp.last_sync))
except:
print("Unable to connect to the MISP instance ({}/{}).".format(misp.url, misp.apikey))
return []
for attr in r["Attribute"]:
if attr["type"] in ["ip-dst", "domain", "snort", "x509-fingerprint-sha1"]:
ioc = {"value": attr["value"],
"type": None,
"tag": "suspect",
"tlp": "white"}
# Deduce the IOC type.
if re.match(defs["iocs_types"][0]["regex"], attr["value"]):
ioc["type"] = "ip4addr"
elif re.match(defs["iocs_types"][1]["regex"], attr["value"]):
ioc["type"] = "ip6addr"
elif re.match(defs["iocs_types"][2]["regex"], attr["value"]):
ioc["type"] = "cidr"
elif re.match(defs["iocs_types"][3]["regex"], attr["value"]):
ioc["type"] = "domain"
elif re.match(defs["iocs_types"][4]["regex"], attr["value"]):
ioc["type"] = "sha1cert"
elif "alert " in attr["value"][0:6]:
ioc["type"] = "snort"
else:
continue
if "Tag" in attr:
for tag in attr["Tag"]:
# Add a TLP to the IOC if defined in tags.
tlp = re.search(r"^(?:tlp:)(red|green|amber|white)", tag['name'].lower())
if tlp: ioc["tlp"] = tlp.group(1)
# Add possible tag (need to match TinyCheck tags)
if tag["name"].lower() in [t["tag"] for t in defs["iocs_tags"]]:
ioc["tag"] = tag["name"].lower()
yield ioc

View File

@ -1,5 +1,6 @@
from app import db from app import db
class Ioc(db.Model): class Ioc(db.Model):
def __init__(self, value, type, tlp, tag, source, added_on): def __init__(self, value, type, tlp, tag, source, added_on):
self.value = value self.value = value
@ -9,6 +10,7 @@ class Ioc(db.Model):
self.source = source self.source = source
self.added_on = added_on self.added_on = added_on
class Whitelist(db.Model): class Whitelist(db.Model):
def __init__(self, element, type, source, added_on): def __init__(self, element, type, source, added_on):
self.element = element self.element = element
@ -16,5 +18,17 @@ class Whitelist(db.Model):
self.source = source self.source = source
self.added_on = added_on self.added_on = added_on
class MISPInst(db.Model):
def __init__(self, name, url, key, ssl, added_on, last_sync):
self.name = name
self.url = url
self.apikey = key
self.verifycert = ssl
self.added_on = added_on
self.last_sync = last_sync
db.mapper(Whitelist, db.Table('whitelist', db.metadata, autoload=True)) db.mapper(Whitelist, db.Table('whitelist', db.metadata, autoload=True))
db.mapper(Ioc, db.Table('iocs', db.metadata, autoload=True)) db.mapper(Ioc, db.Table('iocs', db.metadata, autoload=True))
db.mapper(MISPInst, db.Table('misp', db.metadata, autoload=True))

View File

@ -42,7 +42,7 @@ def require_header_token(f):
def decorated(*args, **kwargs): def decorated(*args, **kwargs):
try: try:
token = request.headers['X-Token'] token = request.headers['X-Token']
jwt.decode(token, app.config["SECRET_KEY"]) jwt.decode(token, app.config["SECRET_KEY"], "HS256")
return f(*args, **kwargs) return f(*args, **kwargs)
except: except:
return jsonify({"message": "JWT verification failed"}) return jsonify({"message": "JWT verification failed"})
@ -58,7 +58,7 @@ def require_get_token(f):
def decorated(*args, **kwargs): def decorated(*args, **kwargs):
try: try:
token = request.args.get("token") token = request.args.get("token")
jwt.decode(token, app.config["SECRET_KEY"]) jwt.decode(token, app.config["SECRET_KEY"], "HS256")
return f(*args, **kwargs) return f(*args, **kwargs)
except: except:
return jsonify({"message": "JWT verification failed"}) return jsonify({"message": "JWT verification failed"})

View File

@ -0,0 +1,191 @@
#!/usr/bin/python
import os
import subprocess
import platform
import socket
import pkg_resources
import psutil
__author__ = 'Eugeny N Ablesov'
__version__ = '1.0.17'
def collect_accounts_info():
""" This call collects generic information about
user accounts presented on system running TinyCheck.
No personal information collected or provided by this call.
"""
accs = { }
users = psutil.users()
for user in users:
accs[user.name + '@' + user.host] = {
'started': user.started,
'term': user.terminal
}
alt_user = os.getenv('SUDO_USER', os.getenv('USER'))
usr = 'root' if os.path.expanduser('~') == '/root' else alt_user
pid = psutil.Process().pid
term = psutil.Process().terminal() if 'Linux' in platform.system() else 'win'
accs[usr + '@' + term] = { 'pid': pid }
return accs
def collect_os_info():
""" This call collects generic information about
operating system running TinyCheck.
No personal information collected or provided by this call.
"""
os_info = { }
os_info['system'] = platform.system()
os_info['release'] = platform.release()
os_info['version'] = platform.version()
os_info['platform'] = platform.platform(aliased=True)
if 'Windows' in os_info['system']:
os_info['dist'] = platform.win32_ver()
if 'Linux' in os_info['system']:
os_info['dist'] = platform.libc_ver()
return os_info
def collect_hardware_info():
""" This call collects information about hardware running TinyCheck.
No personal information collected or provided by this call.
"""
hw_info = { }
hw_info['arch'] = platform.architecture()
hw_info['machine'] = platform.machine()
hw_info['cpus'] = psutil.cpu_count(logical=False)
hw_info['cores'] = psutil.cpu_count()
hw_info['load'] = psutil.getloadavg()
disk_info = psutil.disk_usage('/')
hw_info['disk'] = {
'total': disk_info.total,
'used': disk_info.used,
'free': disk_info.free
}
return hw_info
def collect_network_info():
""" This call collects information about
network configuration and state running TinyCheck.
No personal information collected or provided by this call.
"""
net_info = { }
net_info['namei'] = socket.if_nameindex()
addrs = psutil.net_if_addrs()
state = psutil.net_io_counters(pernic=True)
for interface in addrs.keys():
net_info[interface] = { }
int_info = state[interface]
props = [p for p in dir(int_info)
if not p.startswith("_")
and not p == "index"
and not p == "count"]
for prop in props:
net_info[interface][prop] = getattr(int_info, prop)
return net_info
def collect_dependency_info(package_list):
""" This call collects information about
python packages required to run TinyCheck.
No personal information collected or provided by this call.
"""
dependencies = { }
installed_packages = list(pkg_resources.working_set)
installed_packages_list = sorted(["%s==%s"
% (installed.key, installed.version)
for installed in installed_packages])
for pkg in installed_packages_list:
[package_name, package_version] = pkg.split('==')
if package_name in package_list:
dependencies[package_name] = package_version
return dependencies
def collect_db_tables_records_count(db_path, tables):
result = { }
for table in tables:
query = 'SELECT COUNT(*) FROM %s' % (table)
sqlite_call = subprocess.Popen(['sqlite3', db_path, query], stdout = subprocess.PIPE)
stout, sterr = sqlite_call.communicate()
val = stout.decode("utf-8")
recs = int(val) if val else 0
result[table] = recs
return result
def collect_internal_state(db_path, tables, to_check):
""" This call collects information about
installed TinyCheck instance and its internal state.
No personal information collected or provided by this call.
"""
state_ = { }
available = os.path.isfile(db_path)
dbsize = 0
state_['db'] = {
'available': available,
'size': dbsize
}
state_['db']['records'] = { }
if available:
state_['db']['size'] = os.stat(db_path).st_size
state_['db']['records'] = collect_db_tables_records_count(db_path, tables)
services_ = { }
for alias in to_check:
status = subprocess.call(['systemctl', 'is-active', '--quiet', '%s' % (to_check[alias])])
state = ''
if status != 0:
sysctl_call = subprocess.Popen(
["systemctl", "status", "%s" % (to_check[alias]),
r"|",
"grep",
r"''"],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
stout, sterr = sysctl_call.communicate()
state = stout.decode("utf-8")
errs = sterr.decode("utf-8")
if "could not be found" in errs:
state = 'Service not found'
services_[alias] = {
'running': status == 0,
'status': status,
'state': state
}
state_['svc'] = services_
return state_
def main():
print("TinyCheck diagnostics script.\nVersion: %s" % (__version__))
print("")
db_path = '/usr/share/tinycheck/tinycheck.sqlite3'
tables = ['iocs', 'whitelist', 'misp']
services = { }
services['frontend'] = 'tinycheck-frontend.service'
services['backend'] = 'tinycheck-backend.service'
services['kiosk'] = 'tinycheck-kiosk.service'
services['watchers'] = 'tinycheck-watchers.service'
deps = [
'pymisp', 'sqlalchemy', 'ipwhois',
'netaddr', 'flask', 'flask_httpauth',
'pyjwt', 'psutil', 'pydig', 'pyudev',
'pyyaml', 'wifi', 'qrcode', 'netifaces',
'weasyprint', 'python-whois', 'six' ]
diagnostics = { }
diagnostics['acc'] = collect_accounts_info()
diagnostics['os'] = collect_os_info()
diagnostics['hw'] = collect_hardware_info()
diagnostics['net'] = collect_network_info()
diagnostics['deps'] = collect_dependency_info(deps)
diagnostics['state'] = collect_internal_state(db_path, tables, services)
report = { 'diagnostics': diagnostics }
print(report)
print("")
if __name__ == '__main__':
main()

View File

@ -6,10 +6,10 @@ from app.decorators import auth
from app.blueprints.ioc import ioc_bp from app.blueprints.ioc import ioc_bp
from app.blueprints.whitelist import whitelist_bp from app.blueprints.whitelist import whitelist_bp
from app.blueprints.config import config_bp from app.blueprints.config import config_bp
from app.blueprints.misp import misp_bp
import datetime import datetime
import secrets import secrets
import jwt import jwt
from OpenSSL import SSL
from app.utils import read_config from app.utils import read_config
from sys import path from sys import path
@ -34,7 +34,7 @@ def get_token():
""" """
token = jwt.encode({"exp": datetime.datetime.now() + token = jwt.encode({"exp": datetime.datetime.now() +
datetime.timedelta(hours=24)}, app.config["SECRET_KEY"]) datetime.timedelta(hours=24)}, app.config["SECRET_KEY"])
return jsonify({"token": token.decode("utf8")}) return jsonify({"token": token})
@app.route("/<p>/<path:path>", methods=["GET"]) @app.route("/<p>/<path:path>", methods=["GET"])
@ -56,13 +56,13 @@ def page_not_found(e):
app.register_blueprint(ioc_bp, url_prefix='/api/ioc') app.register_blueprint(ioc_bp, url_prefix='/api/ioc')
app.register_blueprint(whitelist_bp, url_prefix='/api/whitelist') app.register_blueprint(whitelist_bp, url_prefix='/api/whitelist')
app.register_blueprint(config_bp, url_prefix='/api/config') app.register_blueprint(config_bp, url_prefix='/api/config')
app.register_blueprint(misp_bp, url_prefix='/api/misp')
if __name__ == '__main__': if __name__ == '__main__':
ssl_cert = "{}/{}".format(path[0], 'cert.pem') ssl_cert = "{}/{}".format(path[0], 'cert.pem')
ssl_key = "{}/{}".format(path[0], 'key.pem') ssl_key = "{}/{}".format(path[0], 'key.pem')
if read_config(("backend", "remote_access")): if read_config(("backend", "remote_access")):
app.run(host="0.0.0.0", port=443, app.run(host="0.0.0.0", port=443, ssl_context=(ssl_cert, ssl_key))
ssl_context=(ssl_cert, ssl_key))
else: else:
app.run(port=443, ssl_context=(ssl_cert, ssl_key)) app.run(port=443)

View File

@ -4,6 +4,7 @@
from app.utils import read_config from app.utils import read_config
from app.classes.iocs import IOCs from app.classes.iocs import IOCs
from app.classes.whitelist import WhiteList from app.classes.whitelist import WhiteList
from app.classes.misp import MISP
import requests import requests
import json import json
@ -16,11 +17,6 @@ from multiprocessing import Process
in the configuration file. This in order to get in the configuration file. This in order to get
automatically new iocs / elements from remote automatically new iocs / elements from remote
sources without user interaction. sources without user interaction.
As of today the default export JSON format from
the backend and unauthenticated HTTP requests
are accepted. The code is little awkward, it'll
be better in a next version ;)
""" """
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
@ -29,7 +25,7 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def watch_iocs(): def watch_iocs():
""" """
Retrieve IOCs from the remote URLs defined in config/watchers. Retrieve IOCs from the remote URLs defined in config/watchers.
For each (new ?) IOC, add it to the DB. For each IOC, add it to the DB.
""" """
# Retrieve the URLs from the configuration # Retrieve the URLs from the configuration
@ -41,6 +37,7 @@ def watch_iocs():
if w["status"] == False: if w["status"] == False:
iocs = IOCs() iocs = IOCs()
iocs_list = [] iocs_list = []
to_delete = []
try: try:
res = requests.get(w["url"], verify=False) res = requests.get(w["url"], verify=False)
if res.status_code == 200: if res.status_code == 200:
@ -89,6 +86,7 @@ def watch_whitelists():
if w["status"] == False: if w["status"] == False:
whitelist = WhiteList() whitelist = WhiteList()
elements = [] elements = []
to_delete = []
try: try:
res = requests.get(w["url"], verify=False) res = requests.get(w["url"], verify=False)
if res.status_code == 200: if res.status_code == 200:
@ -120,8 +118,32 @@ def watch_whitelists():
break break
def watch_misp():
"""
Retrieve IOCs from misp instances. Each new element is
tested and then added to the database.
"""
iocs, misp = IOCs(), MISP()
instances = [i for i in misp.get_instances()]
while instances:
for i, ist in enumerate(instances):
status = misp.test_instance(ist["url"],
ist["apikey"],
ist["verifycert"])
if status:
for ioc in misp.get_iocs(ist["id"]):
iocs.add(ioc["type"], ioc["tag"], ioc["tlp"],
ioc["value"], "misp-{}".format(ist["id"]))
misp.update_sync(ist["id"])
instances.pop(i)
if instances: time.sleep(60)
p1 = Process(target=watch_iocs) p1 = Process(target=watch_iocs)
p2 = Process(target=watch_whitelists) p2 = Process(target=watch_whitelists)
p3 = Process(target=watch_misp)
p1.start() p1.start()
p2.start() p2.start()
p3.start()

View File

@ -2,11 +2,11 @@ country_code=GB
interface={IFACE} interface={IFACE}
ssid={SSID} ssid={SSID}
hw_mode=g hw_mode=g
channel=7 channel={CHAN}
auth_algs=1 auth_algs=1
wpa=2 wpa=2
wpa_passphrase={PASS} wpa_passphrase={PASS}
wpa_key_mgmt=WPA-PSK wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP wpa_pairwise=TKIP
rsn_pairwise=CCMP rsn_pairwise=CCMP
disassoc_low_ack=0 disassoc_low_ack=0

View File

@ -3,7 +3,7 @@
import subprocess as sp import subprocess as sp
from flask import Blueprint, jsonify from flask import Blueprint, jsonify
from app.utils import read_config from app.utils import read_config, delete_captures
import re import re
import sys import sys
import os import os
@ -11,6 +11,17 @@ import os
misc_bp = Blueprint("misc", __name__) misc_bp = Blueprint("misc", __name__)
@misc_bp.route("/delete-captures", methods=["GET"])
def api_delete_captures():
"""
Delete the zombies capture folders (if any)
"""
if delete_captures():
return jsonify({"message": "Captures deleted", "status": True})
else:
return jsonify({"message": "Issue while removing captures", "status": False})
@misc_bp.route("/reboot", methods=["GET"]) @misc_bp.route("/reboot", methods=["GET"])
def api_reboot(): def api_reboot():
""" """
@ -61,5 +72,6 @@ def get_config():
"shutdown_option": read_config(("frontend", "shutdown_option")), "shutdown_option": read_config(("frontend", "shutdown_option")),
"reboot_option": read_config(("frontend", "reboot_option")), "reboot_option": read_config(("frontend", "reboot_option")),
"iface_out": read_config(("network", "out")), "iface_out": read_config(("network", "out")),
"user_lang": read_config(("frontend", "user_lang")) "user_lang": read_config(("frontend", "user_lang")),
"choose_net": read_config(("frontend", "choose_net"))
}) })

View File

@ -24,7 +24,7 @@ class Analysis(object):
if self.token is not None: if self.token is not None:
parent = "/".join(sys.path[0].split("/")[:-2]) parent = "/".join(sys.path[0].split("/")[:-2])
sp.Popen( sp.Popen(
[sys.executable, "{}/analysis/analysis.py".format(parent), "/tmp/{}".format(self.token)]) [sys.executable, "{}/analysis/analysis.py".format(parent), "-f", "/tmp/{}".format(self.token)])
return {"status": True, return {"status": True,
"message": "Analysis started", "message": "Analysis started",
"token": self.token} "token": self.token}
@ -41,13 +41,18 @@ class Analysis(object):
:return: dict containing the report or error message. :return: dict containing the report or error message.
""" """
device, alerts = {}, {} device, alerts, pcap = {}, {}, {}
# Getting device configuration. # Getting device configuration.
if os.path.isfile("/tmp/{}/assets/device.json".format(self.token)): if os.path.isfile("/tmp/{}/assets/device.json".format(self.token)):
with open("/tmp/{}/assets/device.json".format(self.token), "r") as f: with open("/tmp/{}/assets/device.json".format(self.token), "r") as f:
device = json.load(f) device = json.load(f)
# Getting pcap infos.
if os.path.isfile("/tmp/{}/assets/capinfos.json".format(self.token)):
with open("/tmp/{}/assets/capinfos.json".format(self.token), "r") as f:
pcap = json.load(f)
# Getting alerts configuration. # Getting alerts configuration.
if os.path.isfile("/tmp/{}/assets/alerts.json".format(self.token)): if os.path.isfile("/tmp/{}/assets/alerts.json".format(self.token)):
with open("/tmp/{}/assets/alerts.json".format(self.token), "r") as f: with open("/tmp/{}/assets/alerts.json".format(self.token), "r") as f:
@ -55,6 +60,7 @@ class Analysis(object):
if device != {} and alerts != {}: if device != {} and alerts != {}:
return {"alerts": alerts, return {"alerts": alerts,
"device": device} "device": device,
"pcap": pcap}
else: else:
return {"message": "No report yet"} return {"message": "No report yet"}

View File

@ -1,327 +1,369 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import subprocess as sp import subprocess as sp
import netifaces as ni import netifaces as ni
import requests as rq import requests as rq
import sys import re
import time import sys
import qrcode import time
import base64 import qrcode
import random import base64
import requests import random
import requests
from wifi import Cell
from os import path, remove from wifi import Cell
from io import BytesIO from os import path, remove
from app.utils import terminate_process, read_config from io import BytesIO
from app.utils import terminate_process, read_config
class Network(object):
class Network(object):
def __init__(self):
self.AP_SSID = False def __init__(self):
self.AP_PASS = False self.AP_SSID = False
self.iface_in = read_config(("network", "in")) self.AP_PASS = False
self.iface_out = read_config(("network", "out")) self.iface_in = read_config(("network", "in"))
self.enable_interface(self.iface_in) self.iface_out = read_config(("network", "out"))
self.enable_interface(self.iface_out) self.enable_interface(self.iface_in)
self.enable_forwarding() self.enable_interface(self.iface_out)
self.reset_dnsmasq_leases() self.enable_forwarding()
self.random_choice_alphabet = "abcdef1234567890" self.reset_dnsmasq_leases()
self.random_choice_alphabet = "abcdef1234567890"
def check_status(self):
""" def check_status(self):
The method check_status check the IP addressing of each interface """
and return their associated IP. The method check_status check the IP addressing of each interface
and return their associated IP.
:return: dict containing each interface status.
""" :return: dict containing each interface status.
"""
ctx = {"interfaces": {
self.iface_in: False, ctx = {"interfaces": {
self.iface_out: False, self.iface_in: False,
"eth0": False}, self.iface_out: False,
"internet": self.check_internet()} "eth0": False},
"internet": self.check_internet()}
for iface in ctx["interfaces"].keys():
try: for iface in ctx["interfaces"].keys():
ip = ni.ifaddresses(iface)[ni.AF_INET][0]["addr"] try:
if not ip.startswith("127") or not ip.startswith("169.254"): ip = ni.ifaddresses(iface)[ni.AF_INET][0]["addr"]
ctx["interfaces"][iface] = ip if not ip.startswith("127") or not ip.startswith("169.254"):
except: ctx["interfaces"][iface] = ip
ctx["interfaces"][iface] = "Interface not connected or present." except:
return ctx ctx["interfaces"][iface] = "Interface not connected or present."
return ctx
def wifi_list_networks(self):
""" def wifi_list_networks(self):
The method wifi_list_networks list the available WiFi networks """
by using wifi python package. The method wifi_list_networks list the available WiFi networks
:return: dict - containing the list of Wi-Fi networks. by using wifi python package.
""" :return: dict - containing the list of Wi-Fi networks.
networks = [] """
try: networks = []
for n in Cell.all(self.iface_out): try:
if n.ssid not in [n["ssid"] for n in networks] and n.ssid and n.encrypted: for n in Cell.all(self.iface_out):
networks.append( if n.ssid not in [n["ssid"] for n in networks] and n.ssid and n.encrypted:
{"ssid": n.ssid, "type": n.encryption_type}) networks.append(
return {"networks": networks} {"ssid": n.ssid, "type": n.encryption_type})
except: return {"networks": networks}
return {"networks": []} except:
return {"networks": []}
@staticmethod
def wifi_setup(ssid, password): @staticmethod
""" def wifi_setup(ssid, password):
Edit the wpa_supplicant file with provided credentials. """
If the ssid already exists, just update the password. Otherwise Edit the wpa_supplicant file with provided credentials.
create a new entry in the file. If the ssid already exists, just update the password. Otherwise
create a new entry in the file.
:return: dict containing the status of the operation
""" :return: dict containing the status of the operation
if len(password) >= 8 and len(ssid): """
found = False if len(password) >= 8 and len(ssid):
networks = [] found = False
header, content = "", "" networks = []
header, content = "", ""
with open("/etc/wpa_supplicant/wpa_supplicant.conf") as f:
content = f.read() with open("/etc/wpa_supplicant/wpa_supplicant.conf") as f:
blocks = content.split("network={") content = f.read()
header = blocks[0] blocks = content.split("network={")
header = blocks[0]
for block in blocks[1:]:
net = {} for block in blocks[1:]:
for line in block.splitlines(): net = {}
if line and line != "}": for line in block.splitlines():
key, val = line.strip().split("=") if line and line != "}":
if key != "disabled": if "priority=10" not in line.strip():
net[key] = val.replace("\"", "") key, val = line.strip().split("=")
networks.append(net) if key != "disabled":
net[key] = val.replace("\"", "")
for net in networks: networks.append(net)
if net["ssid"] == ssid:
net["psk"] = password.replace('"', '\\"') for net in networks:
found = True if net["ssid"] == ssid:
net["psk"] = password.replace('"', '\\"')
if not found: net["priority"] = "10"
networks.append({ found = True
"ssid": ssid,
"psk": password.replace('"', '\\"'), if not found:
"key_mgmt": "WPA-PSK" networks.append({
}) "ssid": ssid,
"psk": password.replace('"', '\\"'),
with open("/etc/wpa_supplicant/wpa_supplicant.conf", "w+") as f: "key_mgmt": "WPA-PSK",
content = header "priority": "10"
for network in networks: })
net = "network={\n"
for k, v in network.items(): with open("/etc/wpa_supplicant/wpa_supplicant.conf", "w+") as f:
if k in ["ssid", "psk"]: content = header
net += " {}=\"{}\"\n".format(k, v) for network in networks:
else: net = "network={\n"
net += " {}={}\n".format(k, v) for k, v in network.items():
net += "}\n\n" if k in ["ssid", "psk"]:
content += net net += " {}=\"{}\"\n".format(k, v)
if f.write(content): else:
return {"status": True, net += " {}={}\n".format(k, v)
"message": "Configuration saved"} net += "}\n\n"
else: content += net
return {"status": False, if f.write(content):
"message": "Error while writing wpa_supplicant configuration file."} return {"status": True,
else: "message": "Configuration saved"}
return {"status": False, else:
"message": "Empty SSID or/and password length less than 8 chars."} return {"status": False,
"message": "Error while writing wpa_supplicant configuration file."}
def wifi_connect(self): else:
""" return {"status": False,
Connect to one of the WiFi networks present in the wpa_supplicant.conf. "message": "Empty SSID or/and password length less than 8 chars."}
:return: dict containing the TinyCheck <-> AP status.
""" def wifi_connect(self):
"""
# Kill wpa_supplicant instances, if any. Connect to one of the WiFi networks present in the wpa_supplicant.conf.
terminate_process("wpa_supplicant") :return: dict containing the TinyCheck <-> AP status.
# Launch a new instance of wpa_supplicant. """
sp.Popen(["wpa_supplicant", "-B", "-i", self.iface_out, "-c",
"/etc/wpa_supplicant/wpa_supplicant.conf"]).wait() # Kill wpa_supplicant instances, if any.
# Check internet status terminate_process("wpa_supplicant")
for _ in range(1, 40): # Launch a new instance of wpa_supplicant.
if self.check_internet(): sp.Popen(["wpa_supplicant", "-B", "-i", self.iface_out, "-c",
return {"status": True, "/etc/wpa_supplicant/wpa_supplicant.conf"]).wait()
"message": "Wifi connected"} # Check internet status
time.sleep(1) for _ in range(1, 40):
if self.check_internet():
return {"status": False, return {"status": True,
"message": "Wifi not connected"} "message": "Wifi connected"}
time.sleep(1)
def start_ap(self):
""" return {"status": False,
The start_ap method generates an Access Point by using HostApd "message": "Wifi not connected"}
and provide to the GUI the associated ssid, password and qrcode.
def start_ap(self):
:return: dict containing the status of the AP """
""" The start_ap method generates an Access Point by using HostApd
and provide to the GUI the associated ssid, password and qrcode.
# Re-ask to enable interface, sometimes it just go away.
if not self.enable_interface(self.iface_out): :return: dict containing the status of the AP
return {"status": False, """
"message": "Interface not present."}
# Re-ask to enable interface, sometimes it just go away.
# Generate the hostapd configuration if not self.enable_interface(self.iface_out):
if read_config(("network", "tokenized_ssids")): return {"status": False,
token = "".join([random.choice(self.random_choice_alphabet) "message": "Interface not present."}
for i in range(4)])
self.AP_SSID = random.choice(read_config( # Generate the hostapd configuration
("network", "ssids"))) + "-" + token if read_config(("network", "tokenized_ssids")):
else: token = "".join([random.choice(self.random_choice_alphabet)
self.AP_SSID = random.choice(read_config(("network", "ssids"))) for i in range(4)])
self.AP_PASS = "".join( self.AP_SSID = random.choice(read_config(
[random.choice(self.random_choice_alphabet) for i in range(8)]) ("network", "ssids"))) + "-" + token
else:
# Launch hostapd self.AP_SSID = random.choice(read_config(("network", "ssids")))
if self.write_hostapd_config(): self.AP_PASS = "".join(
if self.lauch_hostapd() and self.reset_dnsmasq_leases(): [random.choice(self.random_choice_alphabet) for i in range(8)])
return {"status": True,
"message": "AP started", # Launch hostapd
"ssid": self.AP_SSID, if self.write_hostapd_config():
"password": self.AP_PASS, if self.lauch_hostapd() and self.reset_dnsmasq_leases():
"qrcode": self.generate_qr_code()} return {"status": True,
else: "message": "AP started",
return {"status": False, "ssid": self.AP_SSID,
"message": "Error while creating AP."} "password": self.AP_PASS,
else: "qrcode": self.generate_qr_code()}
return {"status": False, else:
"message": "Error while writing hostapd configuration file."} return {"status": False,
"message": "Error while creating AP."}
def generate_qr_code(self): else:
""" return {"status": False,
The method generate_qr_code returns a QRCode based on "message": "Error while writing hostapd configuration file."}
the SSID and the password.
def generate_qr_code(self):
:return: - string containing the PNG of the QRCode. """
""" The method generate_qr_code returns a QRCode based on
qrc = qrcode.make("WIFI:S:{};T:WPA;P:{};;".format( the SSID and the password.
self.AP_SSID, self.AP_PASS))
buffered = BytesIO() :return: - string containing the PNG of the QRCode.
qrc.save(buffered, format="PNG") """
return "data:image/png;base64,{}".format(base64.b64encode(buffered.getvalue()).decode("utf8")) qrc = qrcode.make("WIFI:S:{};T:WPA;P:{};;".format(
self.AP_SSID, self.AP_PASS))
def write_hostapd_config(self): buffered = BytesIO()
""" qrc.save(buffered, format="PNG")
The method write_hostapd_config write the hostapd configuration return "data:image/png;base64,{}".format(base64.b64encode(buffered.getvalue()).decode("utf8"))
under a temporary location defined in the config file.
def write_hostapd_config(self):
:return: bool - if hostapd configuration file created """
""" The method write_hostapd_config write the hostapd configuration
try: under a temporary location defined in the config file.
with open("{}/app/assets/hostapd.conf".format(sys.path[0]), "r") as f:
conf = f.read() :return: bool - if hostapd configuration file created
conf = conf.replace("{IFACE}", self.iface_in) """
conf = conf.replace("{SSID}", self.AP_SSID) try:
conf = conf.replace("{PASS}", self.AP_PASS) chan = self.set_ap_channel()
with open("/tmp/hostapd.conf", "w") as c: with open("{}/app/assets/hostapd.conf".format(sys.path[0]), "r") as f:
c.write(conf) conf = f.read()
return True conf = conf.replace("{IFACE}", self.iface_in)
except: conf = conf.replace("{SSID}", self.AP_SSID)
return False conf = conf.replace("{PASS}", self.AP_PASS)
conf = conf.replace("{CHAN}", chan)
def lauch_hostapd(self): with open("/tmp/hostapd.conf", "w") as c:
""" c.write(conf)
The method lauch_hostapd kill old instance of hostapd and launch a return True
new one as a background process. except:
return False
:return: bool - if hostapd sucessfully launched.
""" def lauch_hostapd(self):
"""
# Kill potential zombies of hostapd The method lauch_hostapd kill old instance of hostapd and launch a
terminate_process("hostapd") new one as a background process.
sp.Popen(["ifconfig", self.iface_in, "up"]).wait() :return: bool - if hostapd sucessfully launched.
sp.Popen( """
"/usr/sbin/hostapd /tmp/hostapd.conf > /tmp/hostapd.log", shell=True)
# Kill potential zombies of hostapd
while True: terminate_process("hostapd")
if path.isfile("/tmp/hostapd.log"):
with open("/tmp/hostapd.log", "r") as f: sp.Popen(["ip","link","set", self.iface_in, "up"]).wait()
log = f.read() sp.Popen(
err = ["Could not configure driver mode", "/usr/sbin/hostapd /tmp/hostapd.conf > /tmp/hostapd.log", shell=True)
"driver initialization failed"]
if not any(e in log for e in err): while True:
if "AP-ENABLED" in log: if path.isfile("/tmp/hostapd.log"):
return True with open("/tmp/hostapd.log", "r") as f:
else: log = f.read()
return False err = ["Could not configure driver mode",
time.sleep(1) "driver initialization failed"]
if not any(e in log for e in err):
def stop_hostapd(self): if "AP-ENABLED" in log:
""" return True
Stop hostapd instance. else:
return False
:return: dict - a little message for debug. time.sleep(1)
"""
if terminate_process("hostapd"): def stop_hostapd(self):
return {"status": True, """
"message": "AP stopped"} Stop hostapd instance.
else:
return {"status": False, :return: dict - a little message for debug.
"message": "No AP running"} """
if terminate_process("hostapd"):
def reset_dnsmasq_leases(self): return {"status": True,
""" "message": "AP stopped"}
This method reset the DNSMasq leases and logs to get the new else:
connected device name & new DNS entries. return {"status": False,
"message": "No AP running"}
:return: bool if everything goes well
""" def reset_dnsmasq_leases(self):
try: """
sp.Popen("service dnsmasq stop", shell=True).wait() This method reset the DNSMasq leases and logs to get the new
sp.Popen("cp /dev/null /var/lib/misc/dnsmasq.leases", connected device name & new DNS entries.
shell=True).wait()
sp.Popen("cp /dev/null /var/log/messages.log", shell=True).wait() :return: bool if everything goes well
sp.Popen("service dnsmasq start", shell=True).wait() """
return True try:
except: sp.Popen("service dnsmasq stop", shell=True).wait()
return False sp.Popen("cp /dev/null /var/lib/misc/dnsmasq.leases",
shell=True).wait()
def enable_forwarding(self): sp.Popen("cp /dev/null /var/log/messages.log", shell=True).wait()
""" sp.Popen("service dnsmasq start", shell=True).wait()
This enable forwarding to get internet working on the connected device. return True
Method tiggered during the Network class intialization. except:
return False
:return: bool if everything goes well
""" def enable_forwarding(self):
try: """
sp.Popen("echo 1 > /proc/sys/net/ipv4/ip_forward", This enable forwarding to get internet working on the connected device.
shell=True).wait() Method tiggered during the Network class intialization.
sp.Popen(["iptables", "-A", "POSTROUTING", "-t", "nat", "-o",
self.iface_out, "-j", "MASQUERADE"]).wait() :return: bool if everything goes well
return True """
except: try:
return False sp.Popen("echo 1 > /proc/sys/net/ipv4/ip_forward",
shell=True).wait()
def enable_interface(self, iface):
""" # Enable forwarding.
This enable interfaces, with a simple check.
:return: bool if everything goes well sp.Popen("nft add table nat",shell=True).wait()
""" sp.Popen("nft 'add chain nat prerouting { type nat hook prerouting priority 100; }'",shell=True).wait()
sh = sp.Popen(["ifconfig", iface], sp.Popen("nft 'add chain nat postrouting { type nat hook postrouting priority 100; }'",shell=True).wait()
stdout=sp.PIPE, stderr=sp.PIPE) sp.Popen("nft add table ip filter",shell=True).wait()
sh = sh.communicate() sp.Popen("nft 'add chain ip filter INPUT { type filter hook input priority 0; }'",shell=True).wait()
if b"<UP," in sh[0]:
return True # The interface is up.
elif sh[1]: sp.Popen(["nft","add","rule","ip","nat","postrouting","oifname",
return False # The interface doesn't exists (most of the cases). self.iface_out,"counter","masquerade"]).wait()
else:
sp.Popen(["ifconfig", iface, "up"]).wait() # Prevent the device to reach the 80 and 443 of TinyCheck.
return True sp.Popen(["nft","add","rule","ip","filter","INPUT","iifname",self.iface_in,"ip",
"protocol","tcp","ip","daddr","192.168.100.1","tcp","dport","{ 80,443}","counter","drop"]).wait()
def check_internet(self):
"""
Check the internet link just with a small http request return True
to an URL present in the configuration except:
return False
:return: bool - if the request succeed or not.
""" def enable_interface(self, iface):
try: """
url = read_config(("network", "internet_check")) This enable interfaces, with a simple check.
requests.get(url, timeout=10) :return: bool if everything goes well
return True """
except: sh = sp.Popen(["ip" ,"a","s", iface],
return False stdout=sp.PIPE, stderr=sp.PIPE)
sh = sh.communicate()
if b",UP" in sh[0]:
return True # The interface is up.
elif sh[1]:
return False # The interface doesn't exists (most of the cases).
else:
sp.Popen(["ip","link","set", iface, "up"]).wait()
return True
def check_internet(self):
"""
Check the internet link just with a small http request
to an URL present in the configuration
:return: bool - if the request succeed or not.
"""
try:
url = read_config(("network", "internet_check"))
requests.get(url, timeout=10)
return True
except:
return False
def set_ap_channel(self):
"""
Deduce the channel to have for the AP in order to prevent
kind of jamming between the two wifi interfaces.
"""
try:
if self.iface_out[0] == "w":
# Get the channel of the connected interface
sh = sp.Popen(["iw", self.iface_out, "info"],
stdout=sp.PIPE, stderr=sp.PIPE).communicate()
res = re.search("channel ([0-9]{1,2})", sh[0].decode('utf8'))
chn = res.group(1)
# Return a good candidate.
return "11" if int(chn) < 7 else "1"
else:
return "1"
except:
return "1"

View File

@ -7,6 +7,8 @@ import yaml
import sys import sys
import os import os
from functools import reduce from functools import reduce
import shutil
import re
def terminate_process(process): def terminate_process(process):
@ -33,3 +35,16 @@ def read_config(path):
config = yaml.load(open(os.path.join(dir, "config.yaml"), "r"), config = yaml.load(open(os.path.join(dir, "config.yaml"), "r"),
Loader=yaml.SafeLoader) Loader=yaml.SafeLoader)
return reduce(dict.get, path, config) return reduce(dict.get, path, config)
def delete_captures():
"""
Delete potential zombies capture directories
"""
try:
for d in os.listdir("/tmp/"):
if re.match("[A-F0-9]{8}", d):
shutil.rmtree(os.path.join("/tmp/", d))
return True
except:
return False

View File

@ -46,7 +46,12 @@ app.register_blueprint(misc_bp, url_prefix='/api/misc')
app.register_blueprint(update_bp, url_prefix='/api/update') app.register_blueprint(update_bp, url_prefix='/api/update')
if __name__ == '__main__': if __name__ == '__main__':
port = ""
try:
port = int(read_config(("frontend", "http_port")))
except:
port = 80
if read_config(("frontend", "remote_access")): if read_config(("frontend", "remote_access")):
app.run(host="0.0.0.0", port=80) app.run(host="0.0.0.0", port=port)
else: else:
app.run(port=80) app.run(port=port)

View File

@ -37,16 +37,20 @@ elif [ $PWD = "/tmp/tinycheck" ]; then
python3 -m pip install -r assets/requirements.txt python3 -m pip install -r assets/requirements.txt
echo "[+] Building new interfaces..." echo "[+] Building new interfaces..."
cd /usr/share/tinycheck/app/frontend/ && npm install && npm run build cd /usr/share/tinycheck/app/frontend/ && npm install && npm audit fix && npm run build
cd /usr/share/tinycheck/app/backend/ && npm install && npm run build cd /usr/share/tinycheck/app/backend/ && npm install && npm audit fix && npm run build
echo "[+] Updating the database scheme..."
cd /usr/share/tinycheck/
sqlite3 tinycheck.sqlite3 < /tmp/tinycheck/assets/scheme.sql 2>/dev/null
echo "[+] Updating current configuration with new values." echo "[+] Updating current configuration with new values."
if ! grep -q reboot_option /usr/share/tinycheck/config.yaml; then if ! grep -q reboot_option /usr/share/tinycheck/config.yaml; then
sed -i 's/frontend:/frontend:\n reboot_option: true/g' /usr/share/tinycheck/config.yaml sed -i 's/frontend:/frontend:\n reboot_option: true/g' /usr/share/tinycheck/config.yaml
fi fi
if ! grep -q user_lang /usr/share/tinycheck/config.yaml; then if ! grep -q choose_net /usr/share/tinycheck/config.yaml; then
sed -i 's/frontend:/frontend:\n user_lang: en/g' /usr/share/tinycheck/config.yaml sed -i 's/frontend:/frontend:\n choose_net: false/g' /usr/share/tinycheck/config.yaml
fi fi
if ! grep -q shutdown_option /usr/share/tinycheck/config.yaml; then if ! grep -q shutdown_option /usr/share/tinycheck/config.yaml; then
@ -65,6 +69,10 @@ elif [ $PWD = "/tmp/tinycheck" ]; then
sed -i 's/frontend:/frontend:\n update: true/g' /usr/share/tinycheck/config.yaml sed -i 's/frontend:/frontend:\n update: true/g' /usr/share/tinycheck/config.yaml
fi fi
if ! grep -q user_lang /usr/share/tinycheck/config.yaml; then
sed -i 's/frontend:/frontend:\n user_lang: en/g' /usr/share/tinycheck/config.yaml
fi
if ! grep -q "CN=R3,O=Let's Encrypt,C=US" /usr/share/tinycheck/config.yaml; then if ! grep -q "CN=R3,O=Let's Encrypt,C=US" /usr/share/tinycheck/config.yaml; then
sed -i "s/free_issuers:/free_issuers:\n - CN=R3,O=Let's Encrypt,C=US/g" /usr/share/tinycheck/config.yaml sed -i "s/free_issuers:/free_issuers:\n - CN=R3,O=Let's Encrypt,C=US/g" /usr/share/tinycheck/config.yaml
fi fi
@ -78,4 +86,4 @@ elif [ $PWD = "/tmp/tinycheck" ]; then
cd /tmp/tinycheck && git tag | tail -n 1 | xargs echo -n > /usr/share/tinycheck/VERSION cd /tmp/tinycheck && git tag | tail -n 1 | xargs echo -n > /usr/share/tinycheck/VERSION
echo "[+] TinyCheck updated!" echo "[+] TinyCheck updated!"
fi fi