13 Commits

Author SHA1 Message Date
0a636e4a76 Add timeout to requests calls 2024-05-30 21:28:43 +00:00
3ff9520114 snorkell_ai/config_54b37
main
2024-04-14 17:12:47 +00:00
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
052ce4cd9c Merge pull request #2 from 2lambda123/imgbot
[ImgBot] Optimize images
2024-04-14 11:59:41 -05:00
1eecd892f7 Merge pull request #9 from 2lambda123/ablesov/add_diagnostics_script
Added diagnostics script
2024-04-14 11:59:11 -05:00
f9be1daccb Merge pull request #8 from 2lambda123/ablesov/fix_requirements
Update requirements.txt
2024-04-14 11:52:34 -05:00
6d0560c311 Merge pull request #6 from 2lambda123/ablesov/pwd_compare_fix
Update install.sh
2024-04-14 11:28:44 -05:00
dfdbff5100 Merge pull request #3 from 2lambda123/ablesov/fix_field_name
Fixed field mapping @ zeekengine.py
2024-04-14 11:16:37 -05:00
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
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
c3f09469b9 Added diagnostics script 2023-06-26 14:01:58 +03:00
69512ba605 Update install.sh
Fixed password comparison
2023-06-26 14:00:12 +03:00
bd4ab27c21 Update requirements.txt
Use only fixed versions for dependencies
2023-06-26 13:57:42 +03:00
4 changed files with 252 additions and 233 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

@ -2,9 +2,9 @@ pymisp==2.4.165.1
sqlalchemy==1.4.48 sqlalchemy==1.4.48
ipwhois==1.2.0 ipwhois==1.2.0
netaddr==0.8.0 netaddr==0.8.0
flask==1.1.2 flask==2.2.5
flask_httpauth==4.8.0 flask_httpauth==4.8.0
pyjwt==1.7.1 pyjwt==2.4.0
psutil==5.8.0 psutil==5.8.0
pydig==0.4.0 pydig==0.4.0
pyudev==0.24.0 pyudev==0.24.0

View File

@ -1,149 +1,149 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
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 from app.classes.misp import MISP
import requests import requests
import json import json
import urllib3 import urllib3
import time import time
from multiprocessing import Process from multiprocessing import Process
""" """
This file is parsing the watchers present This file is parsing the watchers present
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.
""" """
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 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 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
urls = read_config(("watchers", "iocs")) urls = read_config(("watchers", "iocs"))
watchers = [{"url": url, "status": False} for url in urls] watchers = [{"url": url, "status": False} for url in urls]
while True: while True:
for w in watchers: for w in watchers:
if w["status"] == False: if w["status"] == False:
iocs = IOCs() iocs = IOCs()
iocs_list = [] iocs_list = []
to_delete = [] to_delete = []
try: try:
res = requests.get(w["url"], verify=False) res = requests.get(w["url"], verify=False, timeout=60)
if res.status_code == 200: if res.status_code == 200:
content = json.loads(res.content) content = json.loads(res.content)
iocs_list = content["iocs"] if "iocs" in content else [] iocs_list = content["iocs"] if "iocs" in content else []
to_delete = content["to_delete"] if "to_delete" in content else [] to_delete = content["to_delete"] if "to_delete" in content else []
else: else:
w["status"] = False w["status"] = False
except: except:
w["status"] = False w["status"] = False
for ioc in iocs_list: for ioc in iocs_list:
try: try:
iocs.add(ioc["type"], ioc["tag"], iocs.add(ioc["type"], ioc["tag"],
ioc["tlp"], ioc["value"], "watcher") ioc["tlp"], ioc["value"], "watcher")
w["status"] = True w["status"] = True
except: except:
continue continue
for ioc in to_delete: for ioc in to_delete:
try: try:
iocs.delete_by_value(ioc["value"]) iocs.delete_by_value(ioc["value"])
w["status"] = True w["status"] = True
except: except:
continue continue
# If at least one URL haven't be parsed, let's retry in 1min. # If at least one URL haven't be parsed, let's retry in 1min.
if False in [w["status"] for w in watchers]: if False in [w["status"] for w in watchers]:
time.sleep(60) time.sleep(60)
else: else:
break break
def watch_whitelists(): def watch_whitelists():
""" """
Retrieve whitelist elements from the remote URLs Retrieve whitelist elements from the remote URLs
defined in config/watchers. For each (new ?) element, defined in config/watchers. For each (new ?) element,
add it to the DB. add it to the DB.
""" """
urls = read_config(("watchers", "whitelists")) urls = read_config(("watchers", "whitelists"))
watchers = [{"url": url, "status": False} for url in urls] watchers = [{"url": url, "status": False} for url in urls]
while True: while True:
for w in watchers: for w in watchers:
if w["status"] == False: if w["status"] == False:
whitelist = WhiteList() whitelist = WhiteList()
elements = [] elements = []
to_delete = [] to_delete = []
try: try:
res = requests.get(w["url"], verify=False) res = requests.get(w["url"], verify=False, timeout=60)
if res.status_code == 200: if res.status_code == 200:
content = json.loads(res.content) content = json.loads(res.content)
elements = content["elements"] if "elements" in content else [] elements = content["elements"] if "elements" in content else []
to_delete = content["to_delete"] if "to_delete" in content else [] to_delete = content["to_delete"] if "to_delete" in content else []
else: else:
w["status"] = False w["status"] = False
except: except:
w["status"] = False w["status"] = False
for elem in elements: for elem in elements:
try: try:
whitelist.add(elem["type"], elem["element"], "watcher") whitelist.add(elem["type"], elem["element"], "watcher")
w["status"] = True w["status"] = True
except: except:
continue continue
for elem in to_delete: for elem in to_delete:
try: try:
whitelist.delete_by_value(elem["element"]) whitelist.delete_by_value(elem["element"])
w["status"] = True w["status"] = True
except: except:
continue continue
if False in [w["status"] for w in watchers]: if False in [w["status"] for w in watchers]:
time.sleep(60) time.sleep(60)
else: else:
break break
def watch_misp(): def watch_misp():
""" """
Retrieve IOCs from misp instances. Each new element is Retrieve IOCs from misp instances. Each new element is
tested and then added to the database. tested and then added to the database.
""" """
iocs, misp = IOCs(), MISP() iocs, misp = IOCs(), MISP()
instances = [i for i in misp.get_instances()] instances = [i for i in misp.get_instances()]
while instances: while instances:
for i, ist in enumerate(instances): for i, ist in enumerate(instances):
status = misp.test_instance(ist["url"], status = misp.test_instance(ist["url"],
ist["apikey"], ist["apikey"],
ist["verifycert"]) ist["verifycert"])
if status: if status:
for ioc in misp.get_iocs(ist["id"]): for ioc in misp.get_iocs(ist["id"]):
iocs.add(ioc["type"], ioc["tag"], ioc["tlp"], iocs.add(ioc["type"], ioc["tag"], ioc["tlp"],
ioc["value"], "misp-{}".format(ist["id"])) ioc["value"], "misp-{}".format(ist["id"]))
misp.update_sync(ist["id"]) misp.update_sync(ist["id"])
instances.pop(i) instances.pop(i)
if instances: time.sleep(60) 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) p3 = Process(target=watch_misp)
p1.start() p1.start()
p2.start() p2.start()
p3.start() p3.start()

