diff --git a/bin/background_build_captures.py b/bin/background_build_captures.py index 66d0103c..95637f26 100755 --- a/bin/background_build_captures.py +++ b/bin/background_build_captures.py @@ -77,7 +77,7 @@ def _build_missing_pickles(self) -> bool: return False if ((path / 'tree.pickle.gz').exists() or (path / 'tree.pickle').exists()): # We already have a pickle file - self.logger.debug(f'{path} has a pickle.') + # self.logger.debug(f'{path} has a pickle.') if (path / 'auto_report').exists(): # the pickle was built somewhere else, trigger report. self.__auto_report(path) diff --git a/poetry.lock b/poetry.lock index 3b1eb814..e632508d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. [[package]] name = "aiobotocore" @@ -3346,14 +3346,14 @@ docs = ["Sphinx (>=8.1.3) ; python_version >= \"3.10\""] [[package]] name = "pylookyloo" -version = "1.27.1" +version = "1.28.0" description = "Python CLI and module for Lookyloo" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "pylookyloo-1.27.1-py3-none-any.whl", hash = "sha256:5348ff75d34b292a8b0183414620c6aae6d8fa5fcb15dc362f15b09e25165d42"}, - {file = "pylookyloo-1.27.1.tar.gz", hash = "sha256:37303ee4c02ce82f1011d6a93ee1944a2dde06e670612de00d107b6ce382682f"}, + {file = "pylookyloo-1.28.0-py3-none-any.whl", hash = "sha256:f89ca5c27517762b1b0ff2751a89ea6d033bc4d8f4c1a7d7a096117d3572e928"}, + {file = "pylookyloo-1.28.0.tar.gz", hash = "sha256:99edb8793316e62cd9050f8b6fc700ccd0643fc26272c2a78df7255ef4c0ac7b"}, ] [package.dependencies] @@ -4296,14 +4296,14 @@ files = [ [[package]] name = "types-psutil" -version = "6.1.0.20241221" +version = "7.0.0.20250218" description = "Typing stubs for psutil" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "types_psutil-6.1.0.20241221-py3-none-any.whl", hash = "sha256:8498dbe13285a9ba7d4b2fa934c569cc380efc74e3dacdb34ae16d2cdf389ec3"}, - {file = "types_psutil-6.1.0.20241221.tar.gz", hash = "sha256:600f5a36bd5e0eb8887f0e3f3ff2cf154d90690ad8123c8a707bba4ab94d3185"}, + {file = "types_psutil-7.0.0.20250218-py3-none-any.whl", hash = "sha256:1447a30c282aafefcf8941ece854e1100eee7b0296a9d9be9977292f0269b121"}, + {file = "types_psutil-7.0.0.20250218.tar.gz", hash = "sha256:1e642cdafe837b240295b23b1cbd4691d80b08a07d29932143cbbae30eb0db9c"}, ] [[package]] @@ -4874,4 +4874,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9.2,<3.14" -content-hash = "d8c163aa215fd8a37e478d9fad9c50a4f718a2e2446e870c4365bd338208c2b3" +content-hash = "1eedde488cb9fd0794f98ccda3a80d5a9e337bc2a7096906636798759844c0e4" diff --git a/pyproject.toml b/pyproject.toml index 0f1555fe..c033a7ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ defang = "^0.5.3" vt-py = "^0.19.0" pyeupi = "^1.3.0" pysanejs = "^2.0.4" -pylookyloo = "^1.27.1" +pylookyloo = "^1.28.0" dnspython = "^2.7.0" pytaxonomies = "^2.0" pymisp = {version = "^2.5.4", extras = ["url", "fileobjects"]} @@ -105,7 +105,7 @@ types-python-dateutil = "^2.9.0.20241206" types-beautifulsoup4 = "^4.12.0.20250204" types-Pillow = "^10.2.0.20240822" types-pytz = "^2025.1.0.20250204" -types-psutil = "^6.1.0.20241221" +types-psutil = "^7.0.0.20250218" [build-system] requires = ["poetry-core>=2.0"] diff --git a/website/web/__init__.py b/website/web/__init__.py index 8aaf354d..8b785d34 100644 --- a/website/web/__init__.py +++ b/website/web/__init__.py @@ -37,6 +37,7 @@ from flask_talisman import Talisman # type: ignore[import-untyped] from lacuscore import CaptureStatus, CaptureSettingsError from markupsafe import Markup +from pylookyloo import PyLookylooError, Lookyloo as PyLookyloo from puremagic import from_string, PureError from pymisp import MISPEvent, MISPServerError # type: ignore[attr-defined] from werkzeug.security import check_password_hash @@ -891,6 +892,24 @@ def web_misp_lookup_view(tree_uuid: str) -> str | WerkzeugResponse | Response: misps_occurrences=misps_occurrences) +@app.route('/tree//lookyloo_push', methods=['POST']) +def web_lookyloo_push_view(tree_uuid: str) -> str | WerkzeugResponse | Response: + if remote_lookyloo_url := request.form.get('remote_lookyloo_url'): + to_push = lookyloo.get_capture(tree_uuid) + pylookyloo = PyLookyloo(remote_lookyloo_url) + try: + uuid = pylookyloo.upload_capture(full_capture=to_push, quiet=True) + remote_lookyloo_url = f'{uuid}' + flash(Markup(f'Successfully pushed the capture: {remote_lookyloo_url}.'), 'success') + except PyLookylooError as e: + flash(f'Error while pushing capture: {e}', 'error') + except Exception as e: + flash(f'Unable to push capture: {e}', 'error') + else: + flash('Remote Lookyloo URL missing.', 'error') + return redirect(url_for('tree', tree_uuid=tree_uuid)) + + @app.route('/tree//misp_push', methods=['GET', 'POST']) def web_misp_push_view(tree_uuid: str) -> str | WerkzeugResponse | Response: if not lookyloo.misps.available: @@ -986,7 +1005,8 @@ def web_misp_push_view(tree_uuid: str) -> str | WerkzeugResponse | Response: flash(f'Unable to create event(s): {new_events}', 'error') else: for e in new_events: - flash(f'MISP event {e.id} created on {misp.client.root_url}', 'success') + remote_misp_url = f'{e.id}' + flash(Markup(f'MISP event {remote_misp_url} created on {misp.client.root_url}'), 'success') return redirect(url_for('tree', tree_uuid=tree_uuid)) diff --git a/website/web/genericapi.py b/website/web/genericapi.py index 7851b96f..836bcd9f 100644 --- a/website/web/genericapi.py +++ b/website/web/genericapi.py @@ -527,7 +527,9 @@ def post(self) -> dict[str, str | dict[str, list[str]]] | tuple[dict[str, str], return {'error': ', '.join(messages['errors'])}, 400 return {'uuid': uuid, 'messages': messages} else: - # Treat it as a direct export from Lacus + # Treat it as a direct export from Lacus, requires at a bare minimum a HAR + if 'har' not in parameters or not parameters.get('har'): + return {'error': 'Missing HAR file'}, 400 try: uuid = str(uuid4()) # The following parameters are base64 encoded and need to be decoded first diff --git a/website/web/templates/capture.html b/website/web/templates/capture.html index a42641eb..58bbbc00 100644 --- a/website/web/templates/capture.html +++ b/website/web/templates/capture.html @@ -359,7 +359,7 @@
- +
@@ -941,6 +943,30 @@
+ + +