View File

@ -1,82 +1,82 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from app.utils import read_config from app.utils import read_config
import subprocess as sp import subprocess as sp
import requests import requests
import json import json
import os import os
import re import re
class Update(object): class Update(object):
def __init__(self): def __init__(self):
self.project_url = "https://api.github.com/repos/KasperskyLab/TinyCheck/tags" self.project_url = "https://api.github.com/repos/KasperskyLab/TinyCheck/tags"
self.app_path = "/usr/share/tinycheck" self.app_path = "/usr/share/tinycheck"
return None return None
def check_version(self): def check_version(self):
""" """
Check if a new version of TinyCheck is available Check if a new version of TinyCheck is available
by quering the Github api and comparing the last by quering the Github api and comparing the last
tag inside the VERSION file. tag inside the VERSION file.
:return: dict containing the available versions. :return: dict containing the available versions.
""" """
if read_config(("frontend", "update")): if read_config(("frontend", "update")):
try: try:
res = requests.get(self.project_url) res = requests.get(self.project_url, timeout=60)
res = json.loads(res.content.decode("utf8")) res = json.loads(res.content.decode("utf8"))
with open(os.path.join(self.app_path, "VERSION")) as f: with open(os.path.join(self.app_path, "VERSION")) as f:
cv = f.read() cv = f.read()
if cv != res[0]["name"]: if cv != res[0]["name"]:
return {"status": True, return {"status": True,
"message": "A new version is available", "message": "A new version is available",
"current_version": cv, "current_version": cv,
"next_version": res[0]["name"]} "next_version": res[0]["name"]}
else: else:
return {"status": True, return {"status": True,
"message": "This is the latest version", "message": "This is the latest version",
"current_version": cv} "current_version": cv}
except: except:
return {"status": False, return {"status": False,
"message": "Something went wrong (no API access nor version file)"} "message": "Something went wrong (no API access nor version file)"}
else: else:
return {"status": False, return {"status": False,
"message": "You don't have rights to do this operation."} "message": "You don't have rights to do this operation."}
def get_current_version(self): def get_current_version(self):
""" """
Get the current version of the TinyCheck instance Get the current version of the TinyCheck instance
:return: dict containing the current version or error. :return: dict containing the current version or error.
""" """
if read_config(("frontend", "update")): if read_config(("frontend", "update")):
try: try:
with open(os.path.join(self.app_path, "VERSION")) as f: with open(os.path.join(self.app_path, "VERSION")) as f:
return {"status": True, return {"status": True,
"current_version": f.read()} "current_version": f.read()}
except: except:
return {"status": False, return {"status": False,
"message": "Something went wrong - no version file ?"} "message": "Something went wrong - no version file ?"}
else: else:
return {"status": False, return {"status": False,
"message": "You don't have rights to do this operation."} "message": "You don't have rights to do this operation."}
def update_instance(self): def update_instance(self):
""" """
Update the instance by executing the update script. Update the instance by executing the update script.
:return: dict containing the update status. :return: dict containing the update status.
""" """
if read_config(("frontend", "update")): if read_config(("frontend", "update")):
try: try:
os.chdir(self.app_path) os.chdir(self.app_path)
sp.Popen(["bash", os.path.join(self.app_path, "update.sh")]) sp.Popen(["bash", os.path.join(self.app_path, "update.sh")])
return {"status": True, return {"status": True,
"message": "Update successfully launched"} "message": "Update successfully launched"}
except: except:
return {"status": False, return {"status": False,
"message": "Issue during the update"} "message": "Issue during the update"}
else: else:
return {"status": False, return {"status": False,
"message": "You don't have rights to do this operation."} "message": "You don't have rights to do this operation."}