diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml deleted file mode 100644 index 63e1a564..00000000 --- a/.github/workflows/python-package.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Python package - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] - - steps: - - name: Install packages - run: | - sudo apt-get install libpoppler-cpp-dev libzbar0 tesseract-ocr - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - cache: 'pip' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python -m pip install flake8 pytest - # pyfaul must be installed manually (?) - pip install -r REQUIREMENTS pyfaup - pip install . - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Run server in background - run: | - misp-modules -l 127.0.0.1 -s 2>error.log & - sleep 3 - - name: Check if server is running - run: | - curl -sS localhost:6666/healthcheck - - name: Test with pytest - run: | - pytest tests - - name: Show error log - if: always() - run: | - cat error.log diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml new file mode 100644 index 00000000..b0a3fcc2 --- /dev/null +++ b/.github/workflows/release-package.yml @@ -0,0 +1,138 @@ +name: Release Python package and docs pages + +on: + + push: + tags: + - 'v*.*.*' + +jobs: + + release: + runs-on: ubuntu-latest + steps: + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get previous tag + id: previousTag + run: | + name=$(git --no-pager tag --sort=creatordate --merged ${{ github.ref_name }} | tail -2 | head -1) + echo "previousTag: $name" + echo "previousTag=$name" >> $GITHUB_ENV + + - name: Update changelog + id: changelog + uses: requarks/changelog-action@v1 + with: + token: ${{ github.token }} + fromTag: ${{ github.ref_name }} + toTag: ${{ env.previousTag }} + writeToFile: false + + - name: Create release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + draft: false + makeLatest: true + name: ${{ github.ref_name }} + body: ${{ steps.changelog.outputs.changes }} + token: ${{ secrets.GITHUB_TOKEN }} + + docs: + runs-on: ubuntu-latest + steps: + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install packages + run: sudo apt-get install libpoppler-cpp-dev libzbar0 tesseract-ocr yara + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: 3.12 + + - name: Install poetry + run: python -m pip install poetry + + - name: Build docs + run: make generate_docs + + - name: Setup pages + uses: actions/configure-pages@v5 + + - name: Upload documentation artifact + uses: actions/upload-pages-artifact@v3 + with: + path: site/ + + deploy-gh-pages: + runs-on: ubuntu-latest + needs: docs + + permissions: + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 + + build: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install packages + run: sudo apt-get install libpoppler-cpp-dev libzbar0 tesseract-ocr yara + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: 3.12 + + - name: Install poetry + run: python -m pip install poetry + + - name: Install dependencies + run: poetry install --with unstable + + - name: Build package + run: poetry build + + - name: Upload package artifact + uses: actions/upload-artifact@v4 + with: + name: python-package-distributions + path: dist/ + + publish-to-pypi: + runs-on: ubuntu-latest + needs: build + + permissions: + id-token: write + + steps: + - name: Download dist files + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + skip-existing: true diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml new file mode 100644 index 00000000..7c5b4dfe --- /dev/null +++ b/.github/workflows/test-package.yml @@ -0,0 +1,114 @@ +name: Test Python package + +on: + + push: + branches: [ main ] + + pull_request: + branches: [ main ] + +jobs: + + docs: + runs-on: ubuntu-latest + steps: + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install packages + run: sudo apt-get install libpoppler-cpp-dev libzbar0 tesseract-ocr yara + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: 3.12 + + - name: Install poetry + run: python -m pip install poetry + + - name: Build docs + run: make generate_docs + + test: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + + steps: + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install packages + run: sudo apt-get install libpoppler-cpp-dev libzbar0 tesseract-ocr yara + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install poetry + run: python -m pip install poetry + + - name: Install dependencies + run: poetry install --with test,unstable + + - name: Build package + run: poetry build + + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + poetry run flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + + - name: Run server in background + run: poetry run misp-modules -l 127.0.0.1 -s 2>error.log & + + - name: Sleep for 10 seconds + run: sleep 10s + shell: bash + + - name: Check if server is running + run: curl -sS localhost:6666/healthcheck + + - name: Test package + run: poetry run pytest + + - name: Show error log + if: always() + run: cat error.log + + - name: Upload package artifcat + if: ${{ matrix.python-version == '3.12' }} + uses: actions/upload-artifact@v4 + with: + name: python-package-distributions + path: dist/ + + publish-to-test-pypi: + runs-on: ubuntu-latest + needs: test + + permissions: + id-token: write + + steps: + - name: Download dist files + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + + - name: Publish to Test PyPI + if: ${{ github.event_name == 'push' }} + uses: pypa/gh-action-pypi-publish@release/v1 + with: + skip-existing: true + repository-url: https://test.pypi.org/legacy/ diff --git a/.gitignore b/.gitignore index b602dfd6..bc998d04 100644 --- a/.gitignore +++ b/.gitignore @@ -7,18 +7,20 @@ dist/ misp_modules.egg-info/ # For MKDOCS -docs/expansion* -docs/import_mod* -docs/export_mod* -site* +docs +docs/* +site +site/* #pycharm env .idea/* #venv venv* +.venv/ #vscode .vscode* *.sqlite website/conf/config.cfg +wheels diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 93328062..00000000 --- a/.travis.yml +++ /dev/null @@ -1,56 +0,0 @@ -language: python - -services: - - redis-server - -cache: pip - -python: - - "3.6" - - "3.6-dev" - - "3.7-dev" - - "3.8-dev" - -install: - - sudo apt-get install libzbar0 libzbar-dev libpoppler-cpp-dev tesseract-ocr libfuzzy-dev libcaca-dev liblua5.3-dev - - pip install pipenv - - pip install -r REQUIREMENTS - # - pipenv install --dev - # install gtcaca - - git clone git://github.com/stricaud/gtcaca.git - - mkdir -p gtcaca/build - - pushd gtcaca/build - - cmake .. && make - - sudo make install - - popd - # install pyfaup - - git clone https://github.com/stricaud/faup.git - - pushd faup/build - - cmake .. && make - - sudo make install - - popd - - sudo ldconfig - - pushd faup/src/lib/bindings/python - - pip install . - - popd - -script: - - pip install coverage - - coverage run -m --parallel-mode --source=misp_modules misp_modules.__init__ -l 127.0.0.1 & - - pid=$! - - sleep 5 - - nosetests --with-coverage --cover-package=misp_modules - - kill -s KILL $pid - - pushd ~/ - - coverage run -m --parallel-mode --source=misp_modules misp_modules.__init__ -s -l 127.0.0.1 & - - pid=$! - - popd - - sleep 5 - - nosetests --with-coverage --cover-package=misp_modules - - kill -s KILL $pid - - pip install flake8 - - flake8 --ignore=E501,W503,E226,E126 misp_modules - -after_success: - - coverage combine .coverage* - - codecov diff --git a/ChangeLog.md b/ChangeLog.md deleted file mode 100644 index 010d2a7a..00000000 --- a/ChangeLog.md +++ /dev/null @@ -1,4602 +0,0 @@ -# Changelog - - -## v2.4.141 (2021-04-19) - -### Changes - -* [tests] LiveCI set for RBL tests (network connectivity issues in the CI) [Alexandre Dulaunoy] - -* [rbl] Added a timeout parameter to change the resolver timeout & lifetime if needed. [chrisr3d] - -* [rbl] Small changes on the rbl list and the results handling. [chrisr3d] - -* [test] skip some tests if running in the CI (API limitation or specific host issues) [Alexandre Dulaunoy] - -* [tests] historical records in threatcrowd. [Alexandre Dulaunoy] - -* [test] fixing IP addresses. [Alexandre Dulaunoy] - -* [passivetotal] new test IP address. [Alexandre Dulaunoy] - -* [farsight] make PEP happy. [Alexandre Dulaunoy] - -* [requirements] openpyxl added. [Alexandre Dulaunoy] - -* [travis] missing dep. [Alexandre Dulaunoy] - -* [test expansion] IPv4 address of CIRCL updated. [Alexandre Dulaunoy] - -* [coverage] install. [Alexandre Dulaunoy] - -* [pipenv] removed. [Alexandre Dulaunoy] - -* [travis] get rid of pipenv. [Alexandre Dulaunoy] - -* [Pipfile.lock] updated. [Alexandre Dulaunoy] - -* [doc] fix index of mkdocs. [Alexandre Dulaunoy] - -* [documentation] updated. [Alexandre Dulaunoy] - -* [farsight_passivedns] Making first_time and last_time results human readable. [chrisr3d] - - - We get the datetime format instead of the raw - timestamp - -* Bump deps. [Raphaël Vinot] - -* [farsight_passivedns] Making first_time and last_time results human readable. [chrisr3d] - - - We get the datetime format instead of the raw - timestamp - -* [farsight_passivedns] Added input types for more flex queries. [chrisr3d] - - - Standard types still supported as before - - Name or ip lookup, with optional flex queries - - New attribute types added will only send flex - queries to the DNSDB API - -* [doc] fix #460 - rh install. [Alexandre Dulaunoy] - -* [requirements] fix 463. [Alexandre Dulaunoy] - -### Fix - -* [tests] Fixed btc_steroids test assertion. [chrisr3d] - -* [ocr_enrich] Making Pep8 happy. [chrisr3d] - -* [tests] Fixed variable names that have been changed with the latest commit. [chrisr3d] - -* [ocr_enrich] Fixed tesseract input format. [chrisr3d] - - - It looks like the `image_to_string` method now - assumes RGB format and the `imdecode` method - seems to give BGR format, so we convert the - image array before - -* [tests] Fixed tests for some modules waiting for standard MISP Attribute format as input. [chrisr3d] - -* [tests] Fixed hibp test which requires an API key. [chrisr3d] - -* [hibp] Fixed config handling to avoir KeyError exceptions. [chrisr3d] - -* [test] dns module. [Alexandre Dulaunoy] - -* [main] Disable duplicate JSON decoding. [Jakub Onderka] - -* [cve_advanced] Some CVEs are not in CWE format but in NVD-CWE-Other. [Alexandre Dulaunoy] - -* [farsight_passivedns] Fixed lookup_rdata_name results desclaration. [chrisr3d] - - - Getting generator as a list as it is already the - case for all the other results, so it avoids - issues to read the results by accidently looping - through the generator before it is actually - needed, which would lose the content of the - generator - - Also removed print that was accidently introduced - with the last commit - -* [farsight_passivedns] Excluding last_seen value for now, in order to get the available results. [chrisr3d] - - - With last_seen set we can easily get results - included in a certain time frame (between first - seen and last seen), but we do not get the - latest results. In order to get those ones, we - skip filtering on the time_last_before value - -* [farsight_passivedns] Fixed lookup_rdata_name results desclaration. [chrisr3d] - - - Getting generator as a list as it is already the - case for all the other results, so it avoids - issues to read the results by accidently looping - through the generator before it is actually - needed, which would lose the content of the - generator - - Also removed print that was accidently introduced - with the last commit - -* Making pep8 happy. [chrisr3d] - -* [farsight_passivedns] Fixed queries to the API. [chrisr3d] - - - Since flex queries input may be email addresses, - we nake sure we replace '@' by '.' in the flex - queries input. - - We also run the flex queries with the input as - is first, before runnning them as second time - with '.' characters escaped: '\\.' - -* Google.py module. [Jürgen Löhel] - - The search result does not include always 3 elements. It's better to - enumerate here. - The googleapi fails sometimes. Retry it 3 times. - -* Google.py module. [Jürgen Löhel] - - Corrects import for gh.com/abenassi/Google-Search-API. - -* Consider mail body as UTF-8 encoded. [Jakub Onderka] - -### Other - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [Alexandre Dulaunoy] - -* Fix; [tests] Changes on assertion statements that should fix the passivetotal, rbl & shodan tests. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [Alexandre Dulaunoy] - -* Merge pull request #435 from JakubOnderka/remove-duplicate-decoding. [Alexandre Dulaunoy] - - fix: [main] Remove duplicate JSON decoding - -* Add: [farsight_passivedns] Adding first_seen & last_seen (when available) in passivedns objects. [chrisr3d] - - - The object_relation `time_first` is added as the - `first_seen` value of the object - - Same with `time_last` -> `last_seen` - -* Merge branch 'main' of github.com:MISP/misp-modules into new_features. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into new_features. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into new_features. [chrisr3d] - -* Merge pull request #484 from GreyNoise-Intelligence/main. [Alexandre Dulaunoy] - - Update to GreyNoise expansion module - -* Update community api to released ver. [Brad Chiappetta] - -* Fix ver info. [Brad Chiappetta] - -* Updates for greynoise community api. [Brad Chiappetta] - -* Merge pull request #485 from jgwilson42/patch-1. [Alexandre Dulaunoy] - - Update README.md - -* Update README.md. [James Wilson] - - Ensure that the clone of misp-modules is owned by www-data - -* Merge pull request #482 from MISP/new_features. [Alexandre Dulaunoy] - - Farsight_passivedns module updated with new input types compatible with flex queries - -* Add: [farsight_passivedns] New lookup argument based on the first_seen & last_seen fields. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into new_features. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into new_features. [chrisr3d] - -* Merge pull request #481 from cocaman/main. [Alexandre Dulaunoy] - - Adding ThreatFox enrichment module - -* Adding additional tags. [Corsin Camichel] - -* First version of ThreatFox enrichment module. [Corsin Camichel] - -* Merge pull request #480 from cocaman/patch-1. [Alexandre Dulaunoy] - - updating "hibp" for API version 3 - -* Updating "hibp" for API version 3. [Corsin Camichel] - -* Merge pull request #477 from jloehel/fix/google-module. [Alexandre Dulaunoy] - - Fix/google module - -* Merge pull request #476 from digihash/patch-1. [Alexandre Dulaunoy] - - Update README.md - -* Update README.md. [Kevin Holvoet] - - Added fix based on https://github.com/MISP/MISP/issues/4045 - -* Merge pull request #475 from adammchugh/patch-3. [Alexandre Dulaunoy] - - Fixed the censys version - -* Fixed the censys version. [adammchugh] - - Unsure how I managed to get the version so wrong, but I have updated it to the current version and confirmed as working. - -* Merge pull request #474 from JakubOnderka/patch-4. [Alexandre Dulaunoy] - - fix: Consider mail body as UTF-8 encoded - -* Merge pull request #473 from adammchugh/patch-2. [Alexandre Dulaunoy] - - Change to pandas version requirement to address pip install failure - -* Included missing dependencies for censys and pyfaup. [adammchugh] - - Added censys dependency - Added pyfaup dependency - -* Change to pandas version requirement to address pip install failure. [adammchugh] - - Updated pandas version to 1.1.5 to allow pip install as defined at https://github.com/MISP/misp-modules to complete successfully. - -* Merge pull request #470 from adammchugh/patch-1. [Alexandre Dulaunoy] - - Update assemblyline_submit.py - Add verify SSL option - -* Update assemblyline_submit.py. [adammchugh] - -* Update assemblyline_query.py. [adammchugh] - -* Update assemblyline_submit.py. [adammchugh] - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [Alexandre Dulaunoy] - -* Update README long hyphen is not standard ASCII hyphen. [Alexandre Dulaunoy] - - Fix #464 - - -## v2.4.137 (2021-01-25) - -### Changes - -* Bump deps. [Raphaël Vinot] - -* Bump requirements. [Raphaël Vinot] - -* [pipenv] Enable email extras for PyMISP. [Jakub Onderka] - -### Fix - -* Bump PyMISP dep to latest. [Raphaël Vinot] - -* Use PyMISP from PyPi. [Raphaël Vinot] - -* Use pymisp from pypi. [Raphaël Vinot] - -* [pipenv] Missing clamd. [Jakub Onderka] - -### Other - -* Merge pull request #466 from NoDataFound/main. [Alexandre Dulaunoy] - - Corrected VMray rest API import - -* Corrected VMray rest API import. [Cory Kennedy] - - When loading misp-modules, the VMray module ```modules/expansion/vmray_submit.py ``` incorrectly imports the library. VMray's documentation and examples here: https://pypi.org/project/vmray-rest-api/#history also reflect this change as the correct import. - -* Merge pull request #457 from trustar/main. [Alexandre Dulaunoy] - - added more explicit error messages for indicators that return no enri… - -* Added more explicit error messages for indicators that return no enrichment data. [Jesse Hedden] - -* Merge pull request #452 from kuselfu/main. [Alexandre Dulaunoy] - - update vmray_import, add vmray_summary_json_import - -* Fix imports and unused variables. [Jens Thom] - -* Resolve merge conflict. [Jens Thom] - -* Merge remote-tracking branch 'upstream/main' into main. [Jens Thom] - -* Merge pull request #451 from JakubOnderka/versions-update. [Alexandre Dulaunoy] - - fix: [pipenv] Missing clamd - -* Merge pull request #450 from JakubOnderka/versions-update. [Alexandre Dulaunoy] - - chg: [pipenv] Enable email extras for PyMISP - -* Merge pull request #448 from HacknowledgeCH/export_defender_endpoint. [Alexandre Dulaunoy] - - Export defender endpoint - -* Fixed error reported by LGTM analysis. [milkmix] - -* Added documentation. [milkmix] - -* Added missing quotes. [milkmix] - -* Added URL support. [milkmix] - -* Typo in python src name. [milkmix] - -* Initial work on Defender for Endpoint export module. [milkmix] - -* * add parser for report version v1 and v2 * add summary JSON import module. [Jens Thom] - - -## v2.4.134 (2020-11-18) - -### New - -* [expansion] Added html_to_markdown module. [mokaddem] - - It fetches the HTML from the provided URL, performs a bit of DOM - clean-up then convert it into markdown - -* [clamav] Module for malware scan by ClamAV. [Jakub Onderka] - -* [passivedns, passivessl] Add support for ip-src|port and ip-dst|port. [Jakub Onderka] - -* Censys Expansion module. [Golbark] - -* Expansion module to query MALWAREbazaar API with some hash attribute. [chrisr3d] - -### Changes - -* [pipenv] Updated lock Pipfile again. [chrisr3d] - -* [pipenv] Updated lock Pipfile. [chrisr3d] - -* Added socialscan library in Pipfile and updated the lock file. [chrisr3d] - -* [documentation] Cleaner documentation directories & auto-generation. [chrisr3d] - - Including: - - A move of the previous `doc` and `docs` directories to `documentation` - - `documentation` is now the default directory - - The documentation previously under `doc` is now in `documentation/website` - - The mkdocs previously under `docs` is now in `documentation/mkdocs` - - All single JSON documentation files have been JQed - - Some small improvements to list fields displaying - -* [pipenv] Updated Pipfile. [chrisr3d] - -* [documentation] Updated the farsight-passivedns documentation. [chrisr3d] - -* [cpe] Added default limit to the results. [chrisr3d] - - - Results returned by CVE-search are sorted by - cvss score and limited in number to avoid - potential massive amount of data retuned back - to MISP. - - Users can overwrite the default limit with the - configuration already present as optional, and - can also set the limit to 0 to get the full list - of results - -* [farsight_passivedns] Now using the dnsdb2 python library. [chrisr3d] - - - Also updated the results parsing to check in - each returned result for every field if they are - included, to avoid key errors if any field is - missing - -* [cpe] Support of the new CVE-Search API. [chrisr3d] - -* [doc] Updated the farsight_passivedns module documentation. [chrisr3d] - -* [farsight_passivedns] More context added to the results. [chrisr3d] - - - References between the passive-dns objects and - the initial attribute - - Comment on object attributes mentioning whether - the results come from an rrset or an rdata - lookup - -* [farsight_passivedns] Rework of the module to return MISP objects. [chrisr3d] - - - All the results are parsed as passive-dns MISP - objects - - More love to give to the parsing to add - references between the passive-dns objects and - the input attribute, depending on the type of - the query (rrset or rdata), or the rrtype - (to be determined) - -* [cpe] Changed CVE-Search API default url. [chrisr3d] - -* [clamav] Add reference to original attribute. [Jakub Onderka] - -* [clamav] TCP port connection must be an integer. [Alexandre Dulaunoy] - -* Bump deps. [Raphaël Vinot] - -* Updated expansion modules documentation. [chrisr3d] - - - Added documentation for the missing modules - - Renamed some of the documentation files to match - with the module names and avoid issues within - the documentation file (README.md) with the link - of the miss-spelled module names - -* Updated the bgpranking expansion module test. [chrisr3d] - -* Updated documentation for the recently updated bgpranking module. [chrisr3d] - -* Updated the bgpranking expansion module to return MISP objects. [chrisr3d] - - - The module no longer returns freetext, since the - result returned to the freetext import as text - only allowed MISP to parse the same AS number as - the input attribute. - - The new result returned with the updated module - is an asn object describing more precisely the - AS number, and its ranking for a given day - -* Turned the Shodan expansion module into a misp_standard format module. [chrisr3d] - - - As expected with the misp_standard modules, the - input is a full attribute and the module is able - to return attributes and objects - - There was a lot of data that was parsed as regkey - attributes by the freetext import, the module now - parses properly the different field of the result - of the query returned by Shodan - -* Updated documentation about the greynoise module. [chrisr3d] - -* Updated Greynoise tests following the latest changes on the expansion module. [chrisr3d] - -* Making use of the Greynoise v2 API. [chrisr3d] - -* Bump deps. [Raphaël Vinot] - -* [doc] Added details about faup. [Steve Clement] - -* [doc] in case btc expansion fails, give another hint at why it fails. [Steve Clement] - -* [travis] Added gtcaca and liblua to faup. [Steve Clement] - -* [travis] Added py3.8. [Steve Clement] - -* Bump dependencies. [Raphaël Vinot] - - Should fix https://github.com/MISP/MISP/issues/5739 - -* Quick ransomdncoin test just to make sure the module loads. [chrisr3d] - - - I do not have any api key right now, so the test - should just reach the error - -* Catching missing config issue. [chrisr3d] - -### Fix - -* [pipenv] Removed duplicated dnsdb2 entry that I missed while merging conflict. [chrisr3d] - -* Removed debugging print command. [chrisr3d] - -* [tests] Less specific assertion for the rbl module test. [chrisr3d] - -* [farsight_passivedns] Fixed pep8 backslash issue. [chrisr3d] - -* [farsight_passivedns] Fixed issue with variable name. [chrisr3d] - -* [documentation] Added missing cpe module documentation. [chrisr3d] - -* [cpe] Fixed typo in vulnerable-configuration object relation fields. [chrisr3d] - -* [farsight_passivedns] Fixed typo in the lookup fields. [chrisr3d] - -* [farsight_passivedns] Uncommented mandatory field that was commented for tests. [chrisr3d] - -* [tests] Small fixes on the expansion tests. [chrisr3d] - -* [dnsdb] Avoiding AttributeError with the sys library, probably depending on the python version. [chrisr3d] - -* [documentation] Updated links to the scripts, with the default branch no longer being master, but main. [chrisr3d] - -* Typo. [chrisr3d] - -* Updated Pipfile. [chrisr3d] - -* [cpe] Typos and variable name issues fixed + Making the module available in MISP. [chrisr3d] - -* [cve-advanced] Using the cpe and weakness attribute types. [chrisr3d] - -* [cve_advanced] Avoiding potential MISP object references issues. [chrisr3d] - - - Adding objects as dictionaries in an event may - cause issues in some cases. It is better to pass - the MISP object as is, as it is already a valid - object since the MISPObject class is used - -* [virustotal_public] Resolve key error when user enrich hostname. [chrisr3d] - - - Same as #424 - -* [virustotal] Resolve key error when user enrich hostname. [Jakub Onderka] - -* Typo in EMailObject. [Raphaël Vinot] - - Fix #427 - -* Making pep8 happy. [chrisr3d] - -* Fixed pep8. [chrisr3d] - -* Fixed pep8 + some copy paste issues introduced with the latest commits. [chrisr3d] - -* Avoid issues with the attribute value field name. [chrisr3d] - - - The module setup allows 'value1' as attribute - value field name, but we want to make sure that - users passing standard misp format with 'value' - instead, will not have issues, as well as - keeping the current setup - -* [virustotal] Subdomains is optional in VT response. [Jakub Onderka] - -* Fixed list of sigma backends. [chrisr3d] - -* Fixed validators dependency issues. [chrisr3d] - - - Possible rollback if we get issues with virustotal - -* Removed multiple spaces to comply with pep8. [chrisr3d] - -* Making pep8 happy. [chrisr3d] - -* Removed trustar_import module name in init to avoid validation issues. [chrisr3d] - - (until it is submitted via PR?) - -* [circl_passivessl] Return proper error for IPv6 addresses. [Jakub Onderka] - -* [circl_passivessl] Return not found error. [Jakub Onderka] - - If passivessl returns empty response, return Not found error instead of error in log - -* [circl_passivedns] Return not found error. [Jakub Onderka] - - If passivedns returns empty response, return Not found error instead of error in log - -* [pep] Comply to PEP E261. [Steve Clement] - -* [travis] gtcaca has no build directory. [Steve Clement] - -* [pip] pyfaup required. [Steve Clement] - -* [doc] corrected filenames for 2 docs. [Christophe Vandeplas] - -* Making pep8 happy. [chrisr3d] - -* Catching errors in the reponse of the query to URLhaus. [chrisr3d] - -* Making pep8 happy with indentation. [chrisr3d] - -* Making pep8 happy. [chrisr3d] - -* Removed unused import. [chrisr3d] - -* Making pep8 happy. [chrisr3d] - -* Making the module config available so the module works. [chrisr3d] - -* [VT] Disable SHA512 query for VT. [Jakub Onderka] - -### Other - -* Merge branch 'main' of github.com:MISP/misp-modules into chrisr3d_patch. [chrisr3d] - -* Merge pull request #429 from MISP/new_module. [Christian Studer] - - New module using socialscan to check the availability of an email address or username on some online platforms - -* Merge branch 'main' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Add: Added documentation for the socialscan new module. [chrisr3d] - - - Also quick fix of the message for an invalid - result or response concerning the queried email - address or username - -* Merge branch 'main' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Add: New module using socialscan library to check email addresses and usernames linked to accounts on online platforms. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into chrisr3d_patch. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into chrisr3d_patch. [chrisr3d] - -* Merge pull request #445 from chrisr3d/main. [Christian Studer] - - Added missing cpe module documentation - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [chrisr3d] - -* Add: [farsight-passivedns] Optional feature to submit flex queries. [chrisr3d] - - - The rrset and rdata queries remain the same but - with the parameter `flex_queries`, users can - also get the results of the flex rrnames & flex - rdata regex queries about their domain, hostname - or ip address - - Results can thus include passive-dns objects - containing the `raw_rdata` object_relation added - with 0a3e948 - -* Merge branch 'main' of github.com:MISP/misp-modules into chrisr3d_patch. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into chrisr3d_patch. [chrisr3d] - -* Merge branch 'chrisr3d_patch' of github.com:MISP/misp-modules into main. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into chrisr3d_patch. [chrisr3d] - -* Merge pull request #443 from trustar/main. [Alexandre Dulaunoy] - - fixed typo causing firstSeen and lastSeen to not be pulled from enric… - -* Fixed typo causing firstSeen and lastSeen to not be pulled from enrichment data. [Jesse Hedden] - -* Merge pull request #440 from MISP/chrisr3d_patch. [Alexandre Dulaunoy] - - Farsight passivedns module update - -* Merge pull request #437 from chrisr3d/main. [Alexandre Dulaunoy] - - New expansion module to get the vulnerabilities related to a CPE - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [chrisr3d] - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [chrisr3d] - -* Merge pull request #436 from MISP/new-html-to-markdown. [Christian Studer] - - new: [expansion] Added html_to_markdown module - -* Add: Documentation for the html_to_markdown expansion module. [chrisr3d] - -* Add: Added documentation for the cpe module. [chrisr3d] - -* Add: First shot of an expansio module to query cve-search with a cpe to get the related vulnerabilities. [chrisr3d] - -* Merge pull request #432 from JakubOnderka/clamav. [Alexandre Dulaunoy] - - chg: [clamav] Add reference to original attribute - -* Merge pull request #431 from JakubOnderka/clamav. [Alexandre Dulaunoy] - - new: [clamav] Module for malware scan by ClamAV - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [Raphaël Vinot] - -* Merge pull request #424 from JakubOnderka/vt-subdomains-fix. [Christian Studer] - - fix: [virustotal] Resolve key error when user enrich hostname - -* Merge pull request #426 from hildenjohannes/main. [Alexandre Dulaunoy] - - Recorded Future module: Add proxy support and User-Agent header - -* Add proxy support and User-Agent header. [johannesh] - -* Merge pull request #425 from elhoim/elhoim-patch-1. [Alexandre Dulaunoy] - - Disable correlation for detection-ratio attribute in virustotal.py - -* Disable correlation for detection-ratio in virustotal.py. [David André] - -* Merge pull request #422 from trustar/feat/EN-5047/MISP-manual-update. [Alexandre Dulaunoy] - - Feat/en 5047/misp manual update - -* Merge branch 'main' into feat/EN-5047/MISP-manual-update. [Jesse Hedden] - -* Merge pull request #420 from hildenjohannes/main. [Alexandre Dulaunoy] - - Fix typo error introduced in commit: 3b7a5c4dc2541f3b07baee69a7e8b969… - -* Fix typo error introduced in commit: 3b7a5c4dc2541f3b07baee69a7e8b9694a1627fc. [johannesh] - -* Merge pull request #417 from trustar/feat/EN-4664/trustar-misp. [Alexandre Dulaunoy] - - Feat/en 4664/trustar misp - -* Added description to readme. [Jesse Hedden] - -* Merge branch 'master' of github.com:trustar/misp-modules into feat/EN-4664/trustar-misp. [Jesse Hedden] - -* Removed obsoleted module name. [Jesse Hedden] - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [chrisr3d] - -* Merge pull request #416 from hildenjohannes/main. [Alexandre Dulaunoy] - - Add Recorded Future module documentation - -* Improve wording. [johannesh] - -* Add Recorded Future module documentation. [johannesh] - -* Add: Specific error message for misp_standard format expansion modules. [chrisr3d] - - - Checking if the input format is respected and - displaying an error message if it is not - -* Merge pull request #415 from hildenjohannes/main. [Alexandre Dulaunoy] - - Add Recorded Future expansion module - -* Add Recorded Future expansion module. [johannesh] - -* Added comments. [Jesse Hedden] - -* Added comments. [Jesse Hedden] - -* Added comments. [Jesse Hedden] - -* Added error checking. [Jesse Hedden] - -* Updating to include metadata and alter type of trustar link generated. [Jesse Hedden] - -* Merge pull request #1 from trustar/feat/EN-4664/trustar-misp. [Jesse Hedden] - - Feat/en 4664/trustar misp - -* Merge branch 'main' of github.com:MISP/misp-modules into main. [chrisr3d] - -* Merge pull request #411 from JakubOnderka/vt-subdomains-fix. [Alexandre Dulaunoy] - - fix: [virustotal] Subdomains is optional in VT response - -* Merge remote-tracking branch 'origin' into main. [chrisr3d] - -* Add: Trustar python library added to Pipfile. [chrisr3d] - -* Merge branch 'trustar-feat/EN-4664/trustar-misp' [chrisr3d] - -* Merge branch 'feat/EN-4664/trustar-misp' of https://github.com/trustar/misp-modules into trustar-feat/EN-4664/trustar-misp. [chrisr3d] - -* Removed obsolete file. [Jesse Hedden] - -* Corrected variable name. [Jesse Hedden] - -* Fixed indent. [Jesse Hedden] - -* Fixed incorrect attribute name. [Jesse Hedden] - -* Fixed metatag; convert summaries generator to list for error handling. [Jesse Hedden] - -* Added strip to remove potential whitespace. [Jesse Hedden] - -* Removed extra parameter. [Jesse Hedden] - -* Added try/except for TruSTAR API errors and additional comments. [Jesse Hedden] - -* Added comments and increased page size to max for get_indicator_summaries. [Jesse Hedden] - -* Uploaded TruSTAR logo. [Jesse Hedden] - -* Updated client metatag and version. [Jesse Hedden] - -* Added module documentation. [Jesse Hedden] - -* Added client metatag to trustar client. [Jesse Hedden] - -* Ready for code review. [Jesse Hedden] - -* WIP: initial push. [Jesse Hedden] - -* Initial commit. not a working product. need to create a class to manage the MISP event and TruStar client. [Jesse Hedden] - -* Merge pull request #381 from MISP/new_module. [Christian Studer] - - New module for MALWAREbazaar - -* Merge branch 'main' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge pull request #407 from JakubOnderka/patch-3. [Alexandre Dulaunoy] - - fix: [circl_passivessl] Return proper error for IPv6 addresses - -* Merge pull request #406 from JakubOnderka/ip-port. [Alexandre Dulaunoy] - - new: [passivedns, passivessl] Add support for ip-src|port and ip-dst|port - -* Merge pull request #405 from JakubOnderka/patch-2. [Alexandre Dulaunoy] - - fix: [circl_passivedns] Return not found error - -* Merge pull request #402 from MISP/dependabot/pip/httplib2-0.18.0. [Alexandre Dulaunoy] - - build(deps): bump httplib2 from 0.17.0 to 0.18.0 - -* Build(deps): bump httplib2 from 0.17.0 to 0.18.0. [dependabot[bot]] - - Bumps [httplib2](https://github.com/httplib2/httplib2) from 0.17.0 to 0.18.0. - - [Release notes](https://github.com/httplib2/httplib2/releases) - - [Changelog](https://github.com/httplib2/httplib2/blob/master/CHANGELOG) - - [Commits](https://github.com/httplib2/httplib2/compare/v0.17.0...v0.18.0) - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge pull request #395 from SteveClement/master. [Steve Clement] - - chg: [deps] pyfaup seems to be required but not installed - -* Merge pull request #393 from vmray-labs/update-vmray-module. [Alexandre Dulaunoy] - - Update vmray_submit module - -* Update vmray_submit. [Matthias Meidinger] - - The submit module hat some smaller issues with the reanalyze flag. - The source for the enrichment object has been changed and the robustness - of user supplied config parsing improved. - -* Merge pull request #388 from Golbark/censys_expansion. [Christophe Vandeplas] - - new: usr: Censys Expansion module - -* Fix variable issue in the loop. [Golbark] - -* Adding support for more input types, including multi-types. [Golbark] - -* Add: Added documentation for the latest new modules. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #380 from JakubOnderka/patch-1. [Christian Studer] - - csvimport: Return error if input is not valid UTF-8 - -* Csvimport: Return error if input is not valid UTF-8. [Jakub Onderka] - -* Merge pull request #379 from cudeso/master. [Alexandre Dulaunoy] - - Cytomic Orion MISP Module - -* Documentation for Cytomic Orion. [Koen Van Impe] - -* Update __init__ [Koen Van Impe] - -* Make Travis (a little bit) happy. [Koen Van Impe] - -* Cytomic Orion MISP Module. [Koen Van Impe] - - An expansion module to enrich attributes in MISP and share indicators - of compromise with Cytomic Orion - -* Merge pull request #377 from 0xbennyv/master. [Alexandre Dulaunoy] - - Added SophosLabs Intelix as expansion module - -* Removed Unused Import. [bennyv] - -* Fixed handler error handling for missing config. [bennyv] - -* Fixed formatting in README.md. [bennyv] - -* Updated the README.md for SOPHOSLabs Intelix. [bennyv] - -* Initial Build of SOPHOSLabs Intelix Product. [bennyv] - -* Merge pull request #374 from M0un/projet-m2-oun-gindt. [Christian Studer] - - Rendu projet master2 sécurité par Mathilde OUN et Vincent GINDT // No… - -* Rendu projet master2 sécurité par Mathilde OUN et Vincent GINDT // Nouveau module misp de recherche google sur les urls. [Mathilde Oun et Vincent Gindt] - -* Merge pull request #373 from seanthegeek/patch-1. [Christian Studer] - - Create missing __init__.py for _ransomcoindb - -* Revert change inteded for other patch. [Sean Whalen] - -* Install cmake to build faup. [Sean Whalen] - -* Create __init__.py. [Sean Whalen] - -* Merge pull request #371 from GlennHD/master. [Christian Studer] - - Added GeoIP_City and GeoIP_ASN Database Modules - -* Update geoip_asn.py. [GlennHD] - -* Update geoip_city.py. [GlennHD] - -* Added geoip_asn and geoip_city to load. [GlennHD] - -* Added GeoIP_ASN Enrichment module. [GlennHD] - -* Added GeoIP_City Enrichment module. [GlennHD] - -* Added GeoIP City and GeoIP ASN Info. [GlennHD] - -* Merge pull request #370 from JakubOnderka/vt-query-sha512. [Alexandre Dulaunoy] - - fix: [VT] Disable SHA512 query for VT - -* Merge pull request #368 from andurin/lastline_verifyssl. [Christian Studer] - - Lastline verify_ssl option - -* Lastline verify_ssl option. [Hendrik] - - Helps people with on-prem boxes - - -## v2.4.121 (2020-02-06) - -### Fix - -* Making pep8 happy. [chrisr3d] - -* [tests] Fixed BGP raking module test. [chrisr3d] - -### Other - -* Merge pull request #367 from joesecurity/master. [Christian Studer] - - joe: (1) allow users to disable PE object import (2) set 'to_ids' to False - -* Joe: (1) allow users to disable PE object import (2) set 'to_ids' to False. [Georg Schölly] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #365 from ostefano/analysis. [Alexandre Dulaunoy] - - change: migrate to analysis API when submitting files to Lastline - -* Change: migrate to analysis API when submitting tasks to Lastline. [Stefano Ortolani] - -* Merge pull request #364 from cudeso/master. [Christian Studer] - - 2nd fix for VT Public module - -* 2nd fix for VT Public module. [Koen Van Impe] - -* Fix error message in Public VT module. [Koen Van Impe] - - -## v2.4.120 (2020-01-21) - -### New - -* Updated ipasn and added vt_graph documentation. [chrisr3d] - -* Enrichment module for querying APIVoid with domain attributes. [chrisr3d] - -### Changes - -* Making ipasn module return asn object(s) [chrisr3d] - - - Latest changes on the returned value as string - broke the freetext parser, because no asn number - could be parsed when we return the full json - blob as a freetext attribute - - Now returning asn object(s) with a reference to - the initial attribute - -* Bumped pipfile.lock with up-to-date libraries and new vt_graph_api library requirement. [chrisr3d] - -* Checking attributes category. [chrisr3d] - - - We check the category before adding the - attribute to the event - - Checking if the category is correct and if not, - doing a case insensitive check - - If the category is not correct after the 2 first - tests, we simply delete it from the attribute - and pymisp will give the attribute a default - category value based on the atttribute type, at - the creation of the attribute - -* Regenerated the modules documentation following the latest changes. [chrisr3d] - -* Updated documentation following the latest changes on the passive dns module. [chrisr3d] - -* Made circl_passivedns module able to return MISP objects. [chrisr3d] - -* Updated documentation following the latest changes on the passive ssl module. [chrisr3d] - -* Made circl_passivessl module able to return MISP objects. [chrisr3d] - -* Bump dependencies. [Raphaël Vinot] - -* Install faup in travis. [Raphaël Vinot] - -* Deactive emails tests, need update. [Raphaël Vinot] - -* Update email import module, support objects. [Raphaël Vinot] - -* Bump dependencies. [Raphaël Vinot] - -### Fix - -* Fixed ipasn test input format + module version updated. [chrisr3d] - -* Updated ipasn test following the latest changes on the module. [chrisr3d] - -* Typo. [chrisr3d] - -* Fixed vt_graph imports. [chrisr3d] - -* Fixed pep8 in the new module and related libraries. [chrisr3d] - -* Fixed typo on function import. [chrisr3d] - -* [doc] Added APIVoid logo. [chrisr3d] - -* Making pep8 happy with whitespace after ':' [chrisr3d] - -* [tests] With values, tests are always better ... [chrisr3d] - -* [tests] Fixed copy paste issue. [chrisr3d] - -* [tests] Fixed error catching in passive dns and ssl modules. [chrisr3d] - -* [tests] Avoiding issues with btc addresses. [chrisr3d] - -* Making pep8 happy by having spaces around '+' operators. [chrisr3d] - -* [tests] Added missing variable. [chrisr3d] - -* Making pep8 happy. [chrisr3d] - -* Missing dependency in travis. [Raphaël Vinot] - -* Properly install pymisp with file object dependencies. [Raphaël Vinot] - -* Quick variable name fix. [chrisr3d] - -* OTX tests were failing, new entry. [Raphaël Vinot] - -* Somewhat broken emails needed some love. [Raphaël Vinot] - -* MIssing parameter in skip. [Raphaël Vinot] - -* Missing pushd. [Raphaël Vinot] - -* Missing sudo. [Raphaël Vinot] - -### Other - -* Merge pull request #361 from VirusTotal/master. [Christian Studer] - - add vt_graph export module - -* Add vt-graph-api to the requirements. [Alvaro Garcia] - -* Add vt_graph export module. [Alvaro Garcia] - -* Merge pull request #360 from ec4n6/patch-1. [Alexandre Dulaunoy] - - Fix ipasn.py bug - -* Update ipasn.py. [Erick Cheng] - -* Add: Documentation for the new API Void module. [chrisr3d] - -* Add: [tests] Test case for the APIVoid module. [chrisr3d] - -* Revert "fix: [tests] Fixed copy paste issue" [chrisr3d] - - This reverts commit fd711475dd84749063f9ff15961453f90c804101. - -* Add: Test cases for reworked passive dns and ssl modules. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - - -## v2.4.119 (2019-12-03) - -### Changes - -* Bump dependencies. [Raphaël Vinot] - -* Use MISPObject in ransomcoindb. [Raphaël Vinot] - -* Reintroducing the limit to reduce the number of recursive calls to the API when querying for a domain. [chrisr3d] - -### Fix - -* Making pep8 happy. [chrisr3d] - -* Fixed AssemblyLine input description. [chrisr3d] - -* Fixed input types list since domain should not be submitted to AssemblyLine. [chrisr3d] - -* Making pep8 happy. [chrisr3d] - -* Added missing AssemblyLine logo. [chrisr3d] - -* Avoiding KeyError exception when no result is found. [chrisr3d] - -### Other - -* Merge pull request #356 from ostefano/lastline. [Alexandre Dulaunoy] - - add: Modules to query/import/submit data from/to Lastline - -* Add: Modules to query/import/submit data from/to Lastline. [Stefano Ortolani] - -* Revert "Merge pull request #341 from StefanKelm/master" [Raphaël Vinot] - - This reverts commit 1df0d9152ed3346a9432393177c89e137bfc0c64, reversing - changes made to 6042619c6b7fb40fd77b5328f933e67e839e1e83. - - This PR was a fixing a typo in a test case. The typo is in a 3rd party - service. - -* Merge pull request #341 from StefanKelm/master. [Raphaël Vinot] - - Update test_expansions.py - -* Update test_expansions.py. [StefanKelm] - - Tiniest of typos - -* Merge branch 'aaronkaplan-master' [Raphaël Vinot] - -* Oops , use relative import. [aaronkaplan] - -* Use a helpful user-agent string. [aaronkaplan] - -* Final url fix. [aaronkaplan] - -* Revert "fix url" [aaronkaplan] - - This reverts commit 44130e2bf9842c03fb80245b90a873917b56df74. - -* Revert "fix url again" [aaronkaplan] - - This reverts commit c5924aee2543b268b296a57096e636261676b63c. - -* Fix url again. [aaronkaplan] - -* Fix url. [aaronkaplan] - -* Mention the ransomcoindb in the README file as a new module. [aaronkaplan] - -* Remove pprint. [aaronkaplan] - -* Initial version of the ransomcoindb expansion module. [aaronkaplan] - -* Merge pull request #352 from aaronkaplan/patch-1. [Alexandre Dulaunoy] - - Update README.md - -* Update README.md. [AaronK] - - fixes #351 - -* Add: Added documentation for the AssemblyLine query module. [chrisr3d] - -* Add: Module to query AssemblyLine and parse the results. [chrisr3d] - - - Takes an AssemblyLine submission link to query - the API and get the full submission report - - Parses the potentially malicious files and the - IPs, domains or URLs they are connecting to - - Possible improvement of the parsing filters in - order to include more data in the MISP event - -* Add: Added documentation and description in readme for the AssemblyLine submit module. [chrisr3d] - -* Add: Updated python dependencies to include the assemblyline_client library. [chrisr3d] - -* Add: New expansion module to submit samples and urls to AssemblyLine. [chrisr3d] - - -## v2.4.118 (2019-11-08) - -### Changes - -* Using EQL module description from blaverick62. [chrisr3d] - -* [test expansion] Enhanced results parsing. [chrisr3d] - -* [travis] skip E226 as it's more a question of style. [Alexandre Dulaunoy] - -* [apiosintds] make flake8 happy. [Alexandre Dulaunoy] - -* [Pipfile] apiosintDS added as required by new module. [Alexandre Dulaunoy] - -* [env] Pipfile updated. [Alexandre Dulaunoy] - -* [pipenv] updated. [Alexandre Dulaunoy] - -* Avoids returning empty values + easier results parsing. [chrisr3d] - -* Taking into consideration if a user agent is specified in the module configuration. [chrisr3d] - -* Updated csv import documentation. [chrisr3d] - -### Fix - -* Fixed csv file parsing. [chrisr3d] - -* Fixed Xforce Exchange authentication + rework. [chrisr3d] - - - Now able to return MISP objects - - Support of the xforce exchange authentication - with apikey & apipassword - -* Added urlscan & secuirtytrails modules in __init__ list. [chrisr3d] - -* Avoiding empty config error on passivetotal module. [chrisr3d] - -* More clarity on the exception raised on the securitytrails module. [chrisr3d] - -* Better exceptions handling on the passivetotal module. [chrisr3d] - -* Fixed results parsing for various module tests. [chrisr3d] - -* Fixed variable name. [chrisr3d] - -* Bumped Pipfile.lock with the latest libraries versions. [chrisr3d] - -* Fixed config parsing and the associated error message. [chrisr3d] - -* Fixed config parsing + results parsing. [chrisr3d] - - - Avoiding errors with config field when it is - empty or the apikey is not set - - Parsing all the results instead of only the - first one - -* Fixed VT results. [chrisr3d] - -* Making urlscan module available in MISP for ip attributes. [chrisr3d] - - - As expected in the the handler function - -* Avoiding various modules to fail with uncritical issues. [chrisr3d] - - - Avoiding securitytrails to fail with an unavailable - feature for free accounts - - Avoiding urlhaus to fail with input attribute - fields that are not critical for the query and - results - - Avoiding VT modules to fail when a certain - resource does not exist in the dataset - -* Fixed config field parsing for various modules. [chrisr3d] - - - Same as previous commit - -* [expansion] Better config field handling for various modules. [chrisr3d] - - - Testing if config is present before trying to - look whithin the config field - - The config field should be there when the module - is called form MISP, but it is not always the - case when the module is queried from somewhere else - -* [test expansion] Using CVE with lighter results. [chrisr3d] - -* Avoid issues when some config fields are not set. [chrisr3d] - -* Updated pipfile.lock with the correct geoip2 library info. [chrisr3d] - -* Fixed requirements for pymisp and geoip python libraries. [chrisr3d] - -* Fixed Geoip with the supported python library + fixed Geolite db path management. [chrisr3d] - -* Removed unused self param turning the associated functions into static methods. [chrisr3d] - -* Updates following the latest CVE-search version. [chrisr3d] - - - Support of the new vulnerable configuration - field for CPE version > 2.2 - - Support of different 'unknown CWE' message - -* Fixed module names with - to avoid errors with python paths. [chrisr3d] - -* Fixed tesseract python library issues. [Christian Studer] - - - Avoiding 'tesseract is not installed or it's not in your path' issues - -* Using absolute path to open files instead of relative path. [chrisr3d] - -* Removed unused import\ [chrisr3d] - -* Handling issues when the otx api is queried too often in a short time. [chrisr3d] - -* Making pep8 happy. [chrisr3d] - -* Avoiding empty values + Fixed empty types error + Fixed filename KeyError. [chrisr3d] - -* Fixed ThreatMiner results parsing. [chrisr3d] - -* Catching wikidata errors properly + fixed errors parsing. [chrisr3d] - -* Grouped two if conditions to avoid issues with variable unassigned if the second condition is not true. [chrisr3d] - -* Handling errors and exceptions for expansion modules tests that could fail due to a connection error. [chrisr3d] - -* Considering the case of empty results. [chrisr3d] - -* Catching results exceptions properly. [chrisr3d] - -* Catching exceptions and results properly depending on the cases. [chrisr3d] - -* Handling cases where there is no result from the query. [chrisr3d] - -* DBL spamhaus test. [chrisr3d] - -* Quick typo & dbl spamhaus test fixes. [chrisr3d] - -* Fixed pattern parsing + made the module hover only. [chrisr3d] - -* Travis tests should be happy now. [chrisr3d] - -* Copy paste syntax error. [chrisr3d] - -* Fixed greynoise test following the latest changes on the module. [chrisr3d] - -* Returning results in text format. [chrisr3d] - - - Makes the hover functionality display the full - result instead of skipping the records list - -* Making pep8 happy. [chrisr3d] - -* Avoiding errors with uncommon lines. [chrisr3d] - - - Excluding first from data parsed all lines that - are comments or empty - - Skipping lines with failing indexes - -* Fixed unassigned variable name. [chrisr3d] - -* Removed no longer used variables. [chrisr3d] - -* Csv import rework & improvement. [chrisr3d] - - - More efficient parsing - - Support of multiple csv formats - - Possibility to customise headers - - More improvement to come for external csv file - -* Making pep8 happy. [chrisr3d] - -* [tests] Fixed tests to avoid config issues with the cve module. [chrisr3d] - - - Config currently empty in the module, but being - updated soon with a pending pull request - -### Other - -* Add: Updated documentation with the EQL export module. [chrisr3d] - -* Merge branch 'master' of github.com:blaverick62/misp-modules. [chrisr3d] - -* Added documentation json for new modules. [Braden Laverick] - -* Updated README to include EQL modules. [Braden Laverick] - -* Add: Xforce Exchange module tests. [chrisr3d] - -* Merge pull request #347 from MISP/tests. [Christian Studer] - - More advanced expansion tests - -* Merge branch 'master' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Add: Updated documentation with the latest modules info. [chrisr3d] - -* Updated README with new modules and fixed some links. [chrisr3d] - -* Add: Added test for vulners module. [chrisr3d] - -* Add: Added qrcode module test with its test image. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Merge pull request #346 from blaverick62/master. [Alexandre Dulaunoy] - - EQL Query Generation Modules - -* Removed extraneous comments and unused imports. [Braden Laverick] - -* Fixed python links. [Braden Laverick] - -* Changed file name to mass eql export. [Braden Laverick] - -* Fixed comments. [Braden Laverick] - -* Added ors for compound queries. [Braden Laverick] - -* Fixed syntax error. [Braden Laverick] - -* Changed to single attribute EQL. [Braden Laverick] - -* Added EQL enrichment module. [Braden Laverick] - -* Fixed string formatting. [Braden Laverick] - -* Fixed type error in JSON parsing. [Braden Laverick] - -* Attempting to import endgame module. [Braden Laverick] - -* Added endgame export to __all__ [Braden Laverick] - -* Added EQL export test module. [Braden Laverick] - -* Add: [test expansion] Added various tests for modules with api authentication. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Add: [test expansion] New modules tests. [chrisr3d] - - - Starting testing some modules with api keys - - Testing new apiosintDS module - -* Merge pull request #344 from davidonzo/master. [Alexandre Dulaunoy] - - Added apiosintDS module to query OSINT.digitalside.it services - -* Added apiosintDS module to query OSINT.digitalside.it services. [Davide] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #345 from 0xmilkmix/fix_geoip2. [Alexandre Dulaunoy] - - updated to geoip2 to support mmdb format - -* Updated to geoip2 to support mmdb format. [milkmix] - -* Add: cve_advanced module test + functions to test attributes and objects results. [chrisr3d] - -* Merge pull request #342 from MISP/tests. [Christian Studer] - - More expansion tests - -* Merge branch 'tests' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Add: Tests for all the office, libreoffice, pdf & OCR enrich modules. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Add: threatminer module test. [chrisr3d] - -* Add: Tests for expansion modules with different input types. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #339 from MISP/tests. [Christian Studer] - - Expansion modules tests update - -* Add: Added tests for the rest of the easily testable expansion modules. [chrisr3d] - - - More tests for more complex modules to come soon - -* Merge branch 'master' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Merge branch 'tests' of github.com:MISP/misp-modules. [chrisr3d] - -* Add: Tests for sigma queries and syntax validator modules. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into tests. [chrisr3d] - -* Add: More modules tested. [chrisr3d] - -* Add: Added tests for some expansion modules without API key required. [chrisr3d] - - - More tests to come - -* Merge pull request #338 from MISP/features_csvimport. [Christian Studer] - - Fixed the CSV import module - -* Merge pull request #335 from FafnerKeyZee/patch-2. [Christian Studer] - - Travis should not be complaining with the tests after the latest update on "test_cve" - -* Adding custom API. [Fafner [_KeyZee_]] - - Adding the possibility to have our own API server. - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #334 from FafnerKeyZee/patch-1. [Alexandre Dulaunoy] - - Cleaning the error message - -* Cleaning the error message. [Fafner [_KeyZee_]] - - The original message can be confusing is the user change to is own API. - - -## v2.4.116 (2019-09-17) - -### Other - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #329 from 8ear/8ear-add-mkdocs-documentation. [Alexandre Dulaunoy] - - Update mkdocs documentation - -* Fixing Install.md. [8ear] - -* Fix Install.md. [8ear] - -* Change Install documentation. [8ear] - -* Merge pull request #328 from 8ear/8ear-add-docker-capabilitites. [Alexandre Dulaunoy] - - Add Docker Capabilitites - -* Add .travis.yml command for docker build. [8ear] - -* Merge github.com:MISP/misp-modules into 8ear-add-docker-capabilitites. [8ear] - -* Disable not required package virtualenv for final stage. [8ear] - -* Fix entrypoint bug. [8ear] - -* Improve the Dockerfile. [8ear] - -* Add Dockerfile, Entrypoint and Healthcheck script. [8ear] - -* Update install doc. [8ear] - -* Bugfixing for MISP-modules. [8ear] - -* Add: New parameter to specify a custom CVE API to query. [chrisr3d] - - - Any API specified here must return the same - format as the CIRCL CVE search one in order to - be supported by the parsing functions, and - ideally provide response to the same kind of - requests (so the CWE search works as well) - - -## v2.4.114 (2019-08-30) - -### Changes - -* [cuckooimport] Handle archives downloaded from both the WebUI and the API. [Pierre-Jean Grenier] - -### Fix - -* Prevent symlink attacks. [Pierre-Jean Grenier] - -* Have I been pwned API changed again. [Raphaël Vinot] - -### Other - -* Merge pull request #327 from zaphodef/cuckooimport. [Alexandre Dulaunoy] - - fix: prevent symlink attacks - -* Merge pull request #326 from zaphodef/cuckooimport. [Alexandre Dulaunoy] - - chg: [cuckooimport] Handle archives downloaded from both the WebUI and the API - - -## v2.4.113 (2019-08-19) - -### New - -* Rewrite cuckooimport. [Pierre-Jean Grenier] - -### Changes - -* Update PyMISP version. [Pierre-Jean Grenier] - -### Fix - -* Avoiding issues when no CWE id is provided. [chrisr3d] - -* Fixed unnecessary dictionary field call. [chrisr3d] - - - No longer necessary to go under 'Event' field - since PyMISP does not contain it since the - latest update - -### Other - -* Merge pull request #322 from zaphodef/cuckooimport. [Alexandre Dulaunoy] - - Rewrite cuckooimport - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Add: Added initial event to reference it from the vulnerability object created out of it. [chrisr3d] - - -## v2.4.112 (2019-08-02) - -### New - -* First version of an advanced CVE parser module. [chrisr3d] - - - Using cve.circl.lu as well as the initial module - - Going deeper into the CVE parsing - - More parsing to come with the CWE, CAPEC and so on - -### Changes - -* [docs] add additional references. [Alexandre Dulaunoy] - -* [travis] revert. [Alexandre Dulaunoy] - -* [travis] github token. [Alexandre Dulaunoy] - -* [travis] mkdocs disabled for the time being. [Alexandre Dulaunoy] - -* [doc] Fix #317 - update the link to the latest version of the training. [Alexandre Dulaunoy] - -* [doc] README updated to the latest version. [Alexandre Dulaunoy] - -* [docs] symbolic link removed. [Alexandre Dulaunoy] - -* [docs] add logos symbolic link. [Alexandre Dulaunoy] - -* Add print to figure out what's going on on travis. [Raphaël Vinot] - -* Bump dependencies. [Raphaël Vinot] - -* Updated the module to work with the updated VirusTotal API. [chrisr3d] - - - Parsing functions updated to support the updated - format of the VirusTotal API responses - - The module can now return objects - - /!\ This module requires a high number of - requests limit rate to work as expected /!\ - -* Adding references between a domain and their siblings. [chrisr3d] - -* Getting domain siblings attributes uuid for further references. [chrisr3d] - -### Fix - -* Using the attack-pattern object template (copy-paste typo) [chrisr3d] - -* Making pep8 happy. [chrisr3d] - -* Fixed cvss-score object relation name. [chrisr3d] - -* Avoid issues when there is no pe field in a windows file sample analysis. [chrisr3d] - - - For instance: doc file - -* Avoid adding file object twice if a KeyError exception comes for some unexpected reasons. [chrisr3d] - -* Testing if file & registry activities fields exist before trying to parse it. [chrisr3d] - -* Testing if there is some screenshot data before trying to fetch it. [chrisr3d] - -* Fixed direction of the relationship between files, PEs and their sections. [chrisr3d] - - - The file object includes a PE, and the PE - includes sections, not the other way round - -* Fixed variable names. [chrisr3d] - -* Wrong change in last commit. [Raphaël Vinot] - -* Skip tests on haveibeenpwned.com if 403. Make pep8 happy. [Raphaël Vinot] - -* Changed the way references added at the end are saved. [chrisr3d] - - - Some references are saved until they are added - at the end, to make it easier when needed - - Here we changed the way they are saved, from a - dictionary with some keys to identify each part - to the actual dictionary with the keys the - function add_reference needs, so we can directly - use this dictionary as is when the references are - added to the different objects - -* Fixed link in documentation. [chrisr3d] - -* Avoiding issues with non existing sample types. [chrisr3d] - -* Undetected urls are represented in lists. [chrisr3d] - -* Changed function name to avoid confusion with the same variable name. [chrisr3d] - -* Quick fix on siblings & url parsing. [chrisr3d] - -* Typo. [chrisr3d] - -* Parsing detected & undetected urls. [chrisr3d] - -* Various fixes about typo, variable names, data types and so on. [chrisr3d] - -* Making pep8 happy. [chrisr3d] - -### Other - -* Merge pull request #319 from 8ear/8ear-add-mkdocs-documentation. [Alexandre Dulaunoy] - - Add `make deploy` to Makefile - -* Added docker and non-docker make commands. [8ear] - -* Add `make deploy` [8ear] - -* Merge pull request #318 from chrisr3d/master. [Christian Studer] - - Updated cve_advanced module to parse CWE and CAPEC data related to the CVE - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Add: Making vulnerability object reference to its related capec & cwe objects. [chrisr3d] - -* Add: Parsing CAPEC information related to the CVE. [chrisr3d] - -* Add: Parsing CWE related to the CVE. [chrisr3d] - -* Merge pull request #316 from 8ear/8ear-add-mkdocs-documentation. [Alexandre Dulaunoy] - - Add web documentation via mkdocs - -* Fix Bugs. [8ear] - -* Fix Fossa in index.md. [8ear] - -* Delete unused file. [8ear] - -* Change mkdocs deploy method. [8ear] - -* Change index.md. [8ear] - -* Merge branch 'master' into 8ear-add-mkdocs-documentation. [Max H] - -* Add: Parsing linux samples and their elf data. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Add: Parsing apk samples and their permissions. [chrisr3d] - -* Add: Added virustotal_public to the list of available modules. [chrisr3d] - -* Add: TODO comment for the next improvement. [chrisr3d] - -* Add: [documentation] Updated README and documentation with the virustotal modules changes. [chrisr3d] - -* Add: Parsing communicating samples returned by domain reports. [chrisr3d] - -* Add: Parsing downloaded samples as well as the referrer ones. [chrisr3d] - -* Add: Object for VirusTotal public API queries. [chrisr3d] - - - Lighter analysis of the report to avoid reaching - the limit of queries per minute while recursing - on the different elements - -* Add: Updated README file with the new module description. [chrisr3d] - -* Change contribute.md. [8ear] - -* Update index.md. [8ear] - -* Add mkdocs as a great web documentation. [8ear] - -* Merge pull request #1 from fossabot/master. [Max H] - - Add license scan report and status - -* Add license scan report and status. [fossabot] - - -## v2.4.110 (2019-07-08) - -### New - -* [doc] Joe Sandbox added in the list. [Alexandre Dulaunoy] - -* Expansion module to query urlhaus API. [chrisr3d] - - - Using the next version of modules, taking a - MISP attribute as input and able to return - attributes and objects - - Work still in process in the core part - -### Changes - -* [documentation] Making URLhaus visible from the github page. [chrisr3d] - - - Because of the white color, the logo was not - visible at all - -* Moved JoeParser class to make it reachable from expansion & import modules. [chrisr3d] - -* [install] REQUIREMENTS file updated. [Alexandre Dulaunoy] - -* [install] Pipfile.lock updated. [Alexandre Dulaunoy] - -* [requirements] Python API wrapper for the Joe Sandbox API added. [Alexandre Dulaunoy] - -* Bump dependencies. [Raphaël Vinot] - -* [pep8] try/except # noqa. [Steve Clement] - - Not sure how to make flake happy on this one. - -* Updated csvimport to support files from csv export + import MISP objects. [chrisr3d] - -### Fix - -* Added missing add_attribute function. [chrisr3d] - -* [documentation] Fixed json file name. [chrisr3d] - -* [documentation] Fixed some description & logo. [chrisr3d] - -* Testing if an object is not empty before adding it the the event. [chrisr3d] - -* Making travis happy. [chrisr3d] - -* Support of the latest version of sigmatools. [chrisr3d] - -* We will display galaxies with tags. [chrisr3d] - -* Returning tags & galaxies with results. [chrisr3d] - - - Tags may exist with the current version of the - parser - - Galaxies are not yet expected from the parser, - nevertheless the principle is we want to return - them as well if ever we have some galaxies from - parsing a JoeSandbox report. Can be removed if - we never galaxies at all - -* Removed duplicate finalize_results function call. [chrisr3d] - -* Making pep8 happy + added joe_import module in the init list. [chrisr3d] - -* Fixed variable name typo. [chrisr3d] - -* Fixed references between domaininfo/ipinfo & their targets. [chrisr3d] - - - Fixed references when no target id is set - - Fixed domaininfo parsing when no ip is defined - -* Some quick fixes. [chrisr3d] - - - Fixed strptime matching because months are - expressed in abbreviated format - - Made data loaded while the parsing function is - called, in case it has to be called multiple - times at some point - -* Making pep8 & travis happy. [chrisr3d] - -* Added references between processes and the files they drop. [chrisr3d] - -* Avoiding network connection object duplicates. [chrisr3d] - -* Avoid creating a signer info object when the pe is not signed. [chrisr3d] - -* Avoiding dictionary indexes issues. [chrisr3d] - - - Using tuples as a dictionary indexes is better - than using generators... - -* Avoiding attribute & reference duplicates. [chrisr3d] - -* Handling case of multiple processes in behavior field. [chrisr3d] - - - Also starting parsing file activities - -* Testing if some fields exist before trying to import them. [chrisr3d] - - - Testing for pe itself, pe versions and pe signature - -* Removed test print. [chrisr3d] - -* Fixed output format to match with the recent changes on modules. [chrisr3d] - -* Making pep8 happy. [chrisr3d] - -* Checking not MISP header fields. [chrisr3d] - - - Rejecting fields not recognizable by MISP - -* Using pymisp classes & methods to parse the module results. [chrisr3d] - -* Clearer user config messages displayed in the import view. [chrisr3d] - -* Removed unused library. [chrisr3d] - -* Make pep8 happy. [chrisr3d] - -* [pep8] More fixes. [Steve Clement] - -* [pep8] More pep8 happiness. [Steve Clement] - -* [pep8] Fixes. [Steve Clement] - -* Fixed standard MISP csv format header. [root] - - - The csv header we can find in data produced from - MISP restSearch csv format is the one to use to - recognize a csv file produced by MISP - -* Fixed introspection fields for csvimport & goamlimport. [root] - - - Added format field for goaml so the module is - known as returning MISP attributes & objects - - Fixed introspection to make the format, user - config and input source fields visible from - MISP (format also added at the same time) - -* Fixed libraries import that changed with the latest merge. [root] - -* Fixed fields parsing to support files from csv export with additional context. [chrisr3d] - -* Handling the case of Context included in the csv file exported from MISP. [chrisr3d] - -* Fixed changes omissions in handler function. [chrisr3d] - -* Fixed object_id variable name typo. [root] - -* Making json_decode even happier with full json format. [chrisr3d] - - - Using MISPEvent because it is cleaner & easier - - Also cleaner implementation globally - -* Using to_dict on attributes & objects instead of to_json to make json_decode happy in the core part. [chrisr3d] - -### Other - -* Add: [documentation] Added some missing documentation for the most recently added modules. [chrisr3d] - -* Add: [documentation] Added documentation for Joe Sandbox & URLhaus. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #309 from Kortho/patch-2. [Steve Clement] - - changed service pointer - -* Changed service pointer. [Kortho] - - Changed so the service starts the modules in the venv where they are installed - -* Merge pull request #308 from Kortho/patch-1. [Steve Clement] - - Fixed missing dependencies for RHEL install - -* Fixed missing dependencies for RHEL install. [Kortho] - - Added dependencies needed for installing the python library pdftotext - -* Add: Added screenshot of the behavior of the analyzed sample. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #307 from ninoseki/fix-missing-links. [Alexandre Dulaunoy] - - Fix missing links in README.md - -* Fix missing links in README.md. [Manabu Niseki] - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge pull request #306 from MISP/new_module. [Alexandre Dulaunoy] - - New modules able to return MISP objects - -* Add: Added new modules to the list. [chrisr3d] - -* Merge branch 'new_module' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge pull request #305 from joesecurity/new_module. [Alexandre Dulaunoy] - - joesandbox_query.py: improve behavior in unexpected circumstances - -* Joesandbox_query.py: improve behavior in unexpected circumstances. [Georg Schölly] - -* Add: New expansion module to query Joe Sandbox API with a report link. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge branch 'joesecurity-joesandbox_submit' [Alexandre Dulaunoy] - -* Merge branch 'joesandbox_submit' of https://github.com/joesecurity/misp-modules into joesecurity-joesandbox_submit. [Alexandre Dulaunoy] - -* Add expansion for joe sandbox. [Georg Schölly] - -* Merge pull request #304 from joesecurity/new_module. [Alexandre Dulaunoy] - - add support for url analyses - -* Support url analyses. [Georg Schölly] - -* Improve forwards-compatibility. [Georg Schölly] - -* Add: Parsing MITRE ATT&CK tactic matrix related to the Joe report. [chrisr3d] - -* Add: Parsing domains, urls & ips contacted by processes. [chrisr3d] - -* Add: Starting parsing dropped files. [chrisr3d] - -* Add: Starting parsing network behavior fields. [chrisr3d] - -* Add: Parsing registry activities under processes. [chrisr3d] - -* Add: Parsing processes called by the file analyzed in the joe sandbox report. [chrisr3d] - -* Add: Parsing some object references at the end of the process. [chrisr3d] - -* Add: [new_module] Module to import data from Joe sandbox reports. [chrisr3d] - - - Parsing file, pe and pe-section objects from the - report file info field - - Deeper file info parsing to come - - Other fields parsing to come as well - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge pull request #300 from cudeso/master. [Alexandre Dulaunoy] - - Bugfix for "sources" ; do not include as IDS for "access" registry keys - -* Bugfix for "sources" ; do not include as IDS for "access" registry keys. [Koen Van Impe] - - - Bugfix to query "operations" in files, mutex, registry - - Do not set IDS flag for registry 'access' operations - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* New VMRay modules (#299) [Steve Clement] - - New VMRay modules - -* New VMRay modules. [Koen Van Impe] - - New JSON output format of VMRay - Prepare for automation (via PyMISP) with workflow taxonomy tags - -* Merge pull request #1 from MISP/master. [Koen Van Impe] - - Sync - -* Add: Added urlhaus in the expansion modules init list. [root] - -* Merge branch 'new_module' of https://github.com/MISP/misp-modules into new_module. [root] - -* Merge branch 'features_csvimport' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into features_csvimport. [chrisr3d] - -* Merge branch 'features_csvimport' of github.com:MISP/misp-modules into features_csvimport. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into features_csvimport. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into features_csvimport. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge branch 'new_module' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge branch 'master' of https://github.com/MISP/misp-modules into new_module. [root] - -* Merge branch 'master' of https://github.com/MISP/misp-modules into new_module. [root] - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - - -## v2.4.106 (2019-04-27) - -### New - -* Devel mode. [Raphaël Vinot] - - Fix #293 - -* Modules for greynoise, haveibeenpwned and macvendors. [Raphaël Vinot] - -* Add missing dependency (backscatter) [Raphaël Vinot] - -* Add systemd launcher. [Raphaël Vinot] - -* Intel471 module. [Raphaël Vinot] - -* [btc] Very simple BTC expansion chg: [req] yara-python is preferred. [Steve Clement] - -* First version of a yara rule creation expansion module. [chrisr3d] - -* Documentation concerning modules explained in markdown file. [chrisr3d] - -* Expansion hover module to check spamhaus DBL for a domain name. [chrisr3d] - -### Changes - -* [doc] install of deps updated. [Alexandre Dulaunoy] - -* Bump REQUIREMENTS. [Raphaël Vinot] - -* Bump dependencies. [Raphaël Vinot] - -* [doc] new MISP expansion modules added for PDF, OCR, DOCX, XLSX, PPTX , ODS and ODT. [Alexandre Dulaunoy] - -* [init] cleanup for pep. [Alexandre Dulaunoy] - -* [pdf-enrich] updated. [Alexandre Dulaunoy] - -* [Pipfile] collection removed. [Alexandre Dulaunoy] - -* Bump dependencies. [Raphaël Vinot] - -* [doc] Added new dependencies and updated RHEL/CentOS howto. (#295) [Steve Clement] - - chg: [doc] Added new dependencies and updated RHEL/CentOS howto. - -* [doc] Added new dependencies and updated RHEL/CentOS howto. [Steve Clement] - -* [init] removed trailing whitespace. [Alexandre Dulaunoy] - -* [ocr] re module not used - removed. [Alexandre Dulaunoy] - -* Bump dependencies, update REQUIREMENTS file. [Raphaël Vinot] - -* [doc] cuckoo_submit module added. [Alexandre Dulaunoy] - -* Require python3 instead of python 3.6. [Raphaël Vinot] - -* [travis] because we all need sudo. [Alexandre Dulaunoy] - -* [travis] because everyone need a bar. [Alexandre Dulaunoy] - -* [doc] qrcode and Cisco FireSight added. [Alexandre Dulaunoy] - -* [qrcode] add requirements. [Alexandre Dulaunoy] - -* [qrcode] added to the __init__ [Alexandre Dulaunoy] - -* [qrcode] flake8 needs some drugs. [Alexandre Dulaunoy] - -* [qrcode] various fixes to make it PEP compliant. [Alexandre Dulaunoy] - -* Bump dependencies. [Raphaël Vinot] - - Fix CVE-2019-11324 (urllib3) - -* Bump Dependencies. [Raphaël Vinot] - -* [doc] Updated README to reflect current virtualenv efforts. TODO: pipenv. [Steve Clement] - -* [doc] new modules added. [Alexandre Dulaunoy] - -* Bump dependencies. [Raphaël Vinot] - -* Bump dependencies. [Raphaël Vinot] - -* Bump Requirements. [Raphaël Vinot] - -* [doc] asciidoctor requirement removed (new PDF module use reportlab) [Alexandre Dulaunoy] - -* Bump dependencies, add update script. [Raphaël Vinot] - -* [doc] PDF export. [Alexandre Dulaunoy] - -* [pdfexport] make flake8 happy. [Alexandre Dulaunoy] - -* [pipenv] fix the temporary issue that python-yara is not officially released. [Alexandre Dulaunoy] - -* [requirements] reportlab added. [Alexandre Dulaunoy] - -* [pipenv] Pipfile.lock updated. [Alexandre Dulaunoy] - -* [requirements] updated. [Alexandre Dulaunoy] - -* [PyMISP] dep updated to the latest version. [Alexandre Dulaunoy] - -* PyMISP requirement. [Alexandre Dulaunoy] - -* [pypi] Made sure url-normalize installs less stric. [Steve Clement] - -* [btc_scam_check] fix spacing for making flake 8 happy. [Alexandre Dulaunoy] - -* [backscatter.io] blind fix regarding undefined value. [Alexandre Dulaunoy] - -* [doc] backscatter.io updated. [Alexandre Dulaunoy] - -* [doc] backscatter.io documentation added. [Alexandre Dulaunoy] - -* [backscatter.io] remove blank line at the end of the file. [Alexandre Dulaunoy] - -* [backscatter.io] Exception handler fixed for recent version of Python. [Alexandre Dulaunoy] - -* Bump dependencies. [Raphaël Vinot] - -* Use pipenv, update bgpranking/ipasn modules. [Raphaël Vinot] - -* [doc] Nexthink module added. [Alexandre Dulaunoy] - -* [doc] osquery export module added. [Alexandre Dulaunoy] - -* [doc] Nexthink export format added. [Alexandre Dulaunoy] - -* [doc] cannot type today. [Alexandre Dulaunoy] - -* [intel471] module added. [Alexandre Dulaunoy] - -* Regenerated documentation markdown file. [chrisr3d] - -* [onyphe] fix #252. [Alexandre Dulaunoy] - -* [btc] Removed simple PoC for btc expansion. [Steve Clement] - -* [doc] btc module added. [Alexandre Dulaunoy] - -* [doc] generated documentation updated. [Alexandre Dulaunoy] - -* [doc] btc module added to documentation. [Alexandre Dulaunoy] - -* [tools] Added psutil as a dependency to detect misp-modules PID. [Steve Clement] - -* [init] Added try/catch in case misp-modules is already running on a port, or port is in use... [Steve Clement] - -* Validating yara rules after their creation. [chrisr3d] - -* [documentation] osquery logo added. [Alexandre Dulaunoy] - -* [documentation] generated. [Alexandre Dulaunoy] - -* [docs] Added some missing dependencies and instructions for virtualenv deployment. [Steve Clement] - -* [doc] documentation generator updated to include links to source code. [Alexandre Dulaunoy] - -* Changed documentation markdown file name. [chrisr3d] - -* Structurded data. [chrisr3d] - -* Modified the mapping dictionary to support misp-objects updates. [chrisr3d] - -* Modified output format. [chrisr3d] - -* Add new dependency (oauth2) [Raphaël Vinot] - -* Dnspython3 has been superseded by the regular dnspython kit. [Raphaël Vinot] - -* Wikidata module added. [Alexandre Dulaunoy] - -* SPARQLWrapper added (for wikidata module) [Alexandre Dulaunoy] - -### Fix - -* Re-enable python 3.6 support. [Raphaël Vinot] - -* CTRL+C is working again. [Raphaël Vinot] - - Fix #292 - -* Make flake8 happy. [Raphaël Vinot] - -* [doc] Small typo fix. [Steve Clement] - -* Pep8 foobar. [Raphaël Vinot] - -* Add the new module sin the list of modules availables. [Raphaël Vinot] - -* Typos in variable names. [Raphaël Vinot] - -* Remove unused import. [Raphaël Vinot] - -* Tornado expects a KILL now. [Raphaël Vinot] - -* [exportpdf] update documentation. [Falconieri] - -* [exportpdf] custom path parameter. [Falconieri] - -* [exportpdf] add parameters. [Falconieri] - -* [exportpdf] mising whitespace. [Falconieri] - -* [exportpdf] problem on one line. [Falconieri] - -* [exportpdf] add configmodule parameter for galaxy. [Falconieri] - -* [reportlab] Textual description parameter. [Falconieri] - -* [pdfexport] Bugfix on PyMisp exportpdf call. [Falconieri] - -* Systemd service. [Raphaël Vinot] - -* Regenerated documentation. [chrisr3d] - -* Description fixed. [chrisr3d] - -* Pep8 related fixes. [Raphaël Vinot] - -* Make flake8 happy. [Raphaël Vinot] - -* Change in the imports in other sigma module. [Raphaël Vinot] - -* Change in the imports. [Raphaël Vinot] - -* Change module name. [Raphaël Vinot] - -* Allow redis details to be retrieved from environment variables. [Ruiwen Chua] - -* Remove tests on python 3.5. [Raphaël Vinot] - -* Make pep8 happy. [Raphaël Vinot] - -* Removed not valid input type. [chrisr3d] - -* Cleaned up not used variables. [chrisr3d] - -* Updated rbl module result format. [chrisr3d] - - - More readable as str than dumped json - -* Added Macaddress.io module in the init list. [chrisr3d] - -* Typo on input type. [chrisr3d] - -* Fixed type of the result in case of exception. [chrisr3d] - - - Set as str since some exception types are not - jsonable - -* Added hostname attribute support as it is intended. [chrisr3d] - -* Threatanalyzer_import - bugfix for TA6.1 behavior. [Christophe Vandeplas] - -* Displaying documentation items of each module by alphabetic order. [chrisr3d] - - - Also regenerated updated documentation markdown - -* Updated yara import error message. [chrisr3d] - - - Better to 'pip install -I -r REQUIREMENTS' to - have the correct yara-python version working - for all the modules, than having another one - failing with yara hash & pe modules - -* Specifying a yara-python version that works for hash & pe yara modules. [chrisr3d] - -* Making yara query an expansion module for single attributes atm. [chrisr3d] - -* Catching errors while parsing additional info in requests. [chrisr3d] - -* Reduced logos size. [chrisr3d] - -* Typo for separator between each explained module. [chrisr3d] - -* Making python 3.5 happy with the exception type ImportError. [chrisr3d] - -* Fixed exception type for python 3.5. [chrisr3d] - -* Fixed exception type. [chrisr3d] - -* Fixed syntax error. [chrisr3d] - -* Fixed indentation error. [chrisr3d] - -* Fixed 1 variable misuse + cleaned up variable names. [chrisr3d] - - - Fixed use of 'domain' variable instead of 'email' - - Cleaned up variable names to avoid redefinition - of built-in variables - -* Avoiding adding attributes that are already in the event. [chrisr3d] - -* Fixed quick variable issue. [chrisr3d] - -* Cleaned up test function not used anymore. [chrisr3d] - -* Multiple attributes parsing support. [chrisr3d] - - - Fixing one of my previous changes not processing - multiple attributes parsing - -* Removed print. [chrisr3d] - -* Some cleanup and output types fixed. [chrisr3d] - - - hashes types specified in output - -* Quick cleanup. [chrisr3d] - -* Quick cleanup. [chrisr3d] - -* Ta_import - bugfixes. [Christophe Vandeplas] - -* [cleanup] Quick clean up on exception type. [chrisr3d] - -* [cleanup] Quick clean up on yaml load function. [chrisr3d] - -* [cleanup] Quick clean up on exception type. [chrisr3d] - -* Put the report location parsing in a try/catch statement as it is an optional field. [chrisr3d] - -* Put the stix2-pattern library import in a try statement. [chrisr3d] - - --> Error more easily caught - -* Removed STIX related libraries, files, documentation, etc. [chrisr3d] - -* Avoid trying to build attributes with not intended fields. [chrisr3d] - - - Previously: if the header field is not an attribute type, then - it was added as an attribute field. - PyMISP then used to skip it if needed - - - Now: Those fields are discarded before they are put in an attribute - -* Using userConfig to define the header instead of moduleconfig. [chrisr3d] - -* Fixed input & output of the module. [chrisr3d] - -* Added an object checking. [Christian Studer] - - - Checking if there are objects in the event, and then if there is at least 1 transaction object - - This prevents the module from crashing, but does not guaranty having a valid GoAML file (depending on objects and their relations) - -* Fixed input & output of the module. [chrisr3d] - - Also updated some functions - -* Fixed typo of the aml type for country codes. [chrisr3d] - -* Typo in references mapping dictionary. [chrisr3d] - -* Added an object checking. [chrisr3d] - - - Checking if there are objects in the event, and then - if there is at least 1 transaction object - - This prevents the module from crashing, but does not - guaranty having a valid GoAML file (depending on - objects and their relations) - -* Added the moduleinfo field need to have MISP event in standard format. [chrisr3d] - -* Missing cve module test. [Alexandre Dulaunoy] - -* Goamlexport added. [Alexandre Dulaunoy] - -* Python version in Travis. [Alexandre Dulaunoy] - -* Solved reading problems for some files. [chrisr3d] - -* Skipping empty lines. [chrisr3d] - -* Make travis happy. [Raphaël Vinot] - -* OpenIOC importer. [Raphaël Vinot] - -* #137 when a CVE is not found, a return message is given. [Alexandre Dulaunoy] - -* Use the proper formatting method and not the horrible % one. [Hannah Ward] - -* Misp-modules are by default installed in /bin. [Alexandre Dulaunoy] - -* Module_config should be set as introspection relies on it. [Alexandre Dulaunoy] - -* Types array. [Alexandre Dulaunoy] - -* Run the server as "python3 misp-modules" [Raphaël Vinot] - -* Stupid off-by-n line... [Alexandre Dulaunoy] - -### Other - -* Merge branch 'master' of github.com:MISP/misp-modules. [Alexandre Dulaunoy] - -* Removed trailing whitespaces. [Sascha Rommelfangen] - -* Merge branch 'master' of https://github.com/MISP/misp-modules. [Sascha Rommelfangen] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Raphaël Vinot] - -* New modules added. [Sascha Rommelfangen] - -* New requirements for new modules. [Sascha Rommelfangen] - -* Introduction of new modules. [Sascha Rommelfangen] - -* Merge remote-tracking branch 'upstream/master' [Steve Clement] - -* Merge branch 'master' of https://github.com/MISP/misp-modules. [Sascha Rommelfangen] - -* Renamed file. [Sascha Rommelfangen] - -* Renamed module. [Sascha Rommelfangen] - -* Initial version of OCR expansion module. [Sascha Rommelfangen] - -* Merge pull request #291 from Evert0x/submitcuckoo. [Alexandre Dulaunoy] - - Expansion module - File/URL submission to Cuckoo Sandbox - -* Generate latest version of documentation. [Ricardo van Zutphen] - -* Document Cuckoo expansion module. [Ricardo van Zutphen] - -* Use double quotes and provide headers correctly. [Ricardo van Zutphen] - -* Update Cuckoo module to support files and URLs. [Ricardo van Zutphen] - -* Update __init__.py. [Evert0x] - -* Create cuckoo_submit.py. [Evert0x] - -* Brackets are difficult... [Sascha Rommelfangen] - -* Merge branch 'qr-code-module' of https://github.com/rommelfs/misp-modules into rommelfs-qr-code-module. [Alexandre Dulaunoy] - -* Initial version of QR code reader. [Sascha Rommelfangen] - - Module accepts attachments and processes pictures. It tries to identify and analyze an existing QR code. - Identified values can be inserted into the event. - -* Merge branch 'iceone23-patch-1' [Raphaël Vinot] - -* Create cisco_firesight_manager_ACL_rule_export.py. [iceone23] - - Cisco Firesight Manager ACL Rule Export module - -* Merge pull request #289 from SteveClement/master. [Steve Clement] - - fix: [doc] Small typo fix - -* Merge remote-tracking branch 'upstream/master' [Steve Clement] - -* Merge pull request #285 from wesinator/patch-1. [Alexandre Dulaunoy] - - Fix command highlighting - -* Fix command highlighting. [Ԝеѕ] - -* Merge branch 'master' of https://github.com/MISP/misp-modules. [Sascha Rommelfangen] - -* Merge pull request #284 from Vincent-CIRCL/master. [Alexandre Dulaunoy] - - fix: [exportpdf] custom path parameter - -* Merge pull request #283 from Vincent-CIRCL/master. [Alexandre Dulaunoy] - - fix: [exportpdf] add parameters - -* Merge pull request #281 from Vincent-CIRCL/master. [Alexandre Dulaunoy] - - fix: [exportpdf] add configmodule parameter for galaxy - -* Merge pull request #282 from cgi1/patch-1. [Alexandre Dulaunoy] - - Adding virtualenv to apt-get install - -* Adding virtualenv to apt-get install. [cgi1] - -* Merge pull request #279 from Vincent-CIRCL/master. [Alexandre Dulaunoy] - - fix: [reportlab] Textual description parameter - -* Chr: Restart the modules after update. [Raphaël Vinot] - -* Fixed a bug when checking malformed BTC addresses. [Sascha Rommelfangen] - -* Merge remote-tracking branch 'upstream/master' [Steve Clement] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Alexandre Dulaunoy] - -* Merge pull request #278 from Vincent-CIRCL/master. [Alexandre Dulaunoy] - - chg: [pdfexport] Fix pdf export, by calling new PyMISP tool for Misp Event export - -* Fix [exportpdf] update parameters for links generation. [Falconieri] - -* Tidy: Remove old dead export code. [Falconieri] - -* Test 1 - PDF call. [Falconieri] - -* Print values. [Vincent-CIRCL] - -* Test update. [Vincent-CIRCL] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Alexandre Dulaunoy] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Alexandre Dulaunoy] - -* Merge pull request #276 from iwitz/patch-1. [Alexandre Dulaunoy] - - Add RHEL installation instructions - -* Add: rhel installation instructions. [iwitz] - -* Add: [doc] Added backscatter.io logo + regenerated documentation. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into new_module. [chrisr3d] - -* Merge pull request #274 from 9b/master. [Alexandre Dulaunoy] - - Backscatter.io expansion module - -* Use the write var on return. [9b] - -* Stubbed module. [9b] - -* Add: New module to check if a bitcoin address has been abused. [chrisr3d] - - - Also related update of documentation - -* Sometimes server doesn't return expected values. fixed. [Sascha Rommelfangen] - -* Merge pull request #266 from MISP/pipenv. [Raphaël Vinot] - - chg: Use pipenv, update bgpranking/ipasn modules, fix imports for sigma - -* Merge pull request #259 from ruiwen/fix_redis. [Alexandre Dulaunoy] - - fix: allow redis details to be retrieved from environment variables - -* Add: [doc] link documentation to README. [Alexandre Dulaunoy] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Alexandre Dulaunoy] - -* Merge pull request #258 from HacknowledgeCH/export_nexthink. [Alexandre Dulaunoy] - - Export nexthink - -* Added 2 blank lines to comply w/ pep8. [milkmix] - -* Removed unused re module. [milkmix] - -* Added documentation. [milkmix] - -* Added domain attributes support. [milkmix] - -* Support for md5 and sha1 hashes. [milkmix] - -* First export feature: sha1 attributes nxql query. [milkmix] - -* Merge branch 'master' of https://github.com/MISP/misp-modules. [Sascha Rommelfangen] - -* Add: Added missing expansion modules in readme. [chrisr3d] - -* Add: Completed documentation for expansion modules. [chrisr3d] - -* Add: Updated more expansion documentation files. [chrisr3d] - -* Add: Added new documentation for hashdd module. [chrisr3d] - -* Add: Update to support sha1 & sha256 attributes. [chrisr3d] - -* Add: More documentation on expansion modules. [chrisr3d] - -* Add: Started filling some expansion modules documentation. [chrisr3d] - -* Add: Added yara_query module documentation, update yara_syntax_validator documentation & generated updated documentation markdown. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into chrisr3d_patch. [chrisr3d] - -* Add: Added test files for yara to test yara library & potentially yara syntax. [chrisr3d] - -* Add: Added imphash to input attribute types. [chrisr3d] - -* Cosmetic output change. [Sascha Rommelfangen] - -* Debug removed. [Sascha Rommelfangen] - -* API changes reflected. [Sascha Rommelfangen] - -* Merge pull request #253 from MISP/chrisr3d_patch. [Alexandre Dulaunoy] - - Validation of yara rules - -* Merge branch 'master' of github.com:MISP/misp-modules into chrisr3d_patch. [chrisr3d] - -* Merge pull request #251 from MISP/rommelfs-patch-4. [Raphaël Vinot] - - bug fix regarding leftovers between runs - -* Bug fix regarding leftovers between runs. [Sascha Rommelfangen] - -* Merge pull request #250 from SteveClement/btc. [Steve Clement] - - chg: [btc] Removed simple PoC for btc expansion. - -* Merge pull request #249 from MISP/rommelfs-patch-3. [Steve Clement] - - added btc_steroids - -* Added btc_steroids. [Sascha Rommelfangen] - -* Merge pull request #248 from rommelfs/master. [Sascha Rommelfangen] - - Pull request for master - -* Added btc_steroids to the list. [Sascha Rommelfangen] - -* Initial version of a Bitcoin module. [Sascha Rommelfangen] - -* Merge pull request #247 from SteveClement/btc. [Alexandre Dulaunoy] - - new: [module] Added very simple BitCoin expansion/hover module - -* Merge pull request #245 from chrisr3d/master. [Alexandre Dulaunoy] - - YARA rules from hashes expansion module - -* Updated list of modules in readme. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Add: [documentation] osquery logo. [Alexandre Dulaunoy] - -* Merge pull request #241 from 0xmilkmix/doc_osqueryexport. [Alexandre Dulaunoy] - - Added basic documentation for OS query - -* Merge branch 'master' into doc_osqueryexport. [Alexandre Dulaunoy] - -* Merge pull request #240 from 0xmilkmix/support_osquery_win_named_obj. [Alexandre Dulaunoy] - - super simple support for mutexes through winbaseobj in osquery 3.3 - -* Merge branch 'master' into support_osquery_win_named_obj. [Alexandre Dulaunoy] - -* Merge pull request #242 from 0xmilkmix/module_writting. [Steve Clement] - - chg: [doc] Additional documentation for export module - -* Documentation for export module. [milkmix] - -* Super simple support for mutexes through winbaseobj in osquery 3.3. [milkmix] - -* Added basic documentation. [milkmix] - -* Merge pull request #239 from SteveClement/master. [Steve Clement] - - chg: [docs] Added some missing dependencies and instructions for virtualenv deployment - -* Merge pull request #237 from 0xmilkmix/export_osquery. [Alexandre Dulaunoy] - - Export osquery - -* Merge branch 'master' into export_osquery. [Julien Bachmann] - -* Merge pull request #232 from CodeLineFi/master. [Alexandre Dulaunoy] - - macaddres.io module - Date conversion bug fixed - -* Merge branch 'master' into master. [Alexandre Dulaunoy] - -* Merge pull request #233 from chrisr3d/documentation. [Christian Studer] - - Modules documentation - -* Merge branch 'master' of github.com:MISP/misp-modules into documentation. [chrisr3d] - -* Updated documentation result file. [chrisr3d] - -* Add: Added documentation for expansion modules. [chrisr3d] - -* Add: Started adding logos on documentation for each module. [chrisr3d] - -* Renamed directory to have consistency in names. [chrisr3d] - -* Removed documentation about a module deleted from the repository. [chrisr3d] - -* Merging readme. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into documentation. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into documentation. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into documentation. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into documentation. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into documentation. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into documentation. [chrisr3d] - -* First try of documentation for import & export modules. [chrisr3d] - - - Providing information about the general purpose of - the modules, their requirements, how to use them - (if there are special features), some references - about the format concerned or the vendors, and their - input and output. - - Documentation to be completed by additional fields - of documentation and / or more detailed descriptions - -* Added Documentation explanations on readme file. [chrisr3d] - -* CSV import documentation first try. [chrisr3d] - -* GoAML modules documentation first try. [chrisr3d] - -* Updated README. Added a link to the integration tutorial. [Codelinefi-admin] - -* Fixed a bug with wrong dates conversion. [Codelinefi-admin] - -* Merge branch 'vulnersCom-master' [Alexandre Dulaunoy] - -* Merge branch 'master' of https://github.com/vulnersCom/misp-modules into vulnersCom-master. [Alexandre Dulaunoy] - -* Fixed getting of the Vulners AI score. [isox] - -* Merge pull request #230 from lctrcl/master. [Alexandre Dulaunoy] - -* Merge branch 'master' into master. [lctrcl] - -* Merge pull request #229 from lctrcl/master. [Alexandre Dulaunoy] - - New vulners module added - -* HotFix: Vulners AI score. [Igor Ivanov] - -* Code cleanup and formatting. [Igor Ivanov] - -* Added exploit information. [Igor Ivanov] - -* Initial Vulners module PoC. [Igor Ivanov] - -* Merge pull request #226 from CodeLineFi/master. [Alexandre Dulaunoy] - - New macaddress.io hover module added - -* Macaddress.io hover module added. [Codelinefi-admin] - -* Merge pull request #223 from chrisr3d/master. [Christian Studer] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #222 from chrisr3d/master. [Christian Studer] - - Clean up + fix of some modules - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #221 from MISP/rommelfs-patch-2. [Alexandre Dulaunoy] - - fixed typo - -* Fixed typo. [Sascha Rommelfangen] - - via #220 - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #218 from surbo/patch-1. [Alexandre Dulaunoy] - - Update urlscan.py - -* Update urlscan.py. [SuRb0] - - Added hash to the search so you can take advantage of the new file down load function on urlscan.io. You can use this to pivot on file hashes and find out domains that hosting the same malicious file. - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #217 from threatsmyth/master. [Alexandre Dulaunoy] - - Add error handling for DNS failures, reduce imports, and simplify attribute comments - -* Merge branch 'master' into master. [David J] - -* Merge pull request #215 from threatsmyth/master. [Alexandre Dulaunoy] - - Create urlscan.py - -* Add error handling for DNS failures, reduce imports, and simplify misp_comments. [David J] - -* Create urlscan.py. [David J] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #214 from chrisr3d/chrisr3d_patch. [Alexandre Dulaunoy] - - New module to check DBL Spamhaus - -* Merge branch 'chrisr3d_patch' of github.com:chrisr3d/misp-modules. [chrisr3d] - -* Add: Added DBL spamhaus module documentation and in expansion init file. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Ta_import - bugfixes for TA 6.1. [Christophe Vandeplas] - -* Merge pull request #210 from chrisr3d/master. [Christian Studer] - - Put the report location parsing in a try/catch statement as it is an optional field - -* Merge pull request #209 from cvandeplas/master. [Christophe Vandeplas] - - ta_import - support for TheatAnalyzer 6.1 - -* Ta_import - support for TheatAnalyzer 6.1. [Christophe Vandeplas] - -* Securitytrails.com expansion module added. [Alexandre Dulaunoy] - -* Merge pull request #208 from sebdraven/dnstrails. [Alexandre Dulaunoy] - - module securitytrails - -* Merge branch 'master' into dnstrails. [sebdraven] - -* Merge pull request #206 from chrisr3d/master. [Alexandre Dulaunoy] - - Expansion module displaying SIEM signatures from a sigma rule - -* Merge branch 'master' into master. [Alexandre Dulaunoy] - -* Remove the never release Python code in Travis. [Alexandre Dulaunoy] - -* Remove Python 3.4 and Python 3.7 added. [Alexandre Dulaunoy] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #202 from SteveClement/master. [Alexandre Dulaunoy] - - Removed test modules from view - -* - Removed test modules from view - Moved skeleton expansion module to it's proper place. [Steve Clement] - -* Merge pull request #201 from chrisr3d/master. [Alexandre Dulaunoy] - - add: STIX2 pattern syntax validator - -* Add: Experimental expansion module to display the SIEM signatures from a sigma rule. [chrisr3d] - -* Add: stix2 pattern validator requirements. [chrisr3d] - -* Add: STIX2 pattern syntax validator. [chrisr3d] - -* Merge pull request #199 from SteveClement/master. [Alexandre Dulaunoy] - - Added (Multipage) PDF support to OCR Module, minor refactor - -* - Reverted to <3.6 compatibility. [Steve Clement] - -* - Fixed log output. [Steve Clement] - -* - Forgot to import sys. [Steve Clement] - -* - Added logger functionality for debug sessions. [Steve Clement] - -* - content was already a wand.obj. [Steve Clement] - -* Merge remote-tracking branch 'upstream/master' [Steve Clement] - -* Threatanalyzer_import - order of category tuned. [Christophe Vandeplas] - -* Merge branch 'master' of github.com:SteveClement/misp-modules. [Steve Clement] - -* Merge branch 'master' into master. [Alexandre Dulaunoy] - -* - Some more comments - Removed libmagic, wand can handle it better. [Steve Clement] - -* - Set tornado timeout to 300 seconds. [Steve Clement] - -* - Quick comment ToDo: Avoid using Magic in future releases. [Steve Clement] - -* - added wand requirement - fixed missing return png byte-stream - move module import to handler to catch and report errorz. [Steve Clement] - -* - fixed typo move image back in scope. [Steve Clement] - -* - Added initial PDF support, nothing is processed yet - Test to replace PIL with wand. [Steve Clement] - -* Change type of status. [Sebdraven] - -* Remove print. [Sebdraven] - -* Last commit for release. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add searching_stats. [Sebdraven] - -* Add searching_stats. [Sebdraven] - -* Correct key. [Sebdraven] - -* Correct key. [Sebdraven] - -* Correct param. [Sebdraven] - -* Add searching domains. [Sebdraven] - -* Add searching domains. [Sebdraven] - -* Add return. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add whois expand to test. [Sebdraven] - -* Add whois expand to test. [Sebdraven] - -* Correct index error. [Sebdraven] - -* Error call functions. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add status_ok to true. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add logs. [Sebdraven] - -* Correct out of bound returns. [Sebdraven] - -* Correct key and return of functions. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add logs. [Sebdraven] - -* Correct typo. [Sebdraven] - -* Test whois history. [Sebdraven] - -* History whois dns. [Sebdraven] - -* Correct typo. [Sebdraven] - -* Rename misp modules. [Sebdraven] - -* Add a test to check if the list is not empty. [Sebdraven] - -* Add a test to check if the list is not empty. [Sebdraven] - -* Add logs. [Sebdraven] - -* Debug whois. [Sebdraven] - -* Debug ipv4 or ipv6. [Sebdraven] - -* Add debug. [Sebdraven] - -* Debug. [Sebdraven] - -* Change status. [Sebdraven] - -* Change history dns. [Sebdraven] - -* Add logs to debug. [Sebdraven] - -* Correct call function. [Sebdraven] - -* Add history mx and soa. [Sebdraven] - -* Add history dns and handler exception. [Sebdraven] - -* Add history dns. [Sebdraven] - -* Switch type ip. [Sebdraven] - -* Refactoring expand_whois. [Sebdraven] - -* Correct typo. [Sebdraven] - -* Add ipv6 and ipv4. [Sebdraven] - -* Change type. [Sebdraven] - -* Change type. [Sebdraven] - -* Change loop. [Sebdraven] - -* Add time sleep in each request. [Sebdraven] - -* Control return of records. [Sebdraven] - -* Add history ipv4. [Sebdraven] - -* Add logs. [Sebdraven] - -* Change categories. [Sebdraven] - -* Concat results. [Sebdraven] - -* Change name keys. [Sebdraven] - -* Change return value. [Sebdraven] - -* Add logs. [Sebdraven] - -* Change errors. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add expand whois. [Sebdraven] - -* Typo. [Sebdraven] - -* Add categories and comments. [Sebdraven] - -* Add expand subdomains. [Sebdraven] - -* Add expand subdomains. [Sebdraven] - -* Change categories. [Sebdraven] - -* Changes keys. [Sebdraven] - -* Add status ! [Sebdraven] - -* Add methods. [Sebdraven] - -* Add expand domains. [Sebdraven] - -* Add link pydnstrain in requirements. [Sebdraven] - -* Add new module dnstrails. [Sebdraven] - -* Merge pull request #198 from chrisr3d/master. [Alexandre Dulaunoy] - - Sigma syntax validator expansion module + some updates - -* Updated README to add sigma & some other missing modules. [chrisr3d] - -* Updated the list of modules (removed stiximport) [chrisr3d] - -* Add: Sigma syntax validator expansion module. [chrisr3d] - - --> Checks sigma rules syntax - - Updated the expansion modules list as well - - Updated the requirements list - -* Updated the list of expansion modules. [chrisr3d] - -* Corrected typos and unused imports. [milkmix] - -* Added support for scheduledtasks. [milkmix] - -* Added support for service-displayname, regkey|value. [milkmix] - -* Initial implementation supporting regkey. mutexes support waiting osquery table. [milkmix] - -* Merge pull request #197 from sebdraven/onyphe_full_module. [Alexandre Dulaunoy] - - Onyphe full module - -* Add return handle domains. [Sebdraven] - -* Add search. [Sebdraven] - -* Add domain to expand. [Sebdraven] - -* Correct bugs. [Sebdraven] - -* Add domain expansion. [Sebdraven] - -* Add comment. [Sebdraven] - -* Correct bugs. [Sebdraven] - -* Correct comments. [Sebdraven] - -* Add threat list expansion. [Sebdraven] - -* Change method to concat methods. [Sebdraven] - -* Set status after requests. [Sebdraven] - -* Set status after requests. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add logs. [Sebdraven] - -* Add logs. [Sebdraven] - -* Pep 8. [Sebdraven] - -* Correct bug. [Sebdraven] - -* Add datascan expansion. [Sebdraven] - -* Add reverse infos. [Sebdraven] - -* Add reverse infos. [Sebdraven] - -* Add reverse infos. [Sebdraven] - -* Add reverse infos. [Sebdraven] - -* Add forward infos. [Sebdraven] - -* Add comment of attributes. [Sebdraven] - -* Add comment of attributes. [Sebdraven] - -* Error loops. [Sebdraven] - -* Error method. [Sebdraven] - -* Error type. [Sebdraven] - -* Error keys. [Sebdraven] - -* Add expansion synscan. [Sebdraven] - -* Change key access domains. [Sebdraven] - -* Change add in results. [Sebdraven] - -* Add logs. [Sebdraven] - -* Correct error keys. [Sebdraven] - -* Test patries expansion. [Sebdraven] - -* Add onyphe full module. [Sebdraven] - -* Add onyphe full module and code the stub. [Sebdraven] - -* Merge pull request #194 from chrisr3d/master. [Alexandre Dulaunoy] - - Removed STIX1 related requirements to avoid version issues - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #193 from sebdraven/onyphe_module. [Alexandre Dulaunoy] - - Onyphe module - -* Delete vcs.xml. [sebdraven] - -* Correct codecov. [Sebdraven] - -* Pep 8 compliant. [Sebdraven] - -* Correct type of comments. [Sebdraven] - -* Correct typo. [Sebdraven] - -* Correct typo. [Sebdraven] - -* Add domains forward. [Sebdraven] - -* Add domains. [Sebdraven] - -* Add targeting os. [Sebdraven] - -* Add category for AS number. [Sebdraven] - -* Change keys. [Sebdraven] - -* Change type. [Sebdraven] - -* Add category. [Sebdraven] - -* Add as number with onyphe. [Sebdraven] - -* Add as number with onyphe. [Sebdraven] - -* Error indentation. [Sebdraven] - -* Correct key in map result. [Sebdraven] - -* Correct a bug. [Sebdraven] - -* Add pastebin url imports. [Sebdraven] - -* Add onyphe module. [Sebdraven] - -* Updated requirements to avoid version issues in the MISP packer installation script. [chrisr3d] - -* Update countrycode.py. [Andras Iklody] - -* Add: mixing modules. [Alexandre Dulaunoy] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Alexandre Dulaunoy] - -* Merge pull request #190 from chrisr3d/master. [Alexandre Dulaunoy] - - Updated csv import following our recent discussions - -* Updated delimiter finder function. [chrisr3d] - -* Add: Added user config to specify if there is a header in the csv to import. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #189 from chrisr3d/master. [Andras Iklody] - - Using userConfig to define the header instead of moduleconfig - -* Merge pull request #188 from cvandeplas/master. [Christophe Vandeplas] - - ta import - noise removal - -* Merge branch 'master' into master. [Christophe Vandeplas] - -* Merge pull request #187 from cvandeplas/master. [Christophe Vandeplas] - - threatanalyzer_import - minor generic noise removal - -* Threatanalyzer_import - minor generic noise removal. [Christophe Vandeplas] - -* Ta import - more filter for pollution. [Christophe Vandeplas] - -* Threatanalyzer_import - minor generic noise removal. [Christophe Vandeplas] - -* Merge pull request #185 from cvandeplas/master. [Christophe Vandeplas] - - threatanalyzer_import - loads sample info + pollution fix - -* Threatanalyzer_import - loads sample info + pollution fix. [Christophe Vandeplas] - -* Merge pull request #184 from cvandeplas/master. [Christophe Vandeplas] - - threatanalyzer_import - fix regkey issue - -* Threatanalyzer_import - fix regkey issue. [Christophe Vandeplas] - -* Merge pull request #177 from TheDr1ver/patch-1. [Alexandre Dulaunoy] - - fix missing comma - -* Fix missing comma. [Nick Driver] - - fix ip-dst and vulnerability input - -* Merge pull request #176 from cudeso/master. [Alexandre Dulaunoy] - - Fix VMRay API access error - -* Fix VMRay API access error. [Koen Van Impe] - - hotfix for the "Unable to access VMRay API" error - -* Merge remote-tracking branch 'MISP/master' [Koen Van Impe] - -* Merge pull request #173 from m3047/master. [Alexandre Dulaunoy] - - Add exception blocks for query errors. - -* Add exception blocks for query errors. [Fred Morris] - -* Merge pull request #170 from P4rs3R/patch-1. [Alexandre Dulaunoy] - - Improving regex (validating e-mail) - -* Improving regex (validating e-mail) [x41\x43] - - Line 48: - The previous regex ` ^[\w\.\+\-]+\@[\w]+\.[a-z]{2,3}$ ` matched only a small subset of valid e-mail address (e.g.: didn't match domain names longer than 3 chars or user@this-domain.de or user@multiple.level.dom) and needed to be with start (^) and end ($). - This ` [a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])? ` is not perfect (e.g: can't match oriental chars), but imho is much more complete. - - Regex tested with several e-mail addresses with Python 3.6.4 and Python 2.7.14 on Linux 4.14. - -* Merge pull request #169 from chrisr3d/master. [Alexandre Dulaunoy] - - Updated GoAML import including Object References - -* Clarified functions arguments using a class. [chrisr3d] - -* Add: Added Object References in the objects imported. [chrisr3d] - -* Merge pull request #168 from chrisr3d/goaml. [Alexandre Dulaunoy] - - GoAML import module & GoAML export updates - -* Merge branch 'master' of github.com:MISP/misp-modules into goaml. [chrisr3d] - -* Merge pull request #167 from chrisr3d/csvimport. [Alexandre Dulaunoy] - - Updated csvimport - -* Merge branch 'csvimport' of github.com:chrisr3d/misp-modules into goaml. [chrisr3d] - -* Removed print. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into csvimport. [chrisr3d] - -* Merge pull request #165 from chrisr3d/goaml. [Alexandre Dulaunoy] - - fix: Added an object checking - -* Add: added goamlimport. [chrisr3d] - -* Fixed some details about the module output. [chrisr3d] - -* Converting GoAML into MISPEvent. [chrisr3d] - -* Now parsing all the transaction attributes. [chrisr3d] - -* Add: Added dictionary to map aml types into MISP types. [chrisr3d] - -* Typo. [chrisr3d] - -* Merge branch 'master' of github.com:chrisr3d/misp-modules into aml_import. [chrisr3d] - -* Merge pull request #164 from chrisr3d/master. [Alexandre Dulaunoy] - - Latest fixes to make GoAML export module work - -* Add: Added an example file generated by GoAML export module. [chrisr3d] - -* Added GoAML export module in description. [chrisr3d] - -* Reading the entire document, to create a big dictionary containing the data, as a beginning. [chrisr3d] - -* Add: new expansion module to check hashes against hashdd.com including NSLR dataset. [Alexandre Dulaunoy] - -* Merge pull request #163 from chrisr3d/master. [Alexandre Dulaunoy] - - GoAML export - -* Typo. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Quick fix to the invalid hash types offered on all returned hashes, hopefully fixes #162. [Andras Iklody] - -* Explicit name. [chrisr3d] - - Avoiding confusion with the coming import module for goaml - -* Added "t_to" and "t_from" required fields: funds code & country. [chrisr3d] - -* Added a required field & the latest attributes in transaction. [chrisr3d] - -* Added report expected information fields. [chrisr3d] - -* Simplified ObjectReference dictionary reading. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* Add: YARA syntax validator. [Alexandre Dulaunoy] - -* Merge pull request #161 from eCrimeLabs/ecrimelabs_dev. [Alexandre Dulaunoy] - - Added Yara syntax validation expansion module - -* Added Yara syntax validation expansion module. [Dennis Rand] - -* Added some report information. [chrisr3d] - - Also changed the ObjectReference parser to replace - all the if conditions by a dictionary reading - -* Suporting the recent objects added to misp-objects. [chrisr3d] - - - Matching the aml documents structure - - Some parts of the document still need to be added - -* Wip: added location & signatory information. [chrisr3d] - -* Merge branch 'master' of github.com:MISP/misp-modules into test. [chrisr3d] - -* Merge pull request #157 from CenturyLinkCIRT/master. [Alexandre Dulaunoy] - - added csvimport to __init__.py - -* Added csvimport to __init__.py. [Thomas Gardner] - -* Add: CSV import module added. [Alexandre Dulaunoy] - -* Outputting xml format. [chrisr3d] - - Also mapping MISP and GoAML types - -* First tests for the GoAML export module. [chrisr3d] - -* Merge pull request #156 from chrisr3d/master. [Alexandre Dulaunoy] - - CSV import - -* Merge branch 'master' of github.com:MISP/misp-modules. [chrisr3d] - -* 3.7-alpha removed. [Alexandre Dulaunoy] - -* Updated delimiter finder method. [chrisr3d] - -* Fixed data treatment & other updates. [chrisr3d] - -* Updated delimiter parsing & data reading functions. [chrisr3d] - -* First version of csv import module. [chrisr3d] - - - If more than 1 misp type is recognized, for each one an - attribute is created - - - Needs to have header set by user as parameters of the module atm - - - Review needed to see the feasibility with fields that can create - confusion and be interpreted both as misp type or attribute field - (for instance comment is a misp type and an attribute field) - -* Merge pull request #154 from cvandeplas/master. [Raphaël Vinot] - - added CrowdStrike Falcon Intel Indicators expansion module - -* Added CrowdStrike Falcon Intel Indicators expansion module. [Christophe Vandeplas] - -* Add: RBL added. [Alexandre Dulaunoy] - -* Merge pull request #150 from chrisr3d/master. [Alexandre Dulaunoy] - - RBL check module - -* Merge github.com:MISP/misp-modules. [chrisr3d] - -* Merge pull request #149 from cvandeplas/master. [Alexandre Dulaunoy] - - Added ThreatAnalyzer sandbox import - -* Added ThreatAnalyzer sandbox import. [Christophe Vandeplas] - - Experimental module - some parts should be migrated to - -* Check an IPv4 address against known RBLs. [chrisr3d] - -* Fix farsight_passivedns - rdata 404 not found. [Christophe Vandeplas] - -* Added ThreatStream and PDF export. [Alexandre Dulaunoy] - -* Merge branch 'robertnixon2003-master' + a small fix. [Alexandre Dulaunoy] - -* Fix the __init__ import. [Alexandre Dulaunoy] - -* Update threatStream_misp_export.py. [Robert Nixon] - -* Updated __init__.py. [Robert Nixon] - - Added reference to new ThreatStream export module - -* Added threatStream_misp_export.py. [Robert Nixon] - -* Merge branch 'cvandeplas-master' [Alexandre Dulaunoy] - -* Fixes missing init file in dnsdb library folder. [Christophe Vandeplas] - -* New Farsight DNSDB Passive DNS expansion module. [Christophe Vandeplas] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Raphaël Vinot] - -* Merge pull request #144 from attritionorg/patch-1. [Andras Iklody] - - minor touch-ups on error messages for user friendliness - -* Minor touch-ups on error messages for user friendliness. [Jericho] - -* Merge pull request #140 from cudeso/master. [Alexandre Dulaunoy] - - VulnDB Queries - -* VulnDB Queries. [Koen Van Impe] - - Search on CVE at https://vulndb.cyberriskanalytics.com/ - https://www.riskbasedsecurity.com/ - Get extended CVE info, links + CPE - -* Merge remote-tracking branch 'MISP/master' [Koen Van Impe] - -* Add quick and dirty pdf export. [Raphaël Vinot] - -* Merge pull request #139 from Rafiot/master. [Raphaël Vinot] - - fix: OpenIOC importer - -* Merge pull request #135 from DomainTools/domaintools-patch-1. [Raphaël Vinot] - - Added code to allow 3rd party modules - -* Added default parameter for new -m flag. [Viktor von Drakk] - -* Added code to allow 3rd party modules. [Viktor von Drakk] - - The new '-m pip.module.name' feature allows a pip-installed module to be specified on the command line and then loaded into the available modules without having to copy-paste files into the appropriate directories of this package. - -* Broken links fixed. [Alexandre Dulaunoy] - -* ThreatConnect export module added. [Alexandre Dulaunoy] - -* Merge pull request #133 from CenturyLinkCIRT/master. [Alexandre Dulaunoy] - - ThreatConnect export module - -* Added threat_connect_export to export_mod.__init__ [Thomas Gardner] - -* Added test files for threat_connect_export. [Thomas Gardner] - -* Added threat_connect_export.py. [Thomas Gardner] - -* Merge pull request #129 from seamustuohy/utf_hate. [Raphaël Vinot] - - Added support for malformed internationalized email headers - -* Added support for malformed internationalized email headers. [seamus tuohy] - - When an emails contains headers that use Unicode without properly crafing - them to comform to RFC-6323 the email import module would crash. - (See issue #119 & issue #93) - - To address this I have added additional layers of encoding/decoding to - any possibly internationalized email headers. This decodes properly - formed and malformed UTF-8, UTF-16, and UTF-32 headers appropriately. - When an unknown encoding is encountered it is returned as an 'encoded-word' - per RFC2047. - - This commit also adds unit-tests that tests properly formed and malformed - UTF-8, UTF-16, UTF-32, and CJK encoded strings in all header fields; UTF-8, - UTF-16, and UTF-32 encoded message bodies; and emoji testing for headers - and attachment file names. - -* Merge branch 'master' into utf_hate. [seamus tuohy] - -* Added unit tests for UTF emails. [seamus tuohy] - -* OTX and ThreatCrowd added. [Alexandre Dulaunoy] - -* Merge pull request #130 from chrisdoman/master. [Alexandre Dulaunoy] - - Add AlienVault OTX and ThreatCrowd Expansions - -* Add AlienVault OTX and ThreatCrowd Expansions. [Chris Doman] - -* Use proper version of PyMISP. [Raphaël Vinot] - -* Update travis, fix open ioc import. [Raphaël Vinot] - -* Merge pull request #122 from truckydev/master. [Alexandre Dulaunoy] - - Add tags on import with ioc import module - -* Replace tab by space. [Tristan METAYER] - -* Add a field for user to add tag for this import. [Tristan METAYER] - -* Merge pull request #121 from truckydev/master. [Andras Iklody] - - If filename add iocfilename as attachment - -* Typo correction. [Tristan METAYER] - -* Add user config to not add file as attachement in a box. [Tristan METAYER] - -* If filename add iocfilename as attachment. [Tristan METAYER] - -* Merge pull request #118 from truckydev/master. [Alexandre Dulaunoy] - - Add indent field for export - -* Add indent field for export. [Tristan METAYER] - -* Merge pull request #115 from FloatingGhost/master. [Alexandre Dulaunoy] - - fix: Use the proper formatting method and not the horrible % one - -* Missing expansion modules added in README. [Alexandre Dulaunoy] - -* ThreatMiner added. [Alexandre Dulaunoy] - -* Merge pull request #114 from kx499/master. [Alexandre Dulaunoy] - - ThreatMiner Expansion module - -* Bug fixes. [kx499] - -* Threatminer initial commit. [kx499] - -* Cosmetic changes. [Raphaël Vinot] - -* Merge pull request #111 from kx499/master. [Raphaël Vinot] - - Handful of changes to VirusTotal module - -* Bug fixes, tweaks, and python3 learning curve :) [kx499] - -* Initial commit of IPRep module. [kx499] - -* Fixed spacing, addressed error handling for public api, added subdomains, and added context comment. [kx499] - -* OpenIOC import module added. [Alexandre Dulaunoy] - -* Add OpenIOC import module. [Raphaël Vinot] - -* Merge pull request #109 from truckydev/master. [Alexandre Dulaunoy] - - add information about offline installation - -* Add information about offline installation. [truckydev] - -* Merge pull request #106 from truckydev/master. [Alexandre Dulaunoy] - - Lite export of an event - -* Exclude internal reference. [Tristan METAYER] - -* Add lite Export module. [Tristan METAYER] - -* Merge pull request #100 from rmarsollier/master. [Alexandre Dulaunoy] - - Some improvements of virustotal plugin - -* Some improvements of virustotal plugin. [rmarsollier] - -* Merge pull request #96 from johestephan/master. [Raphaël Vinot] - - XForce Exchange v1 (alpha) - -* Passed local run check. [Joerg Stephan] - -* V1. [Joerg Stephan] - -* Removed urrlib2. [Joerg Stephan] - -* Python3 changes. [Joerg Stephan] - -* Merged xforce exchange. [Joerg Stephan] - -* XForce Exchange v1 (alpha) [Joerg Stephan] - -* Merge pull request #56 from RichieB2B/ncsc-nl/mispjson. [Alexandre Dulaunoy] - - Simple import module to import MISP JSON format - -* Updated description to reflect merging use case. [Richard van den Berg] - -* Simple import module to import MISP JSON format. [Richard van den Berg] - -* Merge pull request #92 from seamustuohy/duck_typing_failure. [Alexandre Dulaunoy] - - Email import no longer unzips major compressed text document formats. - -* Email import no longer unzips major compressed text document formats. [seamus tuohy] - - Let this commit serve as a warning about the perils of duck typing. - Word documents (docx,odt,etc) were being uncompressed when they were - attached to emails. The email importer now checks a list of well known - extensions and will not attempt to unzip them. - - It is stuck using a list of extensions instead of using file magic because - many of these formats produce an application/zip mimetype when scanned. - -* Merge branch 'master' of github.com:MISP/misp-modules. [Raphaël Vinot] - -* Merge pull request #91 from Rafiot/master. [Raphaël Vinot] - - Improve email import module - -* Keep zip content as binary. [Raphaël Vinot] - -* Fix tests, cleanup. [Raphaël Vinot] - -* Improve support of email attachments. [Raphaël Vinot] - - Related to #90 - -* Merge pull request #89 from Rafiot/fix_87. [Raphaël Vinot] - - Improve VT support. - -* Standardised key checking. [Hannah Ward] - -* Fixed checking for submission_names in VT JSON. [Hannah Ward] - -* Update virustotal.py. [CheYenBzh] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Raphaël Vinot] - -* Training materials updated + Cuckoo JSON import module was missing. [Alexandre Dulaunoy] - -* Improve support of email importer if headers are missing. [Raphaël Vinot] - - Fix #88 - -* Remove python 3.3 support. [Raphaël Vinot] - -* Fix python 3.6 support. [Raphaël Vinot] - -* Make PEP8 happy. [Raphaël Vinot] - -* Add email_import in the modules loaded by default. [Raphaël Vinot] - -* Make PEP8 happy. [Raphaël Vinot] - -* Fix failing test (bug in the mail parser?) [Raphaël Vinot] - -* Add additional email parsing and tests. [seamus tuohy] - - Added additional attribute parsing and corresponding unit-tests. - E-mail attachment and url extraction added in this commit. This includes - unpacking zipfiles and simple password cracking of encrypted zipfiles. - -* Fixed basic errors. [seamus tuohy] - -* Merged with current master. [seamus tuohy] - -* Merge pull request #85 from rmarsollier/master. [Raphaël Vinot] - - add libjpeg-dev as a dep to allow pillow to be installed succesfully - -* Add libjpeg-dev as a dep to allow pillow to be installed succesfully. [robin.marsollier@conix.fr] - -* GeoIP module added. [Alexandre Dulaunoy] - -* Merge pull request #84 from MISP/amuehlem-master. [Raphaël Vinot] - - Fix PR - -* Do not crash if the dat file is not available. [Raphaël Vinot] - -* Fix path to config file. [Raphaël Vinot] - -* Merge branch 'master' of https://github.com/amuehlem/misp-modules into amuehlem-master. [Raphaël Vinot] - -* Added empty line to end of config file. [Andreas Muehlemann] - -* Removed DEFAULT section from configfile. [Andreas Muehlemann] - -* Fixed more typos. [Andreas Muehlemann] - -* Fixed typo. [Andreas Muehlemann] - -* Changed configparser from python2 to python3. [Andreas Muehlemann] - -* Updated missing parenthesis. [Andreas Muehlemann] - -* Merge branch 'geoip_country' [Andreas Muehlemann] - -* Removed unneeded config option for misp. [Andreas Muehlemann] - -* Removed debug message. [Andreas Muehlemann] - -* Added config option to geoip_country.py. [Andreas Muehlemann] - -* Added pygeoip to the REQUIREMENTS list. [Andreas Muehlemann] - -* Updated geoip_country to __init__.py. [Andreas Muehlemann] - -* Added geoip_country.py. [Andreas Muehlemann] - -* Better error reporting. [Raphaël Vinot] - -* Catch exception. [Raphaël Vinot] - -* Add reverse lookup. [Raphaël Vinot] - -* Refactoring of domaintools expansion module. [Raphaël Vinot] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Raphaël Vinot] - -* Merge pull request #83 from stoep/master. [Alexandre Dulaunoy] - - Added cuckooimport.py - -* Added cuckooimport.py. [Ubuntu] - -* DomainTools module added. [Alexandre Dulaunoy] - -* Remove domaintools tests. [Raphaël Vinot] - -* Add test for domaintools. [Raphaël Vinot] - -* Merge pull request #78 from deralexxx/patch-2. [Alexandre Dulaunoy] - - Update README.md - -* Update README.md. [Alexander J] - - mentioning import / export modules - -* Merge pull request #76 from deralexxx/patch-1. [Alexandre Dulaunoy] - - Update README.md - -* Update README.md. [Alexander J] - -* Merge pull request #75 from Rafiot/domtools. [Raphaël Vinot] - - Add Domain Tools module - -* Update requirements list. [Raphaël Vinot] - -* Add domaintools to the import list. [Raphaël Vinot] - -* Fix Typo. [Raphaël Vinot] - -* Add domain profile and reputation. [Raphaël Vinot] - -* Add more comments. [Raphaël Vinot] - -* Fix typo. [Raphaël Vinot] - -* Remove json.dumps. [Raphaël Vinot] - -* Avoid passing None in comments. [Raphaël Vinot] - -* Add comments to fields when possible. [Raphaël Vinot] - -* Add initial Domain Tools module. [Raphaël Vinot] - -* Merge pull request #74 from cudeso/master. [Raphaël Vinot] - - Extra VTI detections - -* Merge remote-tracking branch 'MISP/master' [Koen Van Impe] - -* Update README.md. [Raphaël Vinot] - -* Merge pull request #73 from FloatingGhost/master. [Raphaël Vinot] - - Use SpooledTemp, not NamedTemp file - -* Use git for everything we can. [Hannah Ward] - -* Ok we'll use the dep from misp-stix-converter. Surely this'll work? [Hannah Ward] - -* Use the CIRCL pymisp. Silly @rafiot ;) [Hannah Ward] - -* Travis should now use the master branch. [Hannah Ward] - -* Maybe it'll take the git repo now? [Hannah Ward] - -* Added pymisp to reqs. [Hannah Ward] - -* Don't cache anything pls travis. [Hannah Ward] - -* Removed unneeded modules. [Hannah Ward] - -* Use SpooledTemp, not NamedTemp file. [Hannah Ward] - -* VMRay import module added. [Alexandre Dulaunoy] - -* Merge pull request #72 from FloatingGhost/master. [Raphaël Vinot] - - Migrated stiximport to use misp-stix-converter - -* Moved to misp_stix_converter. [Hannah Ward] - -* Merge pull request #70 from cudeso/master. [Raphaël Vinot] - - Submit malware samples - -* Extra VTI detections. [Koen Van Impe] - -* Submit malware samples. [Koen Van Impe] - - _submit now includes malware samples (zipped content from misp) - _import checks when no vti_results are returned + bugfix - -* Fix STIX import module. [Raphaël Vinot] - -* Multiple clanges in the vmray modules. [Raphaël Vinot] - - * Generic fix to load modules requiring a local library - * Fix python3 support - * PEP8 related cleanups - -* Merge pull request #68 from cudeso/master. [Andras Iklody] - - VMRay Import & Submit module - -* VMRay Import & Submit module. [Koen Van Impe] - - * First commit - * No support for archives (yet) submit - -* Merge pull request #59 from rgraf/master. [Alexandre Dulaunoy] - - label replaced by text, which is existing attribute - -* Label replaced by text, which is existing attribute. [Roman Graf] - -* Adding basic test mockup. [seamus tuohy] - -* Adding more steps to module testing. [seamus tuohy] - -* Added attachment and url support. [seamus tuohy] - -* Added email meta-data import module. [seamus tuohy] - - This email meta-data import module collects basic meta-data from an e-mail - and populates an event with it. It populates the email subject, source - addresses, destination addresses, subject, and any attachment file names. - This commit also contains unit-tests for this module as well as updates to - the readme. Readme updates are additions aimed to make it easier for - outsiders to build modules. - -* Merge pull request #58 from rgraf/master. [Alexandre Dulaunoy] - - Added expansion for Wikidata. - -* Added expansion for Wikidata. Analyst can query Wikidata by label to get additional information for particular term. [Roman Graf] - -* Merge pull request #55 from amuehlem/reversedns. [Raphaël Vinot] - - added new module reversedns.py, added reversedns to __init__.py - -* Added new module reversedns.py, added reversedns to __init__.py. [Andreas Muehlemann] - -* Merge pull request #53 from MISP/Rafiot-patch-1. [Alexandre Dulaunoy] - - Dump host info as text - -* Dump host info as text. [Raphaël Vinot] - -* Fix typo. [Raphaël Vinot] - -* Merge pull request #52 from Rafiot/master. [Alexandre Dulaunoy] - - Add simple Shodan module - -* Add simple Shodan module. [Raphaël Vinot] - -* Merge pull request #49 from FloatingGhost/master. [Alexandre Dulaunoy] - - Removed useless pickle storage of stiximport - -* Removed useless pickle storage of stiximport. [Hannah Ward] - -* Create LICENSE. [Alexandre Dulaunoy] - -* Update README.md. [Andras Iklody] - -* Typo fixed. [Alexandre Dulaunoy] - -* CEF export module added. [Alexandre Dulaunoy] - -* Cef_export module added. [Alexandre Dulaunoy] - -* Merge pull request #47 from FloatingGhost/CEF_Export. [Alexandre Dulaunoy] - - CEF export, fixes in CountryCode, virustotal - -* Removed silly subdomain module. [Hannah Ward] - -* Added CEF export module. [Hannah Ward] - -* Now searches within observable_compositions. [Hannah Ward] - -* Removed calls to print. [Hannah Ward] - -* Added body.json to gitignore. [Hannah Ward] - -* Added virustotal tests. [Hannah Ward] - -* CountryCode JSON now is only grabbed once per server run. [Hannah Ward] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Raphaël Vinot] - -* Merge pull request #46 from Rafiot/master. [Raphaël Vinot] - - Make misp-modules really asynchronous - -* Add timeout for the modules, cleanup. [Raphaël Vinot] - -* Fix python 3.3 and 3.4. [Raphaël Vinot] - -* Make misp-modules really asynchronous. [Raphaël Vinot] - -* Improve tornado parallel. [Raphaël Vinot] - -* Coroutine decorator added to post handler. [Alexandre Dulaunoy] - -* -d option added - enabling debug on queried modules. [Alexandre Dulaunoy] - -* New modules added to __init__ [Alexandre Dulaunoy] - -* README updated for the new modules. [Alexandre Dulaunoy] - -* Merge pull request #45 from FloatingGhost/master. [Alexandre Dulaunoy] - - 2 new modules -- VirusTotal and CountryCode - -* Modified readme with virustotal/countrycode. [Hannah Ward] - -* Added virustotal module. [Hannah Ward] - -* Merge branch 'master' of https://github.com/MISP/misp-modules. [Hannah Ward] - -* Merge pull request #44 from Rafiot/travis. [Alexandre Dulaunoy] - - Add coverage, update logging - -* Add coverage, update logging. [Raphaël Vinot] - -* Merge pull request #43 from FloatingGhost/master. [Alexandre Dulaunoy] - - StixImport now uses TemporaryFile rather than a named file in /tmp - -* Improved virustotal module. [Hannah Ward] - -* Added countrycode, working on virustotal. [Hannah Ward] - -* Added lookup by country code. [Hannah Ward] - -* Merge branch 'master' of https://github.com/MISP/misp-modules. [Hannah Ward] - -* Fix a link to the STIX import module reference. [Alexandre Dulaunoy] - -* Stiximport now uses temporary files to store stix data. [Hannah Ward] - - Set max size in config, in bytes - -* Merge pull request #42 from MISP/pr/41. [Alexandre Dulaunoy] - - Cleanup on the stix import module - -* Merge remote-tracking branch 'origin/master' into pr/41. [Raphaël Vinot] - -* Add info about the import modules. [Alexandre Dulaunoy] - -* Make PEP8 happy \o/ [Raphaël Vinot] - -* Move stiximport.py to misp_modules/modules/import_mod/ [Raphaël Vinot] - -* There was a missing comma. [Hannah Ward] - -* Merge branch 'master' of https://github.com/MISP/misp-modules. [Hannah Ward] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Alexandre Dulaunoy] - -* Merge pull request #40 from Rafiot/master. [Alexandre Dulaunoy] - - Remove bin script, use cleaner way. Fix last commit. - -* Remove bin script, use cleaner way. Fix last commit. [Raphaël Vinot] - -* Merge pull request #39 from Rafiot/master. [Alexandre Dulaunoy] - - Use entry_points instead of scripts in the install. - -* Use entry_points instead of scripts. [Raphaël Vinot] - -* Pip --upgrade must be always called (to have modules updated) [Alexandre Dulaunoy] - -* Added STIX to setup.py. [Hannah Ward] - -* Added STIX to reqs. [Hannah Ward] - -* Merge branch 'stix_import' [Hannah Ward] - -* Added tests, also disregards related_observables. Because they're useless. [Hannah Ward] - -* Fixed observables within an indicator not being added. [Hannah Ward] - -* Stiximport will now consume campaigns. [Hannah Ward] - -* Stiximport will now identify file hashes. [Hannah Ward] - -* I can't spell. [Hannah Ward] - -* Added STIXImport to readme. [Hannah Ward] - -* Threat actors now get imported by stix. [Hannah Ward] - -* Added docs to stiximport. [Hannah Ward] - -* Added stix import -- works for IPs/Domains. [Hannah Ward] - -* Update to the DNS module to support domain|ip. [iglocska] - -* Small change to the skeleton export. [iglocska] - -* Merge remote-tracking branch 'origin/import-test' [iglocska] - -* Added test export module. [Iglocska] - -* Merge branch 'master' of github.com:MISP/misp-modules. [Alexandre Dulaunoy] - -* Merge pull request #37 from Rafiot/master. [Raphaël Vinot] - - Update documentation. - -* Update documentation. [Raphaël Vinot] - - Fix https://github.com/MISP/MISP/issues/1424 - -* Merge branch 'import-test' of github.com:MISP/misp-modules into import-test. [Alexandre Dulaunoy] - -* Merge pull request #36 from Rafiot/import-test. [Alexandre Dulaunoy] - - Pass the server port as integer to the uwhois client - -* Pass the server port as integer to the uwhois client. [Raphaël Vinot] - -* Merge pull request #35 from Rafiot/import-test. [Alexandre Dulaunoy] - - Add whois module - -* Add whois module. [Raphaël Vinot] - -* First version of an Optical Character Recognition (OCR) module for MISP. [Alexandre Dulaunoy] - -* First version of the import skeleton. [Iglocska] - -* Added simple import skeleton. [Iglocska] - -* Merge pull request #33 from Rafiot/master. [Raphaël Vinot] - - fix: run the server as "python3 misp-modules" - -* Added category to the return format description. [Iglocska] - -* Merge pull request #31 from treyka/patch-1. [Alexandre Dulaunoy] - - Refine the installation procedure - -* Refine the installation procedure. [Trey Darley] - - Tweak this to make it more inline with the MISP installation docs, start misp-modules at startup via /etc/rc.local - -* Install documentation updated. [Alexandre Dulaunoy] - -* Merge pull request #28 from Rafiot/pip. [Alexandre Dulaunoy] - - Make it a package - -* Also run travis tests on the system-wide instance. [Raphaël Vinot] - -* Fix typos in the readme. [Raphaël Vinot] - -* Fix travis. [Raphaël Vinot] - -* Make sure misp-modules can be launched from anywhere. [Raphaël Vinot] - -* Proper testcases. [Raphaël Vinot] - -* Make it a package. [Raphaël Vinot] - -* Merge pull request #29 from iglocska/master. [Alexandre Dulaunoy] - - Added skeleton structure for new modules - -* Added skeleton structure for new modules. [Iglocska] - -* Fixed a bug introduced by previous commit if started from the current directory. [Alexandre Dulaunoy] - -* Merge pull request #26 from Rafiot/master. [Alexandre Dulaunoy] - - Automatic chdir when the modules are started - -* Automatic chdir when the modules are started. [Raphaël Vinot] - -* Merge pull request #25 from eu-pi/eupi_expansion_fix. [Alexandre Dulaunoy] - - [EUPI] Fix expansion for empty EUPI response - -* [EUPI] Fix expansion for empty EUPI response. [Rogdham] - - Offer no enrichment instead of displaying an error message - -* Merge pull request #24 from eu-pi/eupi_hover. [Alexandre Dulaunoy] - - [EUPI] Change module for a simple hover status - -* [EUPI] Simplify hover. [Rogdham] - -* Merge pull request #23 from Rafiot/master. [Raphaël Vinot] - - [EUPI] Return error message if unknown - -* [EUPI] Return error message is unknown. [Raphaël Vinot] - -* Merge pull request #22 from Rafiot/master. [Raphaël Vinot] - - [EUPI] Do not return empty results - -* [EUPI] Do not return empty results. [Raphaël Vinot] - -* ASN History added. [Alexandre Dulaunoy] - -* Merge pull request #21 from Rafiot/master. [Raphaël Vinot] - - [ASN description] Fix input type - -* [ASN description] Fix input type. [Raphaël Vinot] - -* Merge pull request #20 from Rafiot/master. [Raphaël Vinot] - - Add ASN Description expansion module - -* Add ASN Description expansion module. [Raphaël Vinot] - -* Merge pull request #19 from Rafiot/master. [Raphaël Vinot] - - Fix last commit - -* Fix last commit. [Raphaël Vinot] - -* Merge pull request #18 from Rafiot/master. [Raphaël Vinot] - - Improve rendering of IP ASN - -* Improve rendering of IP ASN. [Raphaël Vinot] - -* Merge pull request #17 from Rafiot/master. [Raphaël Vinot] - - Fix again IPASN module - -* Fix again IPASN module. [Raphaël Vinot] - -* Merge pull request #16 from Rafiot/master. [Raphaël Vinot] - - Fix IPASN module - -* Fix IPASN module. [Raphaël Vinot] - -* Ipasn module added. [Alexandre Dulaunoy] - -* Merge pull request #15 from Rafiot/master. [Alexandre Dulaunoy] - - Add IPASN history module - -* Add IPASN history module. [Raphaël Vinot] - -* Merge pull request #14 from eu-pi/listen-addr. [Alexandre Dulaunoy] - - Add option to specify listen address - -* Add option to specify listen address. [Rogdham] - -* EUPI module added. [Alexandre Dulaunoy] - -* Merge pull request #13 from Rafiot/master. [Raphaël Vinot] - - Fix eupi module - -* Fix eupi module. [Raphaël Vinot] - -* Merge pull request #12 from Rafiot/master. [Raphaël Vinot] - - Add EUPI module - -* Add redis server. [Raphaël Vinot] - -* Add EUPI module. [Raphaël Vinot] - -* Skip modules that cannot import. [Alexandre Dulaunoy] - -* Skip dot files. [Alexandre Dulaunoy] - -* Value is not required. [Alexandre Dulaunoy] - -* Cache helper added. [Alexandre Dulaunoy] - - The cache helper is a simple helper to cache data - in Redis back-end. The format in the cache is the following: - m::sha1(key) -> value. Default expiration is 86400 seconds. - -* Skeleton for misp-modules helpers added. [Alexandre Dulaunoy] - - Helpers will support modules with basic functionalities - like caching or alike. - -* Option -p added to specify the TCP port of the misp-modules server. [Alexandre Dulaunoy] - -* Intelmq req. removed. [Alexandre Dulaunoy] - -* Argparse used for the test mode. [Alexandre Dulaunoy] - -* Deleted. [Alexandre Dulaunoy] - -* Intelmq is an experimental module (not production ready) [Alexandre Dulaunoy] - -* Merge pull request #11 from Rafiot/master. [Raphaël Vinot] - - Fix test mode - -* Fix test mode. [Raphaël Vinot] - -* Fix install commands. [Raphaël Vinot] - -* Add Travis logo. [Raphaël Vinot] - -* Merge pull request #10 from Rafiot/travis. [Raphaël Vinot] - - Add basic travis file - -* Add basic travis file. [Raphaël Vinot] - -* Merge pull request #9 from Rafiot/master. [Alexandre Dulaunoy] - - Please PEP8 on all expansions - -* Merge branch 'master' of https://github.com/MISP/misp-modules. [Raphaël Vinot] - -* Merge pull request #8 from aaronkaplan/master. [Alexandre Dulaunoy] - - initial example of intelmq connector/enrichtment. Need to change to u… - -* Initial example of intelmq connector/enrichtment. Need to change to use the eventDB RESTful API, not the postgresql DB. [aaronkaplan] - -* Update README.md. [Raphaël Vinot] - -* Dns module test with option added. [Alexandre Dulaunoy] - -* New modules added. [Alexandre Dulaunoy] - -* Dns MISP module - option to specify nameserver added. [Alexandre Dulaunoy] - -* Slides reference added. [Alexandre Dulaunoy] - -* Add missing requirements. [Alexandre Dulaunoy] - -* Merge pull request #7 from Rafiot/master. [Alexandre Dulaunoy] - - Make loader more flexible - -* Make PEP8 happy. [Raphaël Vinot] - -* Add CIRCL pssl module. [Raphaël Vinot] - -* Make loader more flexible. [Raphaël Vinot] - -* First module to test the freetext import functionality. [Alexandre Dulaunoy] - -* CIRCL Passive DNS output attributes updated. [Alexandre Dulaunoy] - -* PyPDNS requirement added. [Alexandre Dulaunoy] - -* CIRCL Passive DNS added. [Alexandre Dulaunoy] - -* Tests updated to include CIRCL passive dns. [Alexandre Dulaunoy] - -* Test file for passivetotal updated. [Alexandre Dulaunoy] - -* Merge pull request #5 from passivetotal/master. [Alexandre Dulaunoy] - - Rewrote the entire PassiveTotal extension - -* Rewrote the entire PassiveTotal extension. [Brandon Dixon] - -* Return a text attribute for an hover only module. [Alexandre Dulaunoy] - -* How to start MISP modules. [Alexandre Dulaunoy] - -* 2.4.28 includes misp modules by default. [Alexandre Dulaunoy] - -* Types are now described. [Alexandre Dulaunoy] - -* Debug removed. [Alexandre Dulaunoy] - -* Convert the base64 to ascii. [Iglocska] - -* Module-type added as default. [Alexandre Dulaunoy] - -* Return base64 value of the archived data. [Alexandre Dulaunoy] - -* Merge pull request #2 from iglocska/master. [Alexandre Dulaunoy] - - Some changes to the sourcecache expansion - -* Merge branch 'alternate_response' [Iglocska] - -* Some changes to the sourcecache expansion. [Iglocska] - - - return attachment or malware sample - -* Cve module tests added. [Alexandre Dulaunoy] - -* CVE hover expansion module. [Alexandre Dulaunoy] - - An hover module is a module returning a JSON that can be used - as hover element in the MISP UI. - -* Sourcecache module includes the metadata config. [Alexandre Dulaunoy] - -* README updated to reflect config parameters changes. [Alexandre Dulaunoy] - -* Removed unused attributes. [Alexandre Dulaunoy] - -* Sample JSON files reflecting config changes. [Alexandre Dulaunoy] - -* Config parameters are now exposed via the meta information. [Alexandre Dulaunoy] - - config uses a specific list of values exposed via the - introspection of the module. config is now passed as an additional - dictionary to the request. MISP attributes include only MISP attributes. - -* Sourcecache module added. [Alexandre Dulaunoy] - -* A minimal caching module added to cache link or url from MISP. [Alexandre Dulaunoy] - -* Typo fixed + meta output. [Alexandre Dulaunoy] - -* Minimal functions requirements updated + PR request. [Alexandre Dulaunoy] - -* Exclude dot files from modules list to be loaded. [Alexandre Dulaunoy] - -* Example of module introspection including meta information. [Alexandre Dulaunoy] - -* Module meta added to return version, description and author per module. [Alexandre Dulaunoy] - -* Authentication notes added. [Alexandre Dulaunoy] - -* Passivetotal module added. [Alexandre Dulaunoy] - -* First version of a passivetotal MISP expansion module. [Alexandre Dulaunoy] - -* Default DNS updated. [Alexandre Dulaunoy] - -* Add a note regarding error codes. [Alexandre Dulaunoy] - -* Handling of error added. [Alexandre Dulaunoy] - -* Merge pull request #1 from Rafiot/master. [Alexandre Dulaunoy] - - Make PEP8 happy. - -* Make PEP8 happy. [Raphaël Vinot] - -* Output updated (type of module added) [Alexandre Dulaunoy] - -* Add a version per default. [Alexandre Dulaunoy] - -* Add type per module. [Alexandre Dulaunoy] - -* Format updated following Andras updates. [Alexandre Dulaunoy] - -* Default var directory added. [Alexandre Dulaunoy] - -* Python pip REQUIREMENTS file added. [Alexandre Dulaunoy] - -* Merge branch 'master' of https://github.com/MISP/misp-modules. [Iglocska] - -* Minimal logging added to the server. [Alexandre Dulaunoy] - -* Debug messages removed. [Alexandre Dulaunoy] - -* Minimal documentation added. [Alexandre Dulaunoy] - -* Curl is now silent. [Alexandre Dulaunoy] - -* Changed the output format to include all matching attribute types. [Iglocska] - - - changed the output format to give us a bit more flexibility - - return an array of results - - return the valid misp attribute types for each result - -* Basic test cases added. [Alexandre Dulaunoy] - -* MISP dns expansion module. [Alexandre Dulaunoy] - -* First version of a web services to provide ReST API to MISP expansion services. [Alexandre Dulaunoy] - - diff --git a/DOC-REQUIREMENTS b/DOC-REQUIREMENTS deleted file mode 100644 index 8373cb71..00000000 --- a/DOC-REQUIREMENTS +++ /dev/null @@ -1,3 +0,0 @@ -mkdocs -pymdown-extensions -mkdocs-material diff --git a/Makefile b/Makefile index b37670ef..e1a08f01 100644 --- a/Makefile +++ b/Makefile @@ -1,37 +1,63 @@ -# https://www.mkdocs.org/user-guide/deploying-your-docs/ +# See: https://www.mkdocs.org/user-guide/deploying-your-docs/ +# Running 'make' uses poetry-installed mkdocs +# Running 'USE_DOCKER=true make' uses docker mkdocs + +.PHONY: prepare_docs generate_docs deploy test_docs + +MKDOCS_DOCKER_IMAGE := squidfunk/mkdocs-material + +DOCS_DIST_DIR := ./docs + +DOCS_SRC_DIR := ./documentation + +USE_DOCKER ?= + +.DEFAULT_GOAL := generate_docs -.PHONY: prepare_docs generate_docs ci_generate_docs test_docs prepare_docs: - cd documentation; python3 generate_documentation.py - mkdir -p docs/expansion/logos docs/export_mod/logos docs/import_mod/logos - mkdir -p docs/logos - cd documentation; cp -R ./logos/* ../docs/logos - cd documentation; cp -R ./logos/* ../docs/expansion/logos - cd documentation; cp -R ./logos/* ../docs/export_mod/logos - cd documentation; cp -R ./logos/* ../docs/import_mod/logos - cp ./documentation/mkdocs/*.md ./docs - cp LICENSE ./docs/license.md + @echo "Preparing documentation." + poetry install --with docs,unstable + poetry run python $(DOCS_SRC_DIR)/generate_documentation.py + mkdir -p $(DOCS_DIST_DIR)/logos + mkdir -p $(DOCS_DIST_DIR)/img + mkdir -p $(DOCS_DIST_DIR)/expansion/logos + mkdir -p $(DOCS_DIST_DIR)/export_mod/logos + mkdir -p $(DOCS_DIST_DIR)/import_mod/logos + cp -R $(DOCS_SRC_DIR)/logos/* $(DOCS_DIST_DIR)/logos + cp -R $(DOCS_SRC_DIR)/img/* $(DOCS_DIST_DIR)/img + cp -R $(DOCS_SRC_DIR)/logos/* $(DOCS_DIST_DIR)/expansion/logos + cp -R $(DOCS_SRC_DIR)/logos/* $(DOCS_DIST_DIR)/export_mod/logos + cp -R $(DOCS_SRC_DIR)/logos/* $(DOCS_DIST_DIR)/import_mod/logos + cp $(DOCS_SRC_DIR)/mkdocs/*.md $(DOCS_DIST_DIR) + cp LICENSE $(DOCS_DIST_DIR)/license.md -install_requirements: - pip install -r docs/REQUIREMENTS.txt generate_docs: prepare_docs - mkdocs build +ifeq ($(USE_DOCKER), true) + @echo "Generating documentation using '$(MKDOCS_DOCKER_IMAGE)'." + docker run --rm -it -v $(PWD):/docs $(MKDOCS_DOCKER_IMAGE) build +else + @echo "Generating docunentation." + poetry run mkdocs build +endif + + +deploy: generate_docs +ifeq ($(USE_DOCKER), true) + @echo "Deploying documentation using '$(MKDOCS_DOCKER_IMAGE)'." + docker run --rm -it -v $(PWD):/docs -v /home/$(whoami)/.docker:/root/.docker:ro $(MKDOCS_DOCKER_IMAGE) gh-deploy +else + @echo "Deploying docunentation." + poetry run mkdocs gh-deploy +endif -deploy: - mkdocs gh-deploy test_docs: prepare_docs - mkdocs serve - - -# DOCKER make commands -generate_docs_docker: prepare_docs - docker run --rm -it -v $(PWD):/docs squidfunk/mkdocs-material build - -deploy_docker: - docker run --rm -it -v $(PWD):/docs -v /home/$(whoami)/.docker:/root/.docker:ro squidfunk/mkdocs-material gh-deploy - -test_docs_docker: prepare_docs - docker run --rm -it -p 8000:8000 -v $(PWD):/docs squidfunk/mkdocs-material +ifeq ($(USE_DOCKER), true) + @echo "Serving documentation using '$(MKDOCS_DOCKER_IMAGE)'." + docker run --rm -it -v $(PWD):/docs -p 8000:8000 $(MKDOCS_DOCKER_IMAGE) +else + @echo "Serving docunentation." + poetry run mkdocs serve +endif diff --git a/Pipfile b/Pipfile deleted file mode 100644 index acd49273..00000000 --- a/Pipfile +++ /dev/null @@ -1,82 +0,0 @@ -[[source]] -name = "pypi" -url = "https://pypi.org/simple" -verify_ssl = true - -[dev-packages] -nose = "*" -codecov = "*" -pytest = "*" -flake8 = "*" - -[packages] -dnspython = "*" -requests = { extras = ["security"], version = "*" } -urlarchiver = "*" -passivetotal = "*" -pypdns = "*" -pypssl = "*" -pyeupi = "*" -pymisp = { extras = ["fileobjects,openioc,pdfexport,email,url"], version = "*" } -pyonyphe = { git = "https://github.com/sebdraven/pyonyphe" } -pydnstrails = { git = "https://github.com/sebdraven/pydnstrails" } -pytesseract = "*" -pygeoip = "*" -beautifulsoup4 = "*" -oauth2 = "*" -yara-python = "==3.8.1" -sigmatools = "*" -stix2 = "*" -stix2-patterns = "*" -taxii2-client = "*" -maclookup = "*" -vulners = "*" -blockchain = "*" -reportlab = "*" -pyintel471 = { git = "https://github.com/MISP/PyIntel471.git" } -shodan = "*" -Pillow = ">=8.2.0" -Wand = "*" -SPARQLWrapper = "*" -domaintools_api = "*" -misp-modules = { path = "." } -pybgpranking = { git = "https://github.com/D4-project/BGP-Ranking.git/", subdirectory = "client", ref = "68de39f6c5196f796055c1ac34504054d688aa59" } -pyipasnhistory = { git = "https://github.com/D4-project/IPASN-History.git/", subdirectory = "client", ref = "a2853c39265cecdd0c0d16850bd34621c0551b87" } -backscatter = "*" -pyzbar = "*" -opencv-python = "*" -np = "*" -ODTReader = { git = "https://github.com/cartertemm/ODTReader.git/" } -python-pptx = "*" -python-docx = "*" -ezodf = "*" -pandas = "==1.3.5" -pandas_ods_reader = "==0.1.2" -pdftotext = "*" -lxml = "*" -xlrd = "*" -jbxapi = "*" -geoip2 = "*" -apiosintDS = "*" -assemblyline_client = "*" -vt-graph-api = "*" -trustar = { git = "https://github.com/SteveClement/trustar-python.git" } -markdownify = "==0.5.3" -socialscan = "==1.4" -pycountry = "==22.3.5" -dnsdb2 = "*" -clamd = "*" -aiohttp = ">=3.7.4" -tau-clients = "*" -vt-py = ">=0.7.1" -crowdstrike-falconpy = "0.9.0" -censys = "2.0.9" -mwdblib = "3.4.1" -ndjson = "0.3.1" -Jinja2 = "3.1.2" -mattermostdriver = "7.3.2" -openpyxl = "*" -slack-sdk = "3.27.1" - -[requires] -python_version = "3.7" diff --git a/README.md b/README.md index dcba72a4..a12879da 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MISP modules -[![Python package](https://github.com/MISP/misp-modules/actions/workflows/python-package.yml/badge.svg)](https://github.com/MISP/misp-modules/actions/workflows/python-package.yml)[![Coverage Status](https://coveralls.io/repos/github/MISP/misp-modules/badge.svg?branch=main)](https://coveralls.io/github/MISP/misp-modules?branch=main) +[![Build status](https://github.com/MISP/misp-modules/actions/workflows/test-package.yml/badge.svg)](https://github.com/MISP/misp-modules/actions/workflows/test-package.yml)[![Coverage Status](https://coveralls.io/repos/github/MISP/misp-modules/badge.svg?branch=main)](https://coveralls.io/github/MISP/misp-modules?branch=main) [![codecov](https://codecov.io/gh/MISP/misp-modules/branch/main/graph/badge.svg)](https://codecov.io/gh/MISP/misp-modules) MISP modules are autonomous modules that can be used to extend [MISP](https://github.com/MISP/MISP) for new services such as expansion, import, export and workflow action. @@ -12,575 +12,16 @@ without modifying core components. The API is available via a simple REST API wh For more information: [Extending MISP with Python modules](https://www.misp-project.org/misp-training/3.1-misp-modules.pdf) slides from [MISP training](https://github.com/MISP/misp-training). -## Existing MISP modules +# Installation +Installation instructions can be found in the [installation documentation](https://misp.github.io/misp-modules/install/). -### Expansion modules -* [apiosintDS](misp_modules/modules/expansion/apiosintds.py) - a hover and expansion module to query the [OSINT.digitalside.it](https://osint.digitalside.it) API. [Documentation](https://apiosintds.readthedocs.io/en/latest/userguidemisp.html). -* [API Void](misp_modules/modules/expansion/apivoid.py) - an expansion and hover module to query API Void with a domain attribute. -* [AssemblyLine submit](misp_modules/modules/expansion/assemblyline_submit.py) - an expansion module to submit samples and urls to AssemblyLine. -* [AssemblyLine query](misp_modules/modules/expansion/assemblyline_query.py) - an expansion module to query AssemblyLine and parse the full submission report. -* [Backscatter.io](misp_modules/modules/expansion/backscatter_io.py) - a hover and expansion module to expand an IP address with mass-scanning observations. -* [BGP Ranking](misp_modules/modules/expansion/bgpranking.py) - a hover and expansion module to expand an AS number with the ASN description and its ranking and position in BGP Ranking. -* [RansomcoinDB check](misp_modules/modules/expansion/ransomcoindb.py) - An expansion hover module to query the [ransomcoinDB](https://ransomcoindb.concinnity-risks.com): it contains mapping between BTC addresses and malware hashes. Enrich MISP by querying for BTC -> hash or hash -> BTC addresses. -* [BTC scam check](misp_modules/modules/expansion/btc_scam_check.py) - An expansion hover module to instantly check if a BTC address has been abused. -* [BTC transactions](misp_modules/modules/expansion/btc_steroids.py) - An expansion hover module to get a blockchain balance and the transactions from a BTC address in MISP. -* [Censys-enrich](misp_modules/modules/expansion/censys_enrich.py) - An expansion and module to retrieve information from censys.io about a particular IP or certificate. -* [CIRCL Passive DNS](misp_modules/modules/expansion/circl_passivedns.py) - a hover and expansion module to expand hostname and IP addresses with passive DNS information. -* [CIRCL Passive SSL](misp_modules/modules/expansion/circl_passivessl.py) - a hover and expansion module to expand IP addresses with the X.509 certificate(s) seen. -* [countrycode](misp_modules/modules/expansion/countrycode.py) - a hover module to tell you what country a URL belongs to. -* [CrowdSec](misp_modules/modules/expansion/crowdsec.py) - a hover module to expand using CrowdSec's CTI API. -* [CrowdStrike Falcon](misp_modules/modules/expansion/crowdstrike_falcon.py) - an expansion module to expand using CrowdStrike Falcon Intel Indicator API. -* [CPE](misp_modules/modules/expansion/cpe.py) - An expansion module to query the CVE Search API with a cpe code, to get its related vulnerabilities. -* [CVE](misp_modules/modules/expansion/cve.py) - a hover module to give more information about a vulnerability (CVE). -* [CVE advanced](misp_modules/modules/expansion/cve_advanced.py) - An expansion module to query the CIRCL CVE search API for more information about a vulnerability (CVE). -* [Cuckoo submit](misp_modules/modules/expansion/cuckoo_submit.py) - A hover module to submit malware sample, url, attachment, domain to Cuckoo Sandbox. -* [Cytomic Orion](misp_modules/modules/expansion/cytomic_orion.py) - An expansion module to enrich attributes in MISP and share indicators of compromise with Cytomic Orion. -* [DBL Spamhaus](misp_modules/modules/expansion/dbl_spamhaus.py) - a hover module to check Spamhaus DBL for a domain name. -* [DNS](misp_modules/modules/expansion/dns.py) - a simple module to resolve MISP attributes like hostname and domain to expand IP addresses attributes. -* [docx-enrich](misp_modules/modules/expansion/docx_enrich.py) - an enrichment module to get text out of Word document into MISP (using free-text parser). -* [DomainTools](misp_modules/modules/expansion/domaintools.py) - a hover and expansion module to get information from [DomainTools](http://www.domaintools.com/) whois. -* [EQL](misp_modules/modules/expansion/eql.py) - an expansion module to generate event query language (EQL) from an attribute. [Event Query Language](https://eql.readthedocs.io/en/latest/) -* [EUPI](misp_modules/modules/expansion/eupi.py) - a hover and expansion module to get information about an URL from the [Phishing Initiative project](https://phishing-initiative.eu/?lang=en). -* [Farsight DNSDB Passive DNS](misp_modules/modules/expansion/farsight_passivedns.py) - a hover and expansion module to expand hostname and IP addresses with passive DNS information. -* [GeoIP](misp_modules/modules/expansion/geoip_country.py) - a hover and expansion module to get GeoIP information from geolite/maxmind. -* [GeoIP_City](misp_modules/modules/expansion/geoip_city.py) - a hover and expansion module to get GeoIP City information from geolite/maxmind. -* [GeoIP_ASN](misp_modules/modules/expansion/geoip_asn.py) - a hover and expansion module to get GeoIP ASN information from geolite/maxmind. -* [GreyNoise](misp_modules/modules/expansion/greynoise.py) - a hover and expansion module to get IP and CVE information from GreyNoise. -* [hashdd](misp_modules/modules/expansion/hashdd.py) - a hover module to check file hashes against [hashdd.com](http://www.hashdd.com) including NSLR dataset. -* [Hashlookup](misp_modules/modules/expansion/hashlookup.py) - An expansion module to enrich a file hash with hashlookup.circl.lu services (NSRL and other sources) -* [hibp](misp_modules/modules/expansion/hibp.py) - a hover module to lookup against Have I Been Pwned? -* [html_to_markdown](misp_modules/modules/expansion/html_to_markdown.py) - Simple HTML to markdown converter -* [HYAS Insight](misp_modules/modules/expansion/hyasinsight.py) - a hover and expansion module to get information from [HYAS Insight](https://www.hyas.com/hyas-insight). -* [intel471](misp_modules/modules/expansion/intel471.py) - an expansion module to get info from [Intel471](https://intel471.com). -* [IP2Location.io](misp_modules/modules/expansion/ip2locationio.py) - an expansion module to get additional information on an IP address using the IP2Location.io API -* [IPASN](misp_modules/modules/expansion/ipasn.py) - a hover and expansion to get the BGP ASN of an IP address. -* [ipinfo.io](misp_modules/modules/expansion/ipinfo.py) - an expansion module to get additional information on an IP address using the ipinfo.io API -* [iprep](misp_modules/modules/expansion/iprep.py) - an expansion module to get IP reputation from packetmail.net. -* [Joe Sandbox submit](misp_modules/modules/expansion/joesandbox_submit.py) - Submit files and URLs to Joe Sandbox. -* [Joe Sandbox query](misp_modules/modules/expansion/joesandbox_query.py) - Query Joe Sandbox with the link of an analysis and get the parsed data. -* [Lastline submit](misp_modules/modules/expansion/lastline_submit.py) - Submit files and URLs to Lastline. -* [Lastline query](misp_modules/modules/expansion/lastline_query.py) - Query Lastline with the link to an analysis and parse the report. -* [macaddress.io](misp_modules/modules/expansion/macaddress_io.py) - a hover module to retrieve vendor details and other information regarding a given MAC address or an OUI from [MAC address Vendor Lookup](https://macaddress.io). See [integration tutorial here](https://macaddress.io/integrations/MISP-module). -* [macvendors](misp_modules/modules/expansion/macvendors.py) - a hover module to retrieve mac vendor information. -* [MALWAREbazaar](misp_modules/modules/expansion/malwarebazaar.py) - an expansion module to query MALWAREbazaar with some payload. -* [McAfee MVISION Insights](misp_modules/modules/expansion/mcafee_insights_enrich.py) - an expansion module enrich IOCs with McAfee MVISION Insights. -* [Mmdb server lookup](misp_modules/modules/expansion/mmdb_lookup.py) - an expansion module to enrich an ip with geolocation information from an mmdb server such as ip.circl.lu. -* [ocr-enrich](misp_modules/modules/expansion/ocr_enrich.py) - an enrichment module to get OCRized data from images into MISP. -* [ods-enrich](misp_modules/modules/expansion/ods_enrich.py) - an enrichment module to get text out of OpenOffice spreadsheet document into MISP (using free-text parser). -* [odt-enrich](misp_modules/modules/expansion/odt_enrich.py) - an enrichment module to get text out of OpenOffice document into MISP (using free-text parser). -* [onyphe](misp_modules/modules/expansion/onyphe.py) - a modules to process queries on Onyphe. -* [onyphe_full](misp_modules/modules/expansion/onyphe_full.py) - a modules to process full queries on Onyphe. -* [OTX](misp_modules/modules/expansion/otx.py) - an expansion module for [OTX](https://otx.alienvault.com/). -* [passivetotal](misp_modules/modules/expansion/passivetotal.py) - a [passivetotal](https://www.passivetotal.org/) module that queries a number of different PassiveTotal datasets. -* [pdf-enrich](misp_modules/modules/expansion/pdf_enrich.py) - an enrichment module to extract text from PDF into MISP (using free-text parser). -* [pptx-enrich](misp_modules/modules/expansion/pptx_enrich.py) - an enrichment module to get text out of PowerPoint document into MISP (using free-text parser). -* [qrcode](misp_modules/modules/expansion/qrcode.py) - a module decode QR code, barcode and similar codes from an image and enrich with the decoded values. -* [rbl](misp_modules/modules/expansion/rbl.py) - a module to get RBL (Real-Time Blackhost List) values from an attribute. -* [recordedfuture](misp_modules/modules/expansion/recordedfuture.py) - a hover and expansion module for enriching MISP attributes with threat intelligence from Recorded Future. -* [reversedns](misp_modules/modules/expansion/reversedns.py) - Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes. -* [securitytrails](misp_modules/modules/expansion/securitytrails.py) - an expansion module for [securitytrails](https://securitytrails.com/). -* [shodan](misp_modules/modules/expansion/shodan.py) - a minimal [shodan](https://www.shodan.io/) expansion module. -* [Sigma queries](misp_modules/modules/expansion/sigma_queries.py) - Experimental expansion module querying a sigma rule to convert it into all the available SIEM signatures. -* [Sigma syntax validator](misp_modules/modules/expansion/sigma_syntax_validator.py) - Sigma syntax validator. -* [Socialscan](misp_modules/modules/expansion/socialscan.py) - a hover module to check if an email address or a username is used on different online platforms, using the [socialscan](https://github.com/iojw/socialscan) python library -* [SophosLabs Intelix](misp_modules/modules/expansion/sophoslabs_intelix.py) - SophosLabs Intelix is an API for Threat Intelligence and Analysis (free tier available). [SophosLabs](https://aws.amazon.com/marketplace/pp/B07SLZPMCS) -* [sourcecache](misp_modules/modules/expansion/sourcecache.py) - a module to cache a specific link from a MISP instance. -* [stairwell](misp_modules/modules/expansion/stairwell.py) - an expansion module to enrich hash observables with the Stairwell API -* [STIX2 pattern syntax validator](misp_modules/modules/expansion/stix2_pattern_syntax_validator.py) - a module to check a STIX2 pattern syntax. -* [ThreatCrowd](misp_modules/modules/expansion/threatcrowd.py) - an expansion module for [ThreatCrowd](https://www.threatcrowd.org/). -* [threatminer](misp_modules/modules/expansion/threatminer.py) - an expansion module to expand from [ThreatMiner](https://www.threatminer.org/). -* [TruSTAR Enrich](misp_modules/modules/expansion/trustar_enrich.py) - an expansion module to enrich MISP data with [TruSTAR](https://www.trustar.co/). -* [urlhaus](misp_modules/modules/expansion/urlhaus.py) - Query urlhaus to get additional data about a domain, hash, hostname, ip or url. -* [urlscan](misp_modules/modules/expansion/urlscan.py) - an expansion module to query [urlscan.io](https://urlscan.io). -* [variotdbs](misp_modules/modules/expansion/variotdbs.py) - an expansion module to query the [VARIoT db](https://www.variotdbs.pl) API to get more information about a Vulnerability -* [virustotal](misp_modules/modules/expansion/virustotal.py) - an expansion module to query the [VirusTotal](https://www.virustotal.com/gui/home) API with a high request rate limit required. (More details about the API: [here](https://developers.virustotal.com/reference)) -* [virustotal_public](misp_modules/modules/expansion/virustotal_public.py) - an expansion module to query the [VirusTotal](https://www.virustotal.com/gui/home) API with a public key and a low request rate limit. (More details about the API: [here](https://developers.virustotal.com/reference)) -* [VMray](misp_modules/modules/expansion/vmray_submit.py) - a module to submit a sample to VMray. -* [VMware NSX](misp_modules/modules/expansion/vmware_nsx.py) - a module to enrich a file or URL with VMware NSX Defender. -* [VulnDB](misp_modules/modules/expansion/vulndb.py) - a module to query [VulnDB](https://www.riskbasedsecurity.com/). -* [Vulners](misp_modules/modules/expansion/vulners.py) - an expansion module to expand information about CVEs using Vulners API. -* [Vysion](misp_modules/modules/expansion/vysion.py) - an expansion module to add dark web intelligence using Vysion API. -* [whois](misp_modules/modules/expansion/whois.py) - a module to query a local instance of [uwhois](https://github.com/rafiot/uwhoisd). -* [whoisfreaks](misp_modules/modules/expansion/whoisfreaks.py) - An expansion module for [whoisfreaks](https://whoisfreaks.com/) that will provide an enriched analysis of the provided domain, including WHOIS and DNS information. -* [wikidata](misp_modules/modules/expansion/wiki.py) - a [wikidata](https://www.wikidata.org) expansion module. -* [xforce](misp_modules/modules/expansion/xforceexchange.py) - an IBM X-Force Exchange expansion module. -* [xlsx-enrich](misp_modules/modules/expansion/xlsx_enrich.py) - an enrichment module to get text out of an Excel document into MISP (using free-text parser). -* [YARA query](misp_modules/modules/expansion/yara_query.py) - a module to create YARA rules from single hash attributes. -* [YARA syntax validator](misp_modules/modules/expansion/yara_syntax_validator.py) - YARA syntax validator. +# How to add your own MISP modules? +Developing a MISP module yourself is fairly easy. Start with a template or existing module and continue from there. \ +More information can be found in the [contribute](https://misp.github.io/misp-modules/contribute/) section of the documentation. -### Export modules +# Documentation -* [CEF](misp_modules/modules/export_mod/cef_export.py) - module to export Common Event Format (CEF). -* [Cisco FireSight Manager ACL rule](misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py) - module to export as rule for the Cisco FireSight manager ACL. -* [GoAML export](misp_modules/modules/export_mod/goamlexport.py) - module to export in [GoAML format](http://goaml.unodc.org/goaml/en/index.html). -* [Lite Export](misp_modules/modules/export_mod/liteexport.py) - module to export a lite event. -* [PDF export](misp_modules/modules/export_mod/pdfexport.py) - module to export an event in PDF. -* [Mass EQL Export](misp_modules/modules/export_mod/mass_eql_export.py) - module to export applicable attributes from an event to a mass EQL query. -* [Nexthink query format](misp_modules/modules/export_mod/nexthinkexport.py) - module to export in Nexthink query format. -* [osquery](misp_modules/modules/export_mod/osqueryexport.py) - module to export in [osquery](https://osquery.io/) query format. -* [ThreatConnect](misp_modules/modules/export_mod/threat_connect_export.py) - module to export in ThreatConnect CSV format. -* [ThreatStream](misp_modules/modules/export_mod/threatStream_misp_export.py) - module to export in ThreatStream format. -* [VirusTotal Graph](misp_modules/modules/export_mod/vt_graph.py) - Module to create a VirusTotal graph out of an event. - -### Import modules - -* [CSV import](misp_modules/modules/import_mod/csvimport.py) - Customizable CSV import module. -* [Cuckoo JSON](misp_modules/modules/import_mod/cuckooimport.py) - Cuckoo JSON import. -* [Email Import](misp_modules/modules/import_mod/email_import.py) - Email import module for MISP to import basic metadata. -* [GoAML import](misp_modules/modules/import_mod/goamlimport.py) - Module to import [GoAML](http://goaml.unodc.org/goaml/en/index.html) XML format. -* [Joe Sandbox import](misp_modules/modules/import_mod/joe_import.py) - Parse data from a Joe Sandbox json report. -* [Lastline import](misp_modules/modules/import_mod/lastline_import.py) - Module to import Lastline analysis reports. -* [OCR](misp_modules/modules/import_mod/ocr.py) - Optical Character Recognition (OCR) module for MISP to import attributes from images, scan or faxes. -* [OpenIOC](misp_modules/modules/import_mod/openiocimport.py) - OpenIOC import based on PyMISP library. -* [ThreatAnalyzer](misp_modules/modules/import_mod/threatanalyzer_import.py) - An import module to process ThreatAnalyzer archive.zip/analysis.json sandbox exports. -* [VMRay](misp_modules/modules/import_mod/vmray_import.py) - An import module to process VMRay export. - -## How to install and start MISP modules in a Python virtualenv? (recommended) - -***Be sure to run the latest version of `pip`***. To install the latest version of pip, `pip install --upgrade pip` will do the job. - -~~~~bash -sudo apt-get install python3-dev python3-pip libpq5 libjpeg-dev tesseract-ocr libpoppler-cpp-dev imagemagick virtualenv libopencv-dev zbar-tools libzbar0 libzbar-dev libfuzzy-dev build-essential -y -sudo -u www-data virtualenv -p python3 /var/www/MISP/venv -cd /usr/local/src/ -sudo chown -R www-data: . -sudo -u www-data git clone https://github.com/MISP/misp-modules.git -cd misp-modules -sudo -u www-data /var/www/MISP/venv/bin/pip install -I -r REQUIREMENTS -sudo -u www-data /var/www/MISP/venv/bin/pip install . -# Start misp-modules as a service -sudo cp etc/systemd/system/misp-modules.service /etc/systemd/system/ -sudo systemctl daemon-reload -sudo systemctl enable --now misp-modules -sudo service misp-modules start #or -/var/www/MISP/venv/bin/misp-modules -l 127.0.0.1 & #to start the modules -~~~~ - -## How to install and start MISP modules on RHEL-based distributions ? -As of this writing, the official RHEL repositories only contain Ruby 2.0.0 and Ruby 2.1 or higher is required. As such, this guide installs Ruby 2.2 from the [SCL](https://access.redhat.com/documentation/en-us/red_hat_software_collections/3/html/3.2_release_notes/chap-installation#sect-Installation-Subscribe) repository. - -~~~~bash -sudo yum install rh-python36 rh-ruby22 -sudo yum install openjpeg-devel -sudo yum install rubygem-rouge rubygem-asciidoctor zbar-devel opencv-devel gcc-c++ pkgconfig poppler-cpp-devel python-devel redhat-rpm-config -cd /var/www/MISP -git clone https://github.com/MISP/misp-modules.git -cd misp-modules -sudo -u apache /usr/bin/scl enable rh-python36 "virtualenv -p python3 /var/www/MISP/venv" -sudo -u apache /var/www/MISP/venv/bin/pip install -U -I -r REQUIREMENTS -sudo -u apache /var/www/MISP/venv/bin/pip install -U . -~~~~ - -Create the service file /etc/systemd/system/misp-modules.service : -~~~~ -echo "[Unit] -Description=MISP's modules -After=misp-workers.service - -[Service] -Type=simple -User=apache -Group=apache -ExecStart=/usr/bin/scl enable rh-python36 rh-ruby22 '/var/www/MISP/venv/bin/misp-modules -l 127.0.0.1' -Restart=always -RestartSec=10 - -[Install] -WantedBy=multi-user.target" | sudo tee /etc/systemd/system/misp-modules.service -~~~~ - -The `After=misp-workers.service` must be changed or removed if you have not created a misp-workers service. -Then, enable the misp-modules service and start it: -~~~~bash -systemctl daemon-reload -systemctl enable --now misp-modules -~~~~ - -## How to add your own MISP modules? - -Create your module in [misp_modules/modules/expansion/](misp_modules/modules/expansion/), [misp_modules/modules/export_mod/](misp_modules/modules/export_mod/), or [misp_modules/modules/import_mod/](misp_modules/modules/import_mod/). The module should have at minimum three functions: - -* **introspection** function that returns a dict of the supported attributes (input and output) by your expansion module. -* **handler** function which accepts a JSON document to expand the values and return a dictionary of the expanded values. -* **version** function that returns a dict with the version and the associated meta-data including potential configurations required of the module. - -Don't forget to return an error key and value if an error is raised to propagate it to the MISP user-interface. - -Your module's script name should also be added in the `__all__` list of `/__init__.py` in order for it to be loaded. - -~~~python -... - # Checking for required value - if not request.get('ip-src'): - # Return an error message - return {'error': "A source IP is required"} -... -~~~ - - -### introspection - -The function that returns a dict of the supported attributes (input and output) by your expansion module. - -~~~python -mispattributes = {'input': ['link', 'url'], - 'output': ['attachment', 'malware-sample']} - -def introspection(): - return mispattributes -~~~ - -### version - -The function that returns a dict with the version and the associated meta-data including potential configurations required of the module. - - -### Additional Configuration Values - -If your module requires additional configuration (to be exposed via the MISP user-interface), you can define those in the moduleconfig value returned by the version function. - -~~~python -# config fields that your code expects from the site admin -moduleconfig = ["apikey", "event_limit"] - -def version(): - moduleinfo['config'] = moduleconfig - return moduleinfo -~~~ - - -When you do this a config array is added to the meta-data output containing all the potential configuration values: - -~~~ -"meta": { - "description": "PassiveTotal expansion service to expand values with multiple Passive DNS sources", - "config": [ - "username", - "password" - ], - "module-type": [ - "expansion", - "hover" - ], - -... -~~~ - - -If you want to use the configuration values set in the web interface they are stored in the key `config` in the JSON object passed to the handler. - -~~~ -def handler(q=False): - - # Check if we were given a configuration - config = q.get("config", {}) - - # Find out if there is a username field - username = config.get("username", None) -~~~ - - -### handler - -The function which accepts a JSON document to expand the values and return a dictionary of the expanded values. - -~~~python -def handler(q=False): - "Fully functional rot-13 encoder" - if q is False: - return False - request = json.loads(q) - src = request.get('ip-src') - if src is None: - # Return an error message - return {'error': "A source IP is required"} - else: - return {'results': - codecs.encode(src, "rot-13")} -~~~ - -#### export module - -For an export module, the `request["data"]` object corresponds to a list of events (dictionaries) to handle. - -Iterating over events attributes is performed using their `Attribute` key. - -~~~python -... -for event in request["data"]: - for attribute in event["Attribute"]: - # do stuff w/ attribute['type'], attribute['value'], ... -... - -### Returning Binary Data - -If you want to return a file or other data you need to add a data attribute. - -~~~python -{"results": {"values": "filename.txt", - "types": "attachment", - "data" : base64.b64encode() # base64 encode your data first - "comment": "This is an attachment"}} -~~~ - -If the binary file is malware you can use 'malware-sample' as the type. If you do this the malware sample will be automatically zipped and password protected ('infected') after being uploaded. - - -~~~python -{"results": {"values": "filename.txt", - "types": "malware-sample", - "data" : base64.b64encode() # base64 encode your data first - "comment": "This is an attachment"}} -~~~ - -[To learn more about how data attributes are processed you can read the processing code here.](https://github.com/MISP/PyMISP/blob/4f230c9299ad9d2d1c851148c629b61a94f3f117/pymisp/mispevent.py#L185-L200) - - -### Module type - -A MISP module can be of four types: - -- **expansion** - service related to an attribute that can be used to extend and update an existing event. -- **hover** - service related to an attribute to provide additional information to the users without updating the event. -- **import** - service related to importing and parsing an external object that can be used to extend an existing event. -- **export** - service related to exporting an object, event, or data. - -module-type is an array where the list of supported types can be added. - -## Testing your modules? - -MISP uses the **modules** function to discover the available MISP modules and their supported MISP attributes: - -~~~ -% curl -s http://127.0.0.1:6666/modules | jq . -[ - { - "name": "passivetotal", - "type": "expansion", - "mispattributes": { - "input": [ - "hostname", - "domain", - "ip-src", - "ip-dst" - ], - "output": [ - "ip-src", - "ip-dst", - "hostname", - "domain" - ] - }, - "meta": { - "description": "PassiveTotal expansion service to expand values with multiple Passive DNS sources", - "config": [ - "username", - "password" - ], - "author": "Alexandre Dulaunoy", - "version": "0.1" - } - }, - { - "name": "sourcecache", - "type": "expansion", - "mispattributes": { - "input": [ - "link" - ], - "output": [ - "link" - ] - }, - "meta": { - "description": "Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page.", - "author": "Alexandre Dulaunoy", - "version": "0.1" - } - }, - { - "name": "dns", - "type": "expansion", - "mispattributes": { - "input": [ - "hostname", - "domain" - ], - "output": [ - "ip-src", - "ip-dst" - ] - }, - "meta": { - "description": "Simple DNS expansion service to resolve IP address from MISP attributes", - "author": "Alexandre Dulaunoy", - "version": "0.1" - } - } -] - -~~~ - -The MISP module service returns the available modules in a JSON array containing each module name along with their supported input attributes. - -Based on this information, a query can be built in a JSON format and saved as body.json: - -~~~json -{ - "hostname": "www.foo.be", - "module": "dns" -} -~~~ - -Then you can POST this JSON format query towards the MISP object server: - -~~~bash -curl -s http://127.0.0.1:6666/query -H "Content-Type: application/json" --data @body.json -X POST -~~~ - -The module should output the following JSON: - -~~~json -{ - "results": [ - { - "types": [ - "ip-src", - "ip-dst" - ], - "values": [ - "188.65.217.78" - ] - } - ] -} -~~~ - -It is also possible to restrict the category options of the resolved attributes by passing a list of categories along (optional): - -~~~json -{ - "results": [ - { - "types": [ - "ip-src", - "ip-dst" - ], - "values": [ - "188.65.217.78" - ], - "categories": [ - "Network activity", - "Payload delivery" - ] - } - ] -} -~~~ - -For both the type and the category lists, the first item in the list will be the default setting on the interface. - -### Enable your module in the web interface - -For a module to be activated in the MISP web interface it must be enabled in the "Plugin Settings. - -Go to "Administration > Server Settings" in the top menu -- Go to "Plugin Settings" in the top "tab menu bar" -- Click on the name of the type of module you have created to expand the list of plugins to show your module. -- Find the name of your plugin's "enabled" value in the Setting Column. -"Plugin.[MODULE NAME]_enabled" -- Double click on its "Value" column - -~~~ -Priority Setting Value Description Error Message -Recommended Plugin.Import_ocr_enabled false Enable or disable the ocr module. Value not set. -~~~ - -- Use the drop-down to set the enabled value to 'true' - -~~~ -Priority Setting Value Description Error Message -Recommended Plugin.Import_ocr_enabled true Enable or disable the ocr module. Value not set. -~~~ - -### Set any other required settings for your module - -In this same menu set any other plugin settings that are required for testing. - -## Install misp-module on an offline instance. -First, you need to grab all necessary packages for example like this : - -Use pip wheel to create an archive -~~~ -mkdir misp-modules-offline -pip3 wheel -r REQUIREMENTS shodan --wheel-dir=./misp-modules-offline -tar -cjvf misp-module-bundeled.tar.bz2 ./misp-modules-offline/* -~~~ -On offline machine : -~~~ -mkdir misp-modules-bundle -tar xvf misp-module-bundeled.tar.bz2 -C misp-modules-bundle -cd misp-modules-bundle -ls -1|while read line; do sudo pip3 install --force-reinstall --ignore-installed --upgrade --no-index --no-deps ${line};done -~~~ -Next you can follow standard install procedure. - -## How to contribute your own module? - -Fork the project, add your module, test it and make a pull-request. Modules can be also private as you can add a module in your own MISP installation. - - -## Tips for developers creating modules - -Download a pre-built virtual image from the [MISP training materials](https://www.circl.lu/services/misp-training-materials/). - -- Create a Host-Only adapter in VirtualBox -- Set your Misp OVA to that Host-Only adapter -- Start the virtual machine -- Get the IP address of the virtual machine -- SSH into the machine (Login info on training page) -- Go into the misp-modules directory - -~~~bash -cd /usr/local/src/misp-modules -~~~ - -Set the git repo to your fork and checkout your development branch. If you SSH'ed in as the misp user you will have to use sudo. - -~~~bash -sudo git remote set-url origin https://github.com/YourRepo/misp-modules.git -sudo git pull -sudo git checkout MyModBranch -~~~ - -Remove the contents of the build directory and re-install misp-modules. - -~~~bash -sudo rm -fr build/* -sudo -u www-data /var/www/MISP/venv/bin/pip install --upgrade . -~~~ - -SSH in with a different terminal and run `misp-modules` with debugging enabled. - -~~~bash -# In case misp-modules is not a service do: -# sudo killall misp-modules -sudo systemctl disable --now misp-modules -sudo -u www-data /var/www/MISP/venv/bin/misp-modules -d -~~~ - - -In your original terminal you can now run your tests manually and see any errors that arrive - -~~~bash -cd tests/ -curl -s http://127.0.0.1:6666/query -H "Content-Type: application/json" --data @MY_TEST_FILE.json -X POST -cd ../ -~~~ - -## Documentation - -In order to provide documentation about some modules that require specific input / output / configuration, the [index.md](docs/index.md) file within the [docs](docs) directory contains detailed information about the general purpose, requirements, features, input and ouput of each of these modules: +In order to provide documentation about some modules that require specific input / output / configuration, the [documentation](https://misp.github.io/misp-modules/) contains detailed information about the general purpose, requirements, features, input and ouput of each of these modules: - ***description** - quick description of the general purpose of the module, as the one given by the moduleinfo - **requirements** - special libraries needed to make the module work @@ -588,3 +29,161 @@ In order to provide documentation about some modules that require specific input - **references** - link(s) giving additional information about the format concerned in the module - **input** - description of the format of data used in input - **output** - description of the format given as the result of the module execution + +## Licenses +For further Information see the [license file](https://misp.github.io/misp-modules/license/). + +# List of MISP modules + +## Expansion Modules +* [Abuse IPDB](https://misp.github.io/misp-modules/expansion/#abuse-ipdb) - AbuseIPDB MISP expansion module +* [OSINT DigitalSide](https://misp.github.io/misp-modules/expansion/#osint-digitalside) - On demand query API for OSINT.digitalside.it project. +* [APIVoid](https://misp.github.io/misp-modules/expansion/#apivoid) - Module to query APIVoid with some domain attributes. +* [AssemblyLine Query](https://misp.github.io/misp-modules/expansion/#assemblyline-query) - A module tu query the AssemblyLine API with a submission ID to get the submission report and parse it. +* [AssemblyLine Submit](https://misp.github.io/misp-modules/expansion/#assemblyline-submit) - A module to submit samples and URLs to AssemblyLine for advanced analysis, and return the link of the submission. +* [Backscatter.io](https://misp.github.io/misp-modules/expansion/#backscatter.io) - Backscatter.io module to bring mass-scanning observations into MISP. +* [BTC Scam Check](https://misp.github.io/misp-modules/expansion/#btc-scam-check) - An expansion hover module to query a special dns blacklist to check if a bitcoin address has been abused. +* [BTC Steroids](https://misp.github.io/misp-modules/expansion/#btc-steroids) - An expansion hover module to get a blockchain balance from a BTC address in MISP. +* [Censys Enrich](https://misp.github.io/misp-modules/expansion/#censys-enrich) - An expansion module to enrich attributes in MISP by quering the censys.io API +* [CIRCL Passive DNS](https://misp.github.io/misp-modules/expansion/#circl-passive-dns) - Module to access CIRCL Passive DNS. +* [CIRCL Passive SSL](https://misp.github.io/misp-modules/expansion/#circl-passive-ssl) - Modules to access CIRCL Passive SSL. +* [ClaamAV](https://misp.github.io/misp-modules/expansion/#claamav) - Submit file to ClamAV +* [Cluster25 Expand](https://misp.github.io/misp-modules/expansion/#cluster25-expand) - Module to query Cluster25 CTI. +* [Country Code](https://misp.github.io/misp-modules/expansion/#country-code) - Module to expand country codes. +* [CPE Lookup](https://misp.github.io/misp-modules/expansion/#cpe-lookup) - An expansion module to query the CVE search API with a cpe code to get its related vulnerabilities. +* [CrowdSec CTI](https://misp.github.io/misp-modules/expansion/#crowdsec-cti) - Module to access CrowdSec CTI API. +* [CrowdStrike Falcon](https://misp.github.io/misp-modules/expansion/#crowdstrike-falcon) - Module to query CrowdStrike Falcon. +* [Cuckoo Submit](https://misp.github.io/misp-modules/expansion/#cuckoo-submit) - Submit files and URLs to Cuckoo Sandbox +* [CVE Lookup](https://misp.github.io/misp-modules/expansion/#cve-lookup) - An expansion hover module to expand information about CVE id. +* [CVE Advanced Lookup](https://misp.github.io/misp-modules/expansion/#cve-advanced-lookup) - An expansion module to query the CIRCL CVE search API for more information about a vulnerability (CVE). +* [Cytomic Orion Lookup](https://misp.github.io/misp-modules/expansion/#cytomic-orion-lookup) - An expansion module to enrich attributes in MISP by quering the Cytomic Orion API +* [DBL Spamhaus Lookup](https://misp.github.io/misp-modules/expansion/#dbl-spamhaus-lookup) - Checks Spamhaus DBL for a domain name. +* [DNS Resolver](https://misp.github.io/misp-modules/expansion/#dns-resolver) - jj +* [DOCX Enrich](https://misp.github.io/misp-modules/expansion/#docx-enrich) - Module to extract freetext from a .docx document. +* [DomainTools Lookup](https://misp.github.io/misp-modules/expansion/#domaintools-lookup) - DomainTools MISP expansion module. +* [EQL Query Generator](https://misp.github.io/misp-modules/expansion/#eql-query-generator) - EQL query generation for a MISP attribute. +* [EUPI Lookup](https://misp.github.io/misp-modules/expansion/#eupi-lookup) - A module to query the Phishing Initiative service (https://phishing-initiative.lu). +* [URL Components Extractor](https://misp.github.io/misp-modules/expansion/#url-components-extractor) - Extract URL components +* [Farsight DNSDB Lookup](https://misp.github.io/misp-modules/expansion/#farsight-dnsdb-lookup) - Module to access Farsight DNSDB Passive DNS. +* [GeoIP ASN Lookup](https://misp.github.io/misp-modules/expansion/#geoip-asn-lookup) - Query a local copy of the Maxmind Geolite ASN database (MMDB format) +* [GeoIP City Lookup](https://misp.github.io/misp-modules/expansion/#geoip-city-lookup) - An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about the city where it is located. +* [GeoIP Country Lookup](https://misp.github.io/misp-modules/expansion/#geoip-country-lookup) - Query a local copy of Maxminds Geolite database, updated for MMDB format +* [Google Safe Browsing Lookup](https://misp.github.io/misp-modules/expansion/#google-safe-browsing-lookup) - Google safe browsing expansion module +* [Google Search](https://misp.github.io/misp-modules/expansion/#google-search) - An expansion hover module to expand google search information about an URL +* [Google Threat Intelligence Lookup](https://misp.github.io/misp-modules/expansion/#google-threat-intelligence-lookup) - An expansion module to have the observable's threat score assessed by Google Threat Intelligence. +* [GreyNoise Lookup](https://misp.github.io/misp-modules/expansion/#greynoise-lookup) - Module to query IP and CVE information from GreyNoise +* [Hashdd Lookup](https://misp.github.io/misp-modules/expansion/#hashdd-lookup) - A hover module to check hashes against hashdd.com including NSLR dataset. +* [CIRCL Hashlookup Lookup](https://misp.github.io/misp-modules/expansion/#circl-hashlookup-lookup) - An expansion module to query the CIRCL hashlookup services to find it if a hash is part of a known set such as NSRL. +* [Have I Been Pwned Lookup](https://misp.github.io/misp-modules/expansion/#have-i-been-pwned-lookup) - Module to access haveibeenpwned.com API. +* [HTML to Markdown](https://misp.github.io/misp-modules/expansion/#html-to-markdown) - Expansion module to fetch the html content from an url and convert it into markdown. +* [HYAS Insight Lookup](https://misp.github.io/misp-modules/expansion/#hyas-insight-lookup) - HYAS Insight integration to MISP provides direct, high volume access to HYAS Insight data. It enables investigators and analysts to understand and defend against cyber adversaries and their infrastructure. +* [Intel471 Lookup](https://misp.github.io/misp-modules/expansion/#intel471-lookup) - Module to access Intel 471 +* [IP2Location.io Lookup](https://misp.github.io/misp-modules/expansion/#ip2location.io-lookup) - An expansion module to query IP2Location.io to gather more information on a given IP address. +* [IPASN-History Lookup](https://misp.github.io/misp-modules/expansion/#ipasn-history-lookup) - Module to query an IP ASN history service (https://github.com/D4-project/IPASN-History). +* [IPInfo.io Lookup](https://misp.github.io/misp-modules/expansion/#ipinfo.io-lookup) - An expansion module to query ipinfo.io to gather more information on a given IP address. +* [IPQualityScore Lookup](https://misp.github.io/misp-modules/expansion/#ipqualityscore-lookup) - IPQualityScore MISP Expansion Module for IP reputation, Email Validation, Phone Number Validation, Malicious Domain and Malicious URL Scanner. +* [IPRep Lookup](https://misp.github.io/misp-modules/expansion/#iprep-lookup) - Module to query IPRep data for IP addresses. +* [Ninja Template Rendering](https://misp.github.io/misp-modules/expansion/#ninja-template-rendering) - Render the template with the data passed +* [Joe Sandbox Import](https://misp.github.io/misp-modules/expansion/#joe-sandbox-import) - Query Joe Sandbox API with a submission url to get the json report and extract its data that is parsed and converted into MISP attributes and objects. +* [Joe Sandbox Submit](https://misp.github.io/misp-modules/expansion/#joe-sandbox-submit) - A module to submit files or URLs to Joe Sandbox for an advanced analysis, and return the link of the submission. +* [Lastline Lookup](https://misp.github.io/misp-modules/expansion/#lastline-lookup) - Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Query Lastline with an analysis link and parse the report into MISP attributes and objects. +* [Lastline Submit](https://misp.github.io/misp-modules/expansion/#lastline-submit) - Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Module to submit a file or URL to Lastline. +* [Macaddress.io Lookup](https://misp.github.io/misp-modules/expansion/#macaddress.io-lookup) - MISP hover module for macaddress.io +* [Macvendors Lookup](https://misp.github.io/misp-modules/expansion/#macvendors-lookup) - Module to access Macvendors API. +* [MalShare Upload](https://misp.github.io/misp-modules/expansion/#malshare-upload) - Module to push malware samples to MalShare +* [Malware Bazaar Lookup](https://misp.github.io/misp-modules/expansion/#malware-bazaar-lookup) - Query Malware Bazaar to get additional information about the input hash. +* [McAfee MVISION Insights Lookup](https://misp.github.io/misp-modules/expansion/#mcafee-mvision-insights-lookup) - Lookup McAfee MVISION Insights Details +* [GeoIP Enrichment](https://misp.github.io/misp-modules/expansion/#geoip-enrichment) - A hover and expansion module to enrich an ip with geolocation and ASN information from an mmdb server instance, such as CIRCL's ip.circl.lu. +* [MWDB Submit](https://misp.github.io/misp-modules/expansion/#mwdb-submit) - Module to push malware samples to a MWDB instance +* [OCR Enrich](https://misp.github.io/misp-modules/expansion/#ocr-enrich) - Module to process some optical character recognition on pictures. +* [ODS Enrich](https://misp.github.io/misp-modules/expansion/#ods-enrich) - Module to extract freetext from a .ods document. +* [ODT Enrich](https://misp.github.io/misp-modules/expansion/#odt-enrich) - Module to extract freetext from a .odt document. +* [Onyphe Lookup](https://misp.github.io/misp-modules/expansion/#onyphe-lookup) - Module to process a query on Onyphe. +* [Onyphe Full Lookup](https://misp.github.io/misp-modules/expansion/#onyphe-full-lookup) - Module to process a full query on Onyphe. +* [AlienVault OTX Lookup](https://misp.github.io/misp-modules/expansion/#alienvault-otx-lookup) - Module to get information from AlienVault OTX. +* [Passive SSH Enrichment](https://misp.github.io/misp-modules/expansion/#passive-ssh-enrichment) - An expansion module to enrich, SSH key fingerprints and IP addresses with information collected by passive-ssh +* [PassiveTotal Lookup](https://misp.github.io/misp-modules/expansion/#passivetotal-lookup) - The PassiveTotal MISP expansion module brings the datasets derived from Internet scanning directly into your MISP instance. This module supports passive DNS, historic SSL, WHOIS, and host attributes. In order to use the module, you must have a valid PassiveTotal account username and API key. Registration is free and can be done by visiting https://www.passivetotal.org/register +* [PDF Enrich](https://misp.github.io/misp-modules/expansion/#pdf-enrich) - Module to extract freetext from a PDF document. +* [PPTX Enrich](https://misp.github.io/misp-modules/expansion/#pptx-enrich) - Module to extract freetext from a .pptx document. +* [Qintel QSentry Lookup](https://misp.github.io/misp-modules/expansion/#qintel-qsentry-lookup) - A hover and expansion module which queries Qintel QSentry for ip reputation data +* [QR Code Decode](https://misp.github.io/misp-modules/expansion/#qr-code-decode) - Module to decode QR codes. +* [RandomcoinDB Lookup](https://misp.github.io/misp-modules/expansion/#randomcoindb-lookup) - Module to access the ransomcoinDB (see https://ransomcoindb.concinnity-risks.com) +* [Real-time Blackhost Lists Lookup](https://misp.github.io/misp-modules/expansion/#real-time-blackhost-lists-lookup) - Module to check an IPv4 address against known RBLs. +* [Recorded Future Enrich](https://misp.github.io/misp-modules/expansion/#recorded-future-enrich) - Module to enrich attributes with threat intelligence from Recorded Future. +* [Reverse DNS](https://misp.github.io/misp-modules/expansion/#reverse-dns) - Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes. +* [SecurityTrails Lookup](https://misp.github.io/misp-modules/expansion/#securitytrails-lookup) - An expansion modules for SecurityTrails. +* [Shodan Lookup](https://misp.github.io/misp-modules/expansion/#shodan-lookup) - Module to query on Shodan. +* [Sigma Rule Converter](https://misp.github.io/misp-modules/expansion/#sigma-rule-converter) - An expansion hover module to display the result of sigma queries. +* [Sigma Syntax Validator](https://misp.github.io/misp-modules/expansion/#sigma-syntax-validator) - An expansion hover module to perform a syntax check on sigma rules. +* [SigMF Expansion](https://misp.github.io/misp-modules/expansion/#sigmf-expansion) - Expands a SigMF Recording object into a SigMF Expanded Recording object, extracts a SigMF archive into a SigMF Recording object. +* [Socialscan Lookup](https://misp.github.io/misp-modules/expansion/#socialscan-lookup) - A hover module to get information on the availability of an email address or username on some online platforms. +* [SophosLabs Intelix Lookup](https://misp.github.io/misp-modules/expansion/#sophoslabs-intelix-lookup) - An expansion module to query the Sophoslabs intelix API to get additional information about an ip address, url, domain or sha256 attribute. +* [URL Archiver](https://misp.github.io/misp-modules/expansion/#url-archiver) - Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page. +* [Stairwell Lookup](https://misp.github.io/misp-modules/expansion/#stairwell-lookup) - Module to query the Stairwell API to get additional information about the input hash attribute +* [STIX2 Pattern Syntax Validator](https://misp.github.io/misp-modules/expansion/#stix2-pattern-syntax-validator) - An expansion hover module to perform a syntax check on stix2 patterns. +* [ThreatCrowd Lookup](https://misp.github.io/misp-modules/expansion/#threatcrowd-lookup) - Module to get information from ThreatCrowd. +* [ThreadFox Lookup](https://misp.github.io/misp-modules/expansion/#threadfox-lookup) - Module to search for an IOC on ThreatFox by abuse.ch. +* [ThreatMiner Lookup](https://misp.github.io/misp-modules/expansion/#threatminer-lookup) - Module to get information from ThreatMiner. +* [Triage Submit](https://misp.github.io/misp-modules/expansion/#triage-submit) - Module to submit samples to tria.ge +* [TruSTAR Enrich](https://misp.github.io/misp-modules/expansion/#trustar-enrich) - Module to get enrich indicators with TruSTAR. +* [URLhaus Lookup](https://misp.github.io/misp-modules/expansion/#urlhaus-lookup) - Query of the URLhaus API to get additional information about the input attribute. +* [URLScan Lookup](https://misp.github.io/misp-modules/expansion/#urlscan-lookup) - An expansion module to query urlscan.io. +* [VARIoT db Lookup](https://misp.github.io/misp-modules/expansion/#variot-db-lookup) - An expansion module to query the VARIoT db API for more information about a vulnerability. +* [VirusTotal v3 Lookup](https://misp.github.io/misp-modules/expansion/#virustotal-v3-lookup) - Enrich observables with the VirusTotal v3 API +* [VirusTotal Public API Lookup](https://misp.github.io/misp-modules/expansion/#virustotal-public-api-lookup) - Enrich observables with the VirusTotal v3 public API +* [VirusTotal Upload](https://misp.github.io/misp-modules/expansion/#virustotal-upload) - Module to push malware samples to VirusTotal +* [VMRay Submit](https://misp.github.io/misp-modules/expansion/#vmray-submit) - Module to submit a sample to VMRay. +* [VMware NSX Defender Enrich](https://misp.github.io/misp-modules/expansion/#vmware-nsx-defender-enrich) - Module to enrich a file or URL with VMware NSX Defender. +* [VulnDB Lookup](https://misp.github.io/misp-modules/expansion/#vulndb-lookup) - Module to query VulnDB (RiskBasedSecurity.com). +* [Vulnerability Lookup](https://misp.github.io/misp-modules/expansion/#vulnerability-lookup) - An expansion module to query Vulnerability Lookup +* [Vulners Lookup](https://misp.github.io/misp-modules/expansion/#vulners-lookup) - An expansion hover module to expand information about CVE id using Vulners API. +* [Vysion Enrich](https://misp.github.io/misp-modules/expansion/#vysion-enrich) - Module to enrich the information by making use of the Vysion API. +* [Whois Lookup](https://misp.github.io/misp-modules/expansion/#whois-lookup) - Module to query a local instance of uwhois (https://github.com/rafiot/uwhoisd). +* [WhoisFreaks Lookup](https://misp.github.io/misp-modules/expansion/#whoisfreaks-lookup) - An expansion module for https://whoisfreaks.com/ that will provide an enriched analysis of the provided domain, including WHOIS and DNS information. +* [Wikidata Lookup](https://misp.github.io/misp-modules/expansion/#wikidata-lookup) - An expansion hover module to extract information from Wikidata to have additional information about particular term for analysis. +* [IBM X-Force Exchange Lookup](https://misp.github.io/misp-modules/expansion/#ibm-x-force-exchange-lookup) - An expansion module for IBM X-Force Exchange. +* [XLXS Enrich](https://misp.github.io/misp-modules/expansion/#xlxs-enrich) - Module to extract freetext from a .xlsx document. +* [YARA Rule Generator](https://misp.github.io/misp-modules/expansion/#yara-rule-generator) - jj +* [YARA Syntax Validator](https://misp.github.io/misp-modules/expansion/#yara-syntax-validator) - An expansion hover module to perform a syntax check on if yara rules are valid or not. +* [Yeti Lookup](https://misp.github.io/misp-modules/expansion/#yeti-lookup) - Module to process a query on Yeti. + +## Export Modules +* [CEF Export](https://misp.github.io/misp-modules/export_mod/#cef-export) - Module to export a MISP event in CEF format. +* [Cisco fireSIGHT blockrule Export](https://misp.github.io/misp-modules/export_mod/#cisco-firesight-blockrule-export) - Module to export malicious network activity attributes to Cisco fireSIGHT manager block rules. +* [Microsoft Defender for Endpoint KQL Export](https://misp.github.io/misp-modules/export_mod/#microsoft-defender-for-endpoint-kql-export) - Defender for Endpoint KQL hunting query export module +* [GoAML Export](https://misp.github.io/misp-modules/export_mod/#goaml-export) - This module is used to export MISP events containing transaction objects into GoAML format. +* [Lite Export](https://misp.github.io/misp-modules/export_mod/#lite-export) - Lite export of a MISP event. +* [EQL Query Export](https://misp.github.io/misp-modules/export_mod/#eql-query-export) - Export MISP event in Event Query Language +* [Nexthink NXQL Export](https://misp.github.io/misp-modules/export_mod/#nexthink-nxql-export) - Nexthink NXQL query export module +* [OSQuery Export](https://misp.github.io/misp-modules/export_mod/#osquery-export) - OSQuery export of a MISP event. +* [Event to PDF Export](https://misp.github.io/misp-modules/export_mod/#event-to-pdf-export) - Simple export of a MISP event to PDF. +* [ThreatStream Export](https://misp.github.io/misp-modules/export_mod/#threatstream-export) - Module to export a structured CSV file for uploading to threatStream. +* [ThreadConnect Export](https://misp.github.io/misp-modules/export_mod/#threadconnect-export) - Module to export a structured CSV file for uploading to ThreatConnect. +* [VirusTotal Collections Export](https://misp.github.io/misp-modules/export_mod/#virustotal-collections-export) - Creates a VT Collection from an event iocs. +* [VirusTotal Graph Export](https://misp.github.io/misp-modules/export_mod/#virustotal-graph-export) - This module is used to create a VirusTotal Graph from a MISP event. +* [YARA Rule Export](https://misp.github.io/misp-modules/export_mod/#yara-rule-export) - This module is used to export MISP events to YARA. + +## Import Modules +* [PDNS COF Importer](https://misp.github.io/misp-modules/import_mod/#pdns-cof-importer) - Passive DNS Common Output Format (COF) MISP importer +* [CSV Import](https://misp.github.io/misp-modules/import_mod/#csv-import) - Module to import MISP attributes from a csv file. +* [Cuckoo Sandbox Import](https://misp.github.io/misp-modules/import_mod/#cuckoo-sandbox-import) - Module to import Cuckoo JSON. +* [Email Import](https://misp.github.io/misp-modules/import_mod/#email-import) - Email import module for MISP +* [GoAML Import](https://misp.github.io/misp-modules/import_mod/#goaml-import) - Module to import MISP objects about financial transactions from GoAML files. +* [Import Blueprint](https://misp.github.io/misp-modules/import_mod/#import-blueprint) - Generic blueprint to be copy-pasted to quickly boostrap creation of import module. +* [Joe Sandbox Import](https://misp.github.io/misp-modules/import_mod/#joe-sandbox-import) - A module to import data from a Joe Sandbox analysis json report. +* [Lastline Import](https://misp.github.io/misp-modules/import_mod/#lastline-import) - Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Module to import and parse reports from Lastline analysis links. +* [MISP JSON Import](https://misp.github.io/misp-modules/import_mod/#misp-json-import) - Module to import MISP JSON format for merging MISP events. +* [OCR Import](https://misp.github.io/misp-modules/import_mod/#ocr-import) - Optical Character Recognition (OCR) module for MISP. +* [OpenIOC Import](https://misp.github.io/misp-modules/import_mod/#openioc-import) - Module to import OpenIOC packages. +* [TAXII 2.1 Import](https://misp.github.io/misp-modules/import_mod/#taxii-2.1-import) - Import content from a TAXII 2.1 server +* [ThreadAnalyzer Sandbox Import](https://misp.github.io/misp-modules/import_mod/#threadanalyzer-sandbox-import) - Module to import ThreatAnalyzer archive.zip / analysis.json files. +* [URL Import](https://misp.github.io/misp-modules/import_mod/#url-import) - Simple URL import tool with Faup +* [VMRay API Import](https://misp.github.io/misp-modules/import_mod/#vmray-api-import) - Module to import VMRay (VTI) results. +* [VMRay Summary JSON Import](https://misp.github.io/misp-modules/import_mod/#vmray-summary-json-import) - Import a VMRay Summary JSON report. + +## Action Modules +* [Mattermost](https://misp.github.io/misp-modules/action_mod/#mattermost) - Simplistic module to send message to a Mattermost channel. +* [Slack](https://misp.github.io/misp-modules/action_mod/#slack) - Simplistic module to send messages to a Slack channel. +* [Test action](https://misp.github.io/misp-modules/action_mod/#test-action) - This module is merely a test, always returning true. Triggers on event publishing. + + diff --git a/README.rst b/README.rst deleted file mode 120000 index 42061c01..00000000 --- a/README.rst +++ /dev/null @@ -1 +0,0 @@ -README.md \ No newline at end of file diff --git a/REQUIREMENTS b/REQUIREMENTS deleted file mode 100644 index 18086670..00000000 --- a/REQUIREMENTS +++ /dev/null @@ -1,190 +0,0 @@ --i https://pypi.org/simple -aiohttp>=3.9.0 -aiosignal==1.3.1 ; python_version >= '3.7' -antlr4-python3-runtime==4.9.3 -anyio==3.6.2 ; python_full_version >= '3.6.2' -git+https://github.com/davidonzo/apiosintDS@misp -appdirs==1.4.4 -argcomplete==3.0.8 ; python_version >= '3.6' -argparse==1.4.0 -assemblyline-client==4.5.1 -async-timeout==4.0.2 ; python_version >= '3.6' -asynctest==0.13.0 ; python_version < '3.8' -attrs==23.1.0 ; python_version >= '3.7' -backoff==2.2.1 ; python_version >= '3.7' and python_version < '4.0' -backports.zoneinfo==0.2.1 ; python_version < '3.9' -backscatter==0.2.4 -beautifulsoup4==4.12.2 -bidict==0.22.1 ; python_version >= '3.7' -blockchain==1.4.4 -censys==2.2.2 -certifi>=2023.7.22 ; python_version >= '3.6' -cffi==1.15.1 -chardet==5.1.0 -charset-normalizer==3.1.0 ; python_full_version >= '3.7.0' -clamd==1.0.2 -click==8.1.3 ; python_version >= '3.7' -click-plugins==1.1.1 -colorama==0.4.6 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' -colorclass==2.2.2 ; python_version >= '2.6' -compressed-rtf==1.0.6 -configparser==5.3.0 ; python_version >= '3.7' -crowdstrike-falconpy==1.2.15 -cryptography>=41.0.2 ; python_version >= '3.6' -dateparser==1.1.8 ; python_version >= '3.7' -decorator==5.1.1 ; python_version >= '3.5' -deprecated==1.2.14 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -dnsdb2==1.1.4 -dnspython==2.3.0 -domaintools-api==1.0.1 -easygui==0.98.3 -ebcdic==1.1.1 -enum-compat==0.0.3 -et-xmlfile==1.1.0 ; python_version >= '3.6' -extract-msg==0.45.0 -ezodf==0.3.2 -filelock==3.12.0 ; python_version >= '3.7' -frozenlist==1.3.3 ; python_version >= '3.7' -future==0.18.3 ; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3' -geoip2==4.7.0 -h11==0.14.0 ; python_version >= '3.7' -httpcore==0.17.1 ; python_version >= '3.7' -httplib2==0.22.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -httpx==0.24.1 ; python_version >= '3.7' -idna==3.4 ; python_version >= '3.5' -imapclient==2.3.1 -importlib-metadata==4.13.0 ; python_version < '3.8' -importlib-resources==5.12.0 ; python_version < '3.9' -isodate==0.6.1 -itsdangerous==2.1.2 ; python_version >= '3.7' -jaraco.classes==3.2.3 ; python_version >= '3.7' -jbxapi==3.21.0 -jeepney==0.8.0 ; sys_platform == 'linux' -jinja2==3.1.2 -json-log-formatter==0.5.2 ; python_version >= '2.7' -jsonschema==4.19.0 ; python_version >= '3.7' -keyring==23.13.1 ; python_version >= '3.7' -lark-parser==0.12.0 -lief==0.13.2 -lxml==4.9.2 -maclookup==1.0.3 -markdown-it-py==2.2.0 ; python_version >= '3.7' -markdownify==0.5.3 -markupsafe==2.1.2 ; python_version >= '3.7' -matplotlib==3.7.2 ; python_version >= '3.8' -matplotlib==3.5.3 ; python_version == '3.7' -mattermostdriver==7.3.2 -maxminddb==2.3.0 ; python_version >= '3.7' -mdurl==0.1.2 ; python_version >= '3.7' -. -more-itertools==9.1.0 ; python_version >= '3.7' -msoffcrypto-tool==5.0.1 ; python_version >= '3' and platform_python_implementation != 'PyPy' or (platform_system != 'Windows' and platform_system != 'Darwin') -multidict==6.0.4 ; python_version >= '3.7' -mwdblib==4.4.0 -ndjson==0.3.1 -np==1.0.2 -numpy==1.21.6 ; python_version < '3.10' and platform_machine == 'aarch64' -oauth2==1.9.0.post1 -git+https://github.com/cartertemm/ODTReader.git/@49d6938693f6faa3ff09998f86dba551ae3a996b#egg=odtreader -olefile==0.46 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -oletools==0.60.1 -opencv-python==4.7.0.72 -openpyxl==3.1.2 -packaging==23.1 ; python_version >= '3.7' -pandas==1.5.3 -pandas-ods-reader==0.1.4 -passivetotal==2.5.9 -pcodedmp==1.2.6 -pdftotext==2.2.2 -pillow>=10.2.0 -pkgutil-resolve-name==1.3.10 ; python_version < '3.9' -progressbar2==4.2.0 ; python_full_version >= '3.7.0' -psutil==5.9.5 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -publicsuffixlist==0.10.0.20230828 ; python_version >= '2.6' -git+https://github.com/D4-project/BGP-Ranking.git/@68de39f6c5196f796055c1ac34504054d688aa59#egg=pybgpranking&subdirectory=client -pycountry==22.3.5 -pycparser==2.21 -pycryptodome==3.18.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -pycryptodomex==3.17 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -pydeep2==0.5.1 -git+https://github.com/sebdraven/pydnstrails@48c1f740025c51289f43a24863d1845ff12fd21a#egg=pydnstrails -pyeupi==1.1 -pyfaup==1.2 -pygeoip==0.3.2 -pygments==2.15.1 ; python_version >= '3.7' -git+https://github.com/MISP/PyIntel471.git@917272fafa8e12102329faca52173e90c5256968#egg=pyintel471 -git+https://github.com/D4-project/IPASN-History.git/@a2853c39265cecdd0c0d16850bd34621c0551b87#egg=pyipasnhistory&subdirectory=client -pymisp[email,fileobjects,openioc,pdfexport,url]==2.4.175 -git+https://github.com/sebdraven/pyonyphe@d1d6741f8ea4475f3bb77ff20c876f08839cabd1#egg=pyonyphe -pyparsing==2.4.7 ; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3' -pypdns==1.5.2 -pypssl==2.2 -pyrsistent==0.19.3 ; python_version >= '3.7' -pysafebrowsing==0.1.2 -pytesseract==0.3.10 -python-baseconv==1.2.2 -python-dateutil==2.8.2 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -python-docx==0.8.11 -python-engineio==4.4.1 ; python_version >= '3.6' -python-magic==0.4.27 -python-pptx==0.6.21 -python-socketio[client]==5.8.0 ; python_version >= '3.6' -python-utils==3.5.2 ; python_version >= '3.7' -pytz==2023.3 -pytz-deprecation-shim==0.1.0.post0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' -pyyaml==6.0 ; python_version >= '3.6' -pyzbar==0.1.9 -pyzipper==0.3.6 ; python_version >= '3.5' -rdflib==6.3.2 ; python_version >= '3.7' and python_version < '4.0' -red-black-tree-mod==1.20 -redis==4.5.5 ; python_version >= '3.7' -regex==2023.5.5 ; python_version >= '3.6' -reportlab==4.0.4 -requests[security]==2.31.0 -requests-cache==0.6.4 ; python_version >= '3.6' -requests-file==1.5.1 -rich==13.3.5 ; python_full_version >= '3.7.0' -rtfde==0.1.0 -secretstorage==3.3.3 ; sys_platform == 'linux' -setuptools==67.7.2 ; python_version >= '3.7' -shodan==1.29.1 -sigmatools==0.19.1 -sigmf==1.1.1 -simplejson==3.19.1 ; python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2, 3.3' -six==1.16.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -slack-sdk==3.27.1 -sniffio==1.3.0 ; python_version >= '3.7' -socialscan==1.4 -socketio-client==0.5.7.4 -soupsieve==2.4.1 ; python_version >= '3.7' -sparqlwrapper==2.0.0 -stix2==3.0.1 -stix2-patterns==2.0.0 -tabulate==0.9.0 ; python_version >= '3.7' -tau-clients==0.3.0 -taxii2-client==2.3.0 -tldextract==3.4.3 ; python_version >= '3.7' -tornado==6.2 ; python_version >= '3.7' -tqdm==4.65.0 ; python_version >= '3.7' -git+https://github.com/SteveClement/trustar-python.git@6954eae38e0c77eaeef26084b6c5fd033925c1c7#egg=trustar -typing-extensions==4.5.0 ; python_version < '3.8' -tzdata==2023.3 ; python_version >= '3.6' -tzlocal==4.2 ; python_version >= '3.6' -unicodecsv==0.14.1 -url-normalize==1.4.3 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' -urlarchiver==0.2 -urllib3==1.26.15 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' -validators==0.14.0 -vt-graph-api==2.2.0 -vt-py==0.17.5 -vulners==2.0.10 -vysion==1.0.10 -wand==0.6.11 -websocket-client==1.5.1 ; python_version >= '3.7' -websockets==11.0.3 ; python_version >= '3.7' -wrapt==1.15.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -xlrd==2.0.1 -xlsxwriter==3.1.0 ; python_version >= '3.6' -yara-python==3.8.1 -yarl==1.9.2 ; python_version >= '3.7' -zipp==3.15.0 ; python_version >= '3.7' diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 8ac6d9f7..00000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,130 +0,0 @@ -FROM python:3.7-buster AS build - -ENV DEBIAN_FRONTEND noninteractive -ENV WORKDIR="/usr/local/src/misp_modules" -ENV VENV_DIR="/misp_modules" - -# Install Packages for build -RUN set -eu \ - ;mkdir -p ${WORKDIR} ${VENV_DIR} \ - ;apt-get update \ - ;apt-get install -y \ - git \ - libpq5 \ - libjpeg-dev \ - tesseract-ocr \ - libpoppler-cpp-dev \ - imagemagick \ - virtualenv \ - libopencv-dev \ - zbar-tools \ - libzbar0 \ - libzbar-dev \ - libfuzzy-dev \ - ;apt-get -y autoremove \ - ;apt-get -y clean \ - ;rm -rf /var/lib/apt/lists/* \ - ; - -# Create MISP Modules -RUN set -eu \ - ;git clone https://github.com/MISP/misp-modules.git ${WORKDIR} \ - ;virtualenv -p python3 ${VENV_DIR}/venv \ - ;cd ${WORKDIR} \ - ;${VENV_DIR}/venv/bin/pip3 install -I -r REQUIREMENTS --no-cache-dir \ - ;${VENV_DIR}/venv/bin/pip3 install . --no-cache-dir \ - ; - -######################################### -# Start Final Docker Image -# -FROM python:3.7-slim-buster AS final - -ENV DEBIAN_FRONTEND noninteractive -ENV VENV_DIR="/misp_modules" - -# Copy all builded files from build stage -COPY --from=build ${VENV_DIR} ${VENV_DIR} - -# Install Packages to run it -RUN set -eu \ - ;apt-get update \ - ;apt-get install -y \ - curl \ - libpq5 \ - # libjpeg-dev \ - tesseract-ocr \ - libpoppler-cpp-dev \ - imagemagick \ - # virtualenv \ - # libopencv-dev \ - zbar-tools \ - libzbar0 \ - # libzbar-dev \ - # libfuzzy-dev \ - ;apt-get -y autoremove \ - ;apt-get -y clean \ - ;rm -rf /var/lib/apt/lists/* \ - ;chown -R nobody ${VENV_DIR} \ - ; - -# Entrypoint - COPY files/entrypoint.sh /entrypoint.sh - ENTRYPOINT [ "/entrypoint.sh" ] - -# Add Healthcheck Config - COPY files/healthcheck.sh /healthcheck.sh - HEALTHCHECK --interval=1m --timeout=45s --retries=3 CMD ["/healthcheck.sh"] - -# Change Workdir - WORKDIR ${VENV_DIR} - -# Change from root to www-data - USER nobody - -# Expose Port - EXPOSE 6666 - -# Shortterm ARG Variables: - ARG VENDOR="MISP" - ARG COMPONENT="misp-modules" - ARG BUILD_DATE - ARG GIT_REPO="https://github.com/MISP/misp-modules" - ARG VCS_REF - ARG RELEASE_DATE - ARG NAME="MISP-dockerized-misp-modules" - ARG DESCRIPTION="This docker container contains MISP modules in an Debian Container." - ARG DOCUMENTATION="https://misp.github.io/misp-modules/" - ARG AUTHOR="MISP" - ARG LICENSE="BSD-3-Clause" - -# Longterm Environment Variables -ENV \ - BUILD_DATE=${BUILD_DATE} \ - NAME=${NAME} \ - PATH=$PATH:${VENV_DIR}/venv/bin - -# Labels -LABEL org.label-schema.build-date="${BUILD_DATE}" \ - org.label-schema.name="${NAME}" \ - org.label-schema.description="${DESCRIPTION}" \ - org.label-schema.vcs-ref="${VCS_REF}" \ - org.label-schema.vcs-url="${GIT_REPO}" \ - org.label-schema.url="${GIT_REPO}" \ - org.label-schema.vendor="${VENDOR}" \ - org.label-schema.version="${VERSION}" \ - org.label-schema.usage="${DOCUMENTATION}" \ - org.label-schema.schema-version="1.0.0-rc1" - -LABEL org.opencontainers.image.created="${BUILD_DATE}" \ - org.opencontainers.image.url="${GIT_REPO}" \ - org.opencontainers.image.source="${GIT_REPO}" \ - org.opencontainers.image.version="${VERSION}" \ - org.opencontainers.image.revision="${VCS_REF}" \ - org.opencontainers.image.vendor="${VENDOR}" \ - org.opencontainers.image.title="${NAME}" \ - org.opencontainers.image.description="${DESCRIPTION}" \ - org.opencontainers.image.documentation="${DOCUMENTATION}" \ - org.opencontainers.image.authors="${AUTHOR}" \ - org.opencontainers.image.licenses="${LICENSE}" - diff --git a/docker/files/entrypoint.sh b/docker/files/entrypoint.sh deleted file mode 100755 index 73d8f396..00000000 --- a/docker/files/entrypoint.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -set -eu - -# Variables -NC='\033[0m' # No Color -Light_Green='\033[1;32m' -STARTMSG="${Light_Green}[ENTRYPOINT_MISP_MODULES]${NC}" -VENV_DIR=${VENV_DIR:-"/misp-modules"} -MISP_MODULES_BINARY="${VENV_DIR}/venv/bin/misp-modules" -DEBUG="" - -# Functions -echo (){ - command echo "$STARTMSG $*" -} - -# Environment Variables -MISP_MODULES_DEBUG=${MISP_MODULES_DEBUG:-"false"} - -# -# MAIN -# - - -# Check if debugging mode should be enabled -[ "$MISP_MODULES_DEBUG" = "true" ] && DEBUG="-d" - -# check if a command parameter exists and start misp-modules -if [ $# = 0 ] -then - # If no cmd parameter is set - echo "Start MISP Modules" && $MISP_MODULES_BINARY $DEBUG -l 0.0.0.0 > /dev/stdout 2> /dev/stderr -else - # If cmd parameter is set - echo "Start MISP Modules" && $MISP_MODULES_BINARY $DEBUG -l 0.0.0.0 > /dev/stdout 2> /dev/stderr & - exec "$@" -fi diff --git a/docker/files/healthcheck.sh b/docker/files/healthcheck.sh deleted file mode 100755 index d6a1f911..00000000 --- a/docker/files/healthcheck.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -# If no contain is there or curl get an error back: exit 1. Docker restart then the container. -curl -fk http://0.0.0.0:6666/modules || exit 1 \ No newline at end of file diff --git a/docs/contribute.md b/docs/contribute.md deleted file mode 100644 index ef312f6a..00000000 --- a/docs/contribute.md +++ /dev/null @@ -1,374 +0,0 @@ -## How to add your own MISP modules? - -Create your module in [misp_modules/modules/expansion/](https://github.com/MISP/misp-modules/tree/master/misp_modules/modules/expansion/), [misp_modules/modules/export_mod/](https://github.com/MISP/misp-modules/tree/master/misp_modules/modules/export_mod/), or [misp_modules/modules/import_mod/](https://github.com/MISP/misp-modules/tree/master/misp_modules/modules/import_mod/). The module should have at minimum three functions: - -* **introspection** function that returns a dict of the supported attributes (input and output) by your expansion module. -* **handler** function which accepts a JSON document to expand the values and return a dictionary of the expanded values. -* **version** function that returns a dict with the version and the associated meta-data including potential configurations required of the module. - -Don't forget to return an error key and value if an error is raised to propagate it to the MISP user-interface. - -Your module's script name should also be added in the `__all__` list of `/__init__.py` in order for it to be loaded. - -~~~python -... - # Checking for required value - if not request.get('ip-src'): - # Return an error message - return {'error': "A source IP is required"} -... -~~~ - - -### introspection - -The function that returns a dict of the supported attributes (input and output) by your expansion module. - -~~~python -mispattributes = {'input': ['link', 'url'], - 'output': ['attachment', 'malware-sample']} - -def introspection(): - return mispattributes -~~~ - -### version - -The function that returns a dict with the version and the associated meta-data including potential configurations required of the module. - - -### Additional Configuration Values - -If your module requires additional configuration (to be exposed via the MISP user-interface), you can define those in the moduleconfig value returned by the version function. - -~~~python -# config fields that your code expects from the site admin -moduleconfig = ["apikey", "event_limit"] - -def version(): - moduleinfo['config'] = moduleconfig - return moduleinfo -~~~ - - -When you do this a config array is added to the meta-data output containing all the potential configuration values: - -~~~ -"meta": { - "description": "PassiveTotal expansion service to expand values with multiple Passive DNS sources", - "config": [ - "username", - "password" - ], - "module-type": [ - "expansion", - "hover" - ], - -... -~~~ - - -If you want to use the configuration values set in the web interface they are stored in the key `config` in the JSON object passed to the handler. - -~~~ -def handler(q=False): - - # Check if we were given a configuration - config = q.get("config", {}) - - # Find out if there is a username field - username = config.get("username", None) -~~~ - - -### handler - -The function which accepts a JSON document to expand the values and return a dictionary of the expanded values. - -~~~python -def handler(q=False): - "Fully functional rot-13 encoder" - if q is False: - return False - request = json.loads(q) - src = request.get('ip-src') - if src is None: - # Return an error message - return {'error': "A source IP is required"} - else: - return {'results': - codecs.encode(src, "rot-13")} -~~~ - -#### export module - -For an export module, the `request["data"]` object corresponds to a list of events (dictionaries) to handle. - -Iterating over events attributes is performed using their `Attribute` key. - -~~~python -... -for event in request["data"]: - for attribute in event["Attribute"]: - # do stuff w/ attribute['type'], attribute['value'], ... -... - -### Returning Binary Data - -If you want to return a file or other data you need to add a data attribute. - -~~~python -{"results": {"values": "filename.txt", - "types": "attachment", - "data" : base64.b64encode() # base64 encode your data first - "comment": "This is an attachment"}} -~~~ - -If the binary file is malware you can use 'malware-sample' as the type. If you do this the malware sample will be automatically zipped and password protected ('infected') after being uploaded. - - -~~~python -{"results": {"values": "filename.txt", - "types": "malware-sample", - "data" : base64.b64encode() # base64 encode your data first - "comment": "This is an attachment"}} -~~~ - -[To learn more about how data attributes are processed you can read the processing code here.](https://github.com/MISP/PyMISP/blob/4f230c9299ad9d2d1c851148c629b61a94f3f117/pymisp/mispevent.py#L185-L200) - - -### Module type - -A MISP module can be of four types: - -- **expansion** - service related to an attribute that can be used to extend and update an existing event. -- **hover** - service related to an attribute to provide additional information to the users without updating the event. -- **import** - service related to importing and parsing an external object that can be used to extend an existing event. -- **export** - service related to exporting an object, event, or data. - -module-type is an array where the list of supported types can be added. - -## Testing your modules? - -MISP uses the **modules** function to discover the available MISP modules and their supported MISP attributes: - -~~~ -% curl -s http://127.0.0.1:6666/modules | jq . -[ - { - "name": "passivetotal", - "type": "expansion", - "mispattributes": { - "input": [ - "hostname", - "domain", - "ip-src", - "ip-dst" - ], - "output": [ - "ip-src", - "ip-dst", - "hostname", - "domain" - ] - }, - "meta": { - "description": "PassiveTotal expansion service to expand values with multiple Passive DNS sources", - "config": [ - "username", - "password" - ], - "author": "Alexandre Dulaunoy", - "version": "0.1" - } - }, - { - "name": "sourcecache", - "type": "expansion", - "mispattributes": { - "input": [ - "link" - ], - "output": [ - "link" - ] - }, - "meta": { - "description": "Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page.", - "author": "Alexandre Dulaunoy", - "version": "0.1" - } - }, - { - "name": "dns", - "type": "expansion", - "mispattributes": { - "input": [ - "hostname", - "domain" - ], - "output": [ - "ip-src", - "ip-dst" - ] - }, - "meta": { - "description": "Simple DNS expansion service to resolve IP address from MISP attributes", - "author": "Alexandre Dulaunoy", - "version": "0.1" - } - } -] - -~~~ - -The MISP module service returns the available modules in a JSON array containing each module name along with their supported input attributes. - -Based on this information, a query can be built in a JSON format and saved as body.json: - -~~~json -{ - "hostname": "www.foo.be", - "module": "dns" -} -~~~ - -Then you can POST this JSON format query towards the MISP object server: - -~~~bash -curl -s http://127.0.0.1:6666/query -H "Content-Type: application/json" --data @body.json -X POST -~~~ - -The module should output the following JSON: - -~~~json -{ - "results": [ - { - "types": [ - "ip-src", - "ip-dst" - ], - "values": [ - "188.65.217.78" - ] - } - ] -} -~~~ - -It is also possible to restrict the category options of the resolved attributes by passing a list of categories along (optional): - -~~~json -{ - "results": [ - { - "types": [ - "ip-src", - "ip-dst" - ], - "values": [ - "188.65.217.78" - ], - "categories": [ - "Network activity", - "Payload delivery" - ] - } - ] -} -~~~ - -For both the type and the category lists, the first item in the list will be the default setting on the interface. - -### Enable your module in the web interface - -For a module to be activated in the MISP web interface it must be enabled in the "Plugin Settings. - -Go to "Administration > Server Settings" in the top menu -- Go to "Plugin Settings" in the top "tab menu bar" -- Click on the name of the type of module you have created to expand the list of plugins to show your module. -- Find the name of your plugin's "enabled" value in the Setting Column. -"Plugin.[MODULE NAME]_enabled" -- Double click on its "Value" column - -~~~ -Priority Setting Value Description Error Message -Recommended Plugin.Import_ocr_enabled false Enable or disable the ocr module. Value not set. -~~~ - -- Use the drop-down to set the enabled value to 'true' - -~~~ -Priority Setting Value Description Error Message -Recommended Plugin.Import_ocr_enabled true Enable or disable the ocr module. Value not set. -~~~ - -### Set any other required settings for your module - -In this same menu set any other plugin settings that are required for testing. - - - -## Documentation - -In order to provide documentation about some modules that require specific input / output / configuration, the [doc](https://github.com/MISP/misp-modules/tree/master/doc) directory contains detailed information about the general purpose, requirements, features, input and output of each of these modules: - -- ***description** - quick description of the general purpose of the module, as the one given by the moduleinfo -- **requirements** - special libraries needed to make the module work -- **features** - description of the way to use the module, with the required MISP features to make the module give the intended result -- **references** - link(s) giving additional information about the format concerned in the module -- **input** - description of the format of data used in input -- **output** - description of the format given as the result of the module execution - -In addition to the module documentation please add your module to [docs/index.md](https://github.com/MISP/misp-modules/tree/master/docs/index.md). - -There are also [complementary slides](https://www.misp-project.org/misp-training/3.1-misp-modules.pdf) for the creation of MISP modules. - - -## Tips for developers creating modules - -Download a pre-built virtual image from the [MISP training materials](https://www.circl.lu/services/misp-training-materials/). - -- Create a Host-Only adapter in VirtualBox -- Set your Misp OVA to that Host-Only adapter -- Start the virtual machine -- Get the IP address of the virutal machine -- SSH into the machine (Login info on training page) -- Go into the misp-modules directory - -~~~bash -cd /usr/local/src/misp-modules -~~~ - -Set the git repo to your fork and checkout your development branch. If you SSH'ed in as the misp user you will have to use sudo. - -~~~bash -sudo git remote set-url origin https://github.com/YourRepo/misp-modules.git -sudo git pull -sudo git checkout MyModBranch -~~~ - -Remove the contents of the build directory and re-install misp-modules. - -~~~python -sudo rm -fr build/* -sudo pip3 install --upgrade . -~~~ - -SSH in with a different terminal and run `misp-modules` with debugging enabled. - -~~~python -sudo killall misp-modules -misp-modules -d -~~~ - - -In your original terminal you can now run your tests manually and see any errors that arrive - -~~~bash -cd tests/ -curl -s http://127.0.0.1:6666/query -H "Content-Type: application/json" --data @MY_TEST_FILE.json -X POST -cd ../ -~~~ diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 35681f69..00000000 --- a/docs/index.md +++ /dev/null @@ -1,122 +0,0 @@ -# Home - -[![Build Status](https://travis-ci.org/MISP/misp-modules.svg?branch=master)](https://travis-ci.org/MISP/misp-modules) -[![Coverage Status](https://coveralls.io/repos/github/MISP/misp-modules/badge.svg?branch=master)](https://coveralls.io/github/MISP/misp-modules?branch=master) -[![codecov](https://codecov.io/gh/MISP/misp-modules/branch/main/graph/badge.svg)](https://codecov.io/gh/MISP/misp-modules) -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%MISP%2Fmisp-modules.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FMISP%2Fmisp-modules?ref=badge_shield) - -MISP modules are autonomous modules that can be used for expansion and other services in [MISP](https://github.com/MISP/MISP). - -The modules are written in Python 3 following a simple API interface. The objective is to ease the extensions of MISP functionalities -without modifying core components. The API is available via a simple REST API which is independent from MISP installation or configuration. - -MISP modules support is included in MISP starting from version `2.4.28`. - -For more information: [Extending MISP with Python modules](https://www.circl.lu/assets/files/misp-training/switch2016/2-misp-modules.pdf) slides from MISP training. - - -## Existing MISP modules - -### Expansion modules - -* [Backscatter.io](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/backscatter_io.py) - a hover and expansion module to expand an IP address with mass-scanning observations. -* [BGP Ranking](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/bgpranking.py) - a hover and expansion module to expand an AS number with the ASN description, its history, and position in BGP Ranking. -* [BTC scam check](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_scam_check.py) - An expansion hover module to instantly check if a BTC address has been abused. -* [BTC transactions](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_steroids.py) - An expansion hover module to get a blockchain balance and the transactions from a BTC address in MISP. -* [CIRCL Passive DNS](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivedns.py) - a hover and expansion module to expand hostname and IP addresses with passive DNS information. -* [CIRCL Passive SSL](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivessl.py) - a hover and expansion module to expand IP addresses with the X.509 certificate seen. -* [countrycode](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/countrycode.py) - a hover module to tell you what country a URL belongs to. -* [CrowdStrike Falcon](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdstrike_falcon.py) - an expansion module to expand using CrowdStrike Falcon Intel Indicator API. -* [CVE](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve.py) - a hover module to give more information about a vulnerability (CVE). -* [CVE advanced](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve_advanced.py) - An expansion module to query the CIRCL CVE search API for more information about a vulnerability (CVE). -* [Cuckoo submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cuckoo_submit.py) - A hover module to submit malware sample, url, attachment, domain to Cuckoo Sandbox. -* [DBL Spamhaus](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dbl_spamhaus.py) - a hover module to check Spamhaus DBL for a domain name. -* [DNS](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dns.py) - a simple module to resolve MISP attributes like hostname and domain to expand IP addresses attributes. -* [docx-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/docx-enrich.py) - an enrichment module to get text out of Word document into MISP (using free-text parser). -* [DomainTools](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/domaintools.py) - a hover and expansion module to get information from [DomainTools](http://www.domaintools.com/) whois. -* [EUPI](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eupi.py) - a hover and expansion module to get information about an URL from the [Phishing Initiative project](https://phishing-initiative.eu/?lang=en). -* [EQL](misp_modules/modules/expansion/eql.py) - an expansion module to generate event query language (EQL) from an attribute. [Event Query Language](https://eql.readthedocs.io/en/latest/) -* [Farsight DNSDB Passive DNS](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/farsight_passivedns.py) - a hover and expansion module to expand hostname and IP addresses with passive DNS information. -* [GeoIP](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_country.py) - a hover and expansion module to get GeoIP information from geolite/maxmind. -* [Greynoise](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/greynoise.py) - a hover to get information from greynoise. -* [hashdd](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashdd.py) - a hover module to check file hashes against [hashdd.com](http://www.hashdd.com) including NSLR dataset. -* [hibp](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hibp.py) - a hover module to lookup against Have I Been Pwned? -* [intel471](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intel471.py) - an expansion module to get info from [Intel471](https://intel471.com). -* [IPASN](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipasn.py) - a hover and expansion to get the BGP ASN of an IP address. -* [iprep](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/iprep.py) - an expansion module to get IP reputation from packetmail.net. -* [Joe Sandbox submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py) - Submit files and URLs to Joe Sandbox. -* [Joe Sandbox query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) - Query Joe Sandbox with the link of an analysis and get the parsed data. -* [macaddress.io](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macaddress_io.py) - a hover module to retrieve vendor details and other information regarding a given MAC address or an OUI from [MAC address Vendor Lookup](https://macaddress.io). See [integration tutorial here](https://macaddress.io/integrations/MISP-module). -* [macvendors](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macvendors.py) - a hover module to retrieve mac vendor information. -* [ocr-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ocr-enrich.py) - an enrichment module to get OCRized data from images into MISP. -* [ods-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ods-enrich.py) - an enrichment module to get text out of OpenOffice spreadsheet document into MISP (using free-text parser). -* [odt-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/odt-enrich.py) - an enrichment module to get text out of OpenOffice document into MISP (using free-text parser). -* [onyphe](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe.py) - a modules to process queries on Onyphe. -* [onyphe_full](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe_full.py) - a modules to process full queries on Onyphe. -* [OTX](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/otx.py) - an expansion module for [OTX](https://otx.alienvault.com/). -* [passivetotal](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passivetotal.py) - a [passivetotal](https://www.passivetotal.org/) module that queries a number of different PassiveTotal datasets. -* [pdf-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pdf-enrich.py) - an enrichment module to extract text from PDF into MISP (using free-text parser). -* [pptx-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pptx-enrich.py) - an enrichment module to get text out of PowerPoint document into MISP (using free-text parser). -* [qrcode](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qrcode.py) - a module decode QR code, barcode and similar codes from an image and enrich with the decoded values. -* [rbl](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/rbl.py) - a module to get RBL (Real-Time Blackhost List) values from an attribute. -* [reversedns](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/reversedns.py) - Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes. -* [securitytrails](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/securitytrails.py) - an expansion module for [securitytrails](https://securitytrails.com/). -* [shodan](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/shodan.py) - a minimal [shodan](https://www.shodan.io/) expansion module. -* [Sigma queries](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_queries.py) - Experimental expansion module querying a sigma rule to convert it into all the available SIEM signatures. -* [Sigma syntax validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_syntax_validator.py) - Sigma syntax validator. -* [sourcecache](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sourcecache.py) - a module to cache a specific link from a MISP instance. -* [stairwell](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stairwell.py) - an expansion module to enrich hash observables with the Stairwell API -* [STIX2 pattern syntax validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py) - a module to check a STIX2 pattern syntax. -* [ThreatCrowd](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatcrowd.py) - an expansion module for [ThreatCrowd](https://www.threatcrowd.org/). -* [threatminer](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatminer.py) - an expansion module to expand from [ThreatMiner](https://www.threatminer.org/). -* [urlhaus](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlhaus.py) - Query urlhaus to get additional data about a domain, hash, hostname, ip or url. -* [urlscan](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlscan.py) - an expansion module to query [urlscan.io](https://urlscan.io). -* [virustotal](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal.py) - an expansion module to query the [VirusTotal](https://www.virustotal.com/gui/home) API with a high request rate limit required. (More details about the API: [here](https://developers.virustotal.com/reference)) -* [virustotal_public](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_public.py) - an expansion module to query the [VirusTotal](https://www.virustotal.com/gui/home) API with a public key and a low request rate limit. (More details about the API: [here](https://developers.virustotal.com/reference)) -* [VMray](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmray_submit.py) - a module to submit a sample to VMray. -* [VulnDB](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulndb.py) - a module to query [VulnDB](https://www.riskbasedsecurity.com/). -* [Vulners](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulners.py) - an expansion module to expand information about CVEs using Vulners API. -* [Vysion](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vysion.py) - an expansion module to add dark web intelligence using Vysion API. -* [whois](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whois.py) - a module to query a local instance of [uwhois](https://github.com/rafiot/uwhoisd). -* [wikidata](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/wiki.py) - a [wikidata](https://www.wikidata.org) expansion module. -* [xforce](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xforceexchange.py) - an IBM X-Force Exchange expansion module. -* [xlsx-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xlsx-enrich.py) - an enrichment module to get text out of an Excel document into MISP (using free-text parser). -* [YARA query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_query.py) - a module to create YARA rules from single hash attributes. -* [YARA syntax validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_syntax_validator.py) - YARA syntax validator. - -### Export modules - -* [CEF](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cef_export.py) module to export Common Event Format (CEF). -* [Cisco FireSight Manager ACL rule](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py) module to export as rule for the Cisco FireSight manager ACL. -* [GoAML export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/goamlexport.py) module to export in [GoAML format](http://goaml.unodc.org/goaml/en/index.html). -* [Lite Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/liteexport.py) module to export a lite event. -* [Mass EQL Export](misp_modules/modules/export_mod/mass_eql_export.py) module to export applicable attributes from an event to a mass EQL query. -* [PDF export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/pdfexport.py) module to export an event in PDF. -* [Nexthink query format](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/nexthinkexport.py) module to export in Nexthink query format. -* [osquery](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/osqueryexport.py) module to export in [osquery](https://osquery.io/) query format. -* [ThreatConnect](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threat_connect_export.py) module to export in ThreatConnect CSV format. -* [ThreatStream](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threatStream_misp_export.py) module to export in ThreatStream format. - -### Import modules - -* [CSV import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/csvimport.py) Customizable CSV import module. -* [Cuckoo JSON](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cuckooimport.py) Cuckoo JSON import. -* [Email Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/email_import.py) Email import module for MISP to import basic metadata. -* [GoAML import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/goamlimport.py) Module to import [GoAML](http://goaml.unodc.org/goaml/en/index.html) XML format. -* [Joe Sandbox import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/joe_import.py) Parse data from a Joe Sandbox json report. -* [OCR](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/ocr.py) Optical Character Recognition (OCR) module for MISP to import attributes from images, scan or faxes. -* [OpenIOC](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/openiocimport.py) OpenIOC import based on PyMISP library. -* [ThreatAnalyzer](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/threatanalyzer_import.py) - An import module to process ThreatAnalyzer archive.zip/analysis.json sandbox exports. -* [VMRay](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_import.py) - An import module to process VMRay export. - - -## How to contribute your own module? - -Fork the project, add your module, test it and make a pull-request. Modules can be also private as you can add a module in your own MISP installation. -For further information please see [Contribute](contribute/). - - -## Licenses -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%MISP%2Fmisp-modules.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FMISP%2Fmisp-modules?ref=badge_large) - -For further Information see also the [license file](license/). diff --git a/docs/install.md b/docs/install.md deleted file mode 100644 index 3eed0f49..00000000 --- a/docs/install.md +++ /dev/null @@ -1,192 +0,0 @@ -## How to install and start MISP modules (in a Python virtualenv)? - -~~~~bash -SUDO_WWW="sudo -u www-data" - -sudo apt-get install -y \ - git \ - libpq5 \ - libjpeg-dev \ - tesseract-ocr \ - libpoppler-cpp-dev \ - imagemagick virtualenv \ - libopencv-dev \ - zbar-tools \ - libzbar0 \ - libzbar-dev \ - libfuzzy-dev \ - libcaca-dev - -# BEGIN with virtualenv: -$SUDO_WWW virtualenv -p python3 /var/www/MISP/venv -# END with virtualenv - -cd /usr/local/src/ -# Ideally you add your user to the staff group and make /usr/local/src group writeable, below follows an example with user misp -sudo adduser misp staff -sudo chmod 2775 /usr/local/src -sudo chown root:staff /usr/local/src -git clone https://github.com/MISP/misp-modules.git -git clone git://github.com/stricaud/faup.git faup -git clone git://github.com/stricaud/gtcaca.git gtcaca - -# Install gtcaca/faup -cd gtcaca -mkdir -p build -cd build -cmake .. && make -sudo make install -cd ../../faup -mkdir -p build -cd build -cmake .. && make -sudo make install -sudo ldconfig - -cd ../../misp-modules - -# BEGIN with virtualenv: -$SUDO_WWW /var/www/MISP/venv/bin/pip install -I -r REQUIREMENTS -$SUDO_WWW /var/www/MISP/venv/bin/pip install . -# END with virtualenv - -# BEGIN without virtualenv: -sudo pip install -I -r REQUIREMENTS -sudo pip install . -# END without virtualenv - -# Start misp-modules as a service -sudo cp etc/systemd/system/misp-modules.service /etc/systemd/system/ -sudo systemctl daemon-reload -sudo systemctl enable --now misp-modules -/var/www/MISP/venv/bin/misp-modules -l 127.0.0.1 -s & #to start the modules -~~~~ - -## How to install and start MISP modules on RHEL-based distributions ? - -As of this writing, the official RHEL repositories only contain Ruby 2.0.0 and Ruby 2.1 or higher is required. As such, this guide installs Ruby 2.2 from the SCL repository. - -~~~~bash -SUDO_WWW="sudo -u apache" -sudo yum install \ - rh-ruby22 \ - openjpeg-devel \ - rubygem-rouge \ - rubygem-asciidoctor \ - zbar-devel \ - opencv-devel \ - gcc-c++ \ - pkgconfig \ - poppler-cpp-devel \ - python-devel \ - redhat-rpm-config -cd /usr/local/src/ -sudo git clone https://github.com/MISP/misp-modules.git -cd misp-modules -$SUDO_WWW /usr/bin/scl enable rh-python36 "virtualenv -p python3 /var/www/MISP/venv" -$SUDO_WWW /var/www/MISP/venv/bin/pip install -U -I -r REQUIREMENTS -$SUDO_WWW /var/www/MISP/venv/bin/pip install -U . -~~~~ - -Create the service file /etc/systemd/system/misp-modules.service : - -~~~~bash -echo "[Unit] -Description=MISP's modules -After=misp-workers.service - -[Service] -Type=simple -User=apache -Group=apache -ExecStart=/usr/bin/scl enable rh-python36 rh-ruby22 '/var/www/MISP/venv/bin/misp-modules –l 127.0.0.1 –s' -Restart=always -RestartSec=10 - -[Install] -WantedBy=multi-user.target" | sudo tee /etc/systemd/system/misp-modules.service -~~~~ - -The After=misp-workers.service must be changed or removed if you have not created a misp-workers service. Then, enable the misp-modules service and start it: - -~~~~bash -systemctl daemon-reload -systemctl enable --now misp-modules -~~~~ - -## How to use an MISP modules Docker container - -### Docker build - -~~~~bash -docker build -t misp-modules \ - --build-arg BUILD_DATE=$(date -u +"%Y-%m-%d") \ - docker/ -~~~~ - -### Docker run - -~~~~bash -# Start Redis -docker run --rm -d --name=misp-redis redis:alpine -# Start MISP-modules -docker run \ - --rm -d --name=misp-modules \ - -e REDIS_BACKEND=misp-redis \ - -e REDIS_PORT="6379" \ - -e REDIS_PW="" \ - -e REDIS_DATABASE="245" \ - -e MISP_MODULES_DEBUG="false" \ - dcso/misp-dockerized-misp-modules -~~~~ - -### Docker-compose - -~~~~yml -services: - misp-modules: - # https://hub.docker.com/r/dcso/misp-dockerized-misp-modules - image: dcso/misp-dockerized-misp-modules:3 - - # Local image: - #image: misp-modules - #build: - # context: docker/ - - environment: - # Redis - REDIS_BACKEND: misp-redis - REDIS_PORT: "6379" - REDIS_DATABASE: "245" - # System PROXY (OPTIONAL) - http_proxy: - https_proxy: - no_proxy: 0.0.0.0 - # Timezone (OPTIONAL) - TZ: Europe/Berlin - # MISP-Modules (OPTIONAL) - MISP_MODULES_DEBUG: "false" - # Logging options (OPTIONAL) - LOG_SYSLOG_ENABLED: "no" - misp-redis: - # https://hub.docker.com/_/redis or alternative https://hub.docker.com/r/dcso/misp-dockerized-redis/ - image: redis:alpine -~~~~ - -## Install misp-module on an offline instance. -First, you need to grab all necessary packages for example like this : - -Use pip wheel to create an archive -~~~ -mkdir misp-modules-offline -pip3 wheel -r REQUIREMENTS shodan --wheel-dir=./misp-modules-offline -tar -cjvf misp-module-bundeled.tar.bz2 ./misp-modules-offline/* -~~~ -On offline machine : -~~~ -mkdir misp-modules-bundle -tar xvf misp-module-bundeled.tar.bz2 -C misp-modules-bundle -cd misp-modules-bundle -ls -1|while read line; do sudo pip3 install --force-reinstall --ignore-installed --upgrade --no-index --no-deps ${line};done -~~~ -Next you can follow standard install procedure. diff --git a/docs/license.md b/docs/license.md deleted file mode 100644 index dbbe3558..00000000 --- a/docs/license.md +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. diff --git a/docs/logos/apivoid.png b/docs/logos/apivoid.png deleted file mode 100644 index e4f84a7c..00000000 Binary files a/docs/logos/apivoid.png and /dev/null differ diff --git a/docs/logos/assemblyline.png b/docs/logos/assemblyline.png deleted file mode 100644 index bda4518a..00000000 Binary files a/docs/logos/assemblyline.png and /dev/null differ diff --git a/docs/logos/backscatter_io.png b/docs/logos/backscatter_io.png deleted file mode 100644 index 09731128..00000000 Binary files a/docs/logos/backscatter_io.png and /dev/null differ diff --git a/docs/logos/bitcoin.png b/docs/logos/bitcoin.png deleted file mode 100644 index e80ad6d1..00000000 Binary files a/docs/logos/bitcoin.png and /dev/null differ diff --git a/docs/logos/circl.png b/docs/logos/circl.png deleted file mode 100644 index 516678de..00000000 Binary files a/docs/logos/circl.png and /dev/null differ diff --git a/docs/logos/cisco.png b/docs/logos/cisco.png deleted file mode 100644 index 87b863b7..00000000 Binary files a/docs/logos/cisco.png and /dev/null differ diff --git a/docs/logos/cluster25.png b/docs/logos/cluster25.png deleted file mode 100644 index e201ca3d..00000000 Binary files a/docs/logos/cluster25.png and /dev/null differ diff --git a/docs/logos/crowdsec.png b/docs/logos/crowdsec.png deleted file mode 100644 index 6b2953da..00000000 Binary files a/docs/logos/crowdsec.png and /dev/null differ diff --git a/docs/logos/crowdstrike.png b/docs/logos/crowdstrike.png deleted file mode 100644 index 359cb01a..00000000 Binary files a/docs/logos/crowdstrike.png and /dev/null differ diff --git a/docs/logos/cuckoo.png b/docs/logos/cuckoo.png deleted file mode 100644 index 57cf35a5..00000000 Binary files a/docs/logos/cuckoo.png and /dev/null differ diff --git a/docs/logos/cve.png b/docs/logos/cve.png deleted file mode 100644 index 315ccd81..00000000 Binary files a/docs/logos/cve.png and /dev/null differ diff --git a/docs/logos/cytomic_orion.png b/docs/logos/cytomic_orion.png deleted file mode 100644 index 45704e92..00000000 Binary files a/docs/logos/cytomic_orion.png and /dev/null differ diff --git a/docs/logos/defender_endpoing.png b/docs/logos/defender_endpoing.png deleted file mode 100644 index efc7aced..00000000 Binary files a/docs/logos/defender_endpoing.png and /dev/null differ diff --git a/docs/logos/docx.png b/docs/logos/docx.png deleted file mode 100644 index 018d2c1a..00000000 Binary files a/docs/logos/docx.png and /dev/null differ diff --git a/docs/logos/domaintools.png b/docs/logos/domaintools.png deleted file mode 100644 index 69965e1b..00000000 Binary files a/docs/logos/domaintools.png and /dev/null differ diff --git a/docs/logos/eql.png b/docs/logos/eql.png deleted file mode 100644 index 4cddb912..00000000 Binary files a/docs/logos/eql.png and /dev/null differ diff --git a/docs/logos/eupi.png b/docs/logos/eupi.png deleted file mode 100644 index 18006572..00000000 Binary files a/docs/logos/eupi.png and /dev/null differ diff --git a/docs/logos/farsight.png b/docs/logos/farsight.png deleted file mode 100644 index 31a73c10..00000000 Binary files a/docs/logos/farsight.png and /dev/null differ diff --git a/docs/logos/goAML.jpg b/docs/logos/goAML.jpg deleted file mode 100644 index 4e938eed..00000000 Binary files a/docs/logos/goAML.jpg and /dev/null differ diff --git a/docs/logos/google.png b/docs/logos/google.png deleted file mode 100644 index 492f44c2..00000000 Binary files a/docs/logos/google.png and /dev/null differ diff --git a/docs/logos/greynoise.png b/docs/logos/greynoise.png deleted file mode 100644 index 0c57e645..00000000 Binary files a/docs/logos/greynoise.png and /dev/null differ diff --git a/docs/logos/hibp.png b/docs/logos/hibp.png deleted file mode 100644 index 849ccf27..00000000 Binary files a/docs/logos/hibp.png and /dev/null differ diff --git a/docs/logos/hyas.png b/docs/logos/hyas.png deleted file mode 100644 index 42acf22f..00000000 Binary files a/docs/logos/hyas.png and /dev/null differ diff --git a/docs/logos/intel471.png b/docs/logos/intel471.png deleted file mode 100644 index 08264e94..00000000 Binary files a/docs/logos/intel471.png and /dev/null differ diff --git a/docs/logos/intelmq.png b/docs/logos/intelmq.png deleted file mode 100644 index fad627cc..00000000 Binary files a/docs/logos/intelmq.png and /dev/null differ diff --git a/docs/logos/ip2locationio.png b/docs/logos/ip2locationio.png deleted file mode 100644 index 85581af8..00000000 Binary files a/docs/logos/ip2locationio.png and /dev/null differ diff --git a/docs/logos/ipinfo.png b/docs/logos/ipinfo.png deleted file mode 100644 index 9dedd955..00000000 Binary files a/docs/logos/ipinfo.png and /dev/null differ diff --git a/docs/logos/ipqualityscore.png b/docs/logos/ipqualityscore.png deleted file mode 100644 index da52d966..00000000 Binary files a/docs/logos/ipqualityscore.png and /dev/null differ diff --git a/docs/logos/joesandbox.png b/docs/logos/joesandbox.png deleted file mode 100644 index 8072f6ea..00000000 Binary files a/docs/logos/joesandbox.png and /dev/null differ diff --git a/docs/logos/lastline.png b/docs/logos/lastline.png deleted file mode 100644 index 6bffe77f..00000000 Binary files a/docs/logos/lastline.png and /dev/null differ diff --git a/docs/logos/macaddress_io.png b/docs/logos/macaddress_io.png deleted file mode 100644 index e77f4552..00000000 Binary files a/docs/logos/macaddress_io.png and /dev/null differ diff --git a/docs/logos/macvendors.png b/docs/logos/macvendors.png deleted file mode 100644 index 3316ea39..00000000 Binary files a/docs/logos/macvendors.png and /dev/null differ diff --git a/docs/logos/maxmind.png b/docs/logos/maxmind.png deleted file mode 100644 index 8f8a6c6e..00000000 Binary files a/docs/logos/maxmind.png and /dev/null differ diff --git a/docs/logos/nexthink.svg b/docs/logos/nexthink.svg deleted file mode 100644 index f18ba8fe..00000000 --- a/docs/logos/nexthink.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - nexthink - Created with Sketch. - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/logos/ods.png b/docs/logos/ods.png deleted file mode 100644 index 19b42f1f..00000000 Binary files a/docs/logos/ods.png and /dev/null differ diff --git a/docs/logos/odt.png b/docs/logos/odt.png deleted file mode 100644 index d177a217..00000000 Binary files a/docs/logos/odt.png and /dev/null differ diff --git a/docs/logos/onyphe.jpg b/docs/logos/onyphe.jpg deleted file mode 100644 index cd16f760..00000000 Binary files a/docs/logos/onyphe.jpg and /dev/null differ diff --git a/docs/logos/osquery.png b/docs/logos/osquery.png deleted file mode 100644 index 2e4320ee..00000000 Binary files a/docs/logos/osquery.png and /dev/null differ diff --git a/docs/logos/otx.png b/docs/logos/otx.png deleted file mode 100644 index eae32c15..00000000 Binary files a/docs/logos/otx.png and /dev/null differ diff --git a/docs/logos/passivedns.png b/docs/logos/passivedns.png deleted file mode 100644 index 4959a847..00000000 Binary files a/docs/logos/passivedns.png and /dev/null differ diff --git a/docs/logos/passivessh.png b/docs/logos/passivessh.png deleted file mode 100644 index 42c81906..00000000 Binary files a/docs/logos/passivessh.png and /dev/null differ diff --git a/docs/logos/passivessl.png b/docs/logos/passivessl.png deleted file mode 100644 index e92c87d0..00000000 Binary files a/docs/logos/passivessl.png and /dev/null differ diff --git a/docs/logos/passivetotal.png b/docs/logos/passivetotal.png deleted file mode 100644 index 87cef695..00000000 Binary files a/docs/logos/passivetotal.png and /dev/null differ diff --git a/docs/logos/pdf.jpg b/docs/logos/pdf.jpg deleted file mode 100644 index 74f4297d..00000000 Binary files a/docs/logos/pdf.jpg and /dev/null differ diff --git a/docs/logos/pptx.png b/docs/logos/pptx.png deleted file mode 100644 index 11b21337..00000000 Binary files a/docs/logos/pptx.png and /dev/null differ diff --git a/docs/logos/qintel.png b/docs/logos/qintel.png deleted file mode 100644 index fa3af768..00000000 Binary files a/docs/logos/qintel.png and /dev/null differ diff --git a/docs/logos/recordedfuture.png b/docs/logos/recordedfuture.png deleted file mode 100644 index a208c045..00000000 Binary files a/docs/logos/recordedfuture.png and /dev/null differ diff --git a/docs/logos/securitytrails.png b/docs/logos/securitytrails.png deleted file mode 100644 index 072dac54..00000000 Binary files a/docs/logos/securitytrails.png and /dev/null differ diff --git a/docs/logos/shodan.png b/docs/logos/shodan.png deleted file mode 100644 index 7de068e9..00000000 Binary files a/docs/logos/shodan.png and /dev/null differ diff --git a/docs/logos/sigma.png b/docs/logos/sigma.png deleted file mode 100644 index 0bd0db14..00000000 Binary files a/docs/logos/sigma.png and /dev/null differ diff --git a/docs/logos/sophoslabs_intelix.svg b/docs/logos/sophoslabs_intelix.svg deleted file mode 100644 index 9fe952f6..00000000 --- a/docs/logos/sophoslabs_intelix.svg +++ /dev/null @@ -1,32 +0,0 @@ - - - - CC812F0D-F9F0-4D68-9347-3579CDA181A3 - Created with sketchtool. - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/logos/spamhaus.jpg b/docs/logos/spamhaus.jpg deleted file mode 100644 index 4c868e46..00000000 Binary files a/docs/logos/spamhaus.jpg and /dev/null differ diff --git a/docs/logos/stix.png b/docs/logos/stix.png deleted file mode 100644 index e8b82414..00000000 Binary files a/docs/logos/stix.png and /dev/null differ diff --git a/docs/logos/threatconnect.png b/docs/logos/threatconnect.png deleted file mode 100644 index 4c8a5b15..00000000 Binary files a/docs/logos/threatconnect.png and /dev/null differ diff --git a/docs/logos/threatcrowd.png b/docs/logos/threatcrowd.png deleted file mode 100644 index 94eacfc5..00000000 Binary files a/docs/logos/threatcrowd.png and /dev/null differ diff --git a/docs/logos/threatminer.png b/docs/logos/threatminer.png deleted file mode 100644 index d7ac96e2..00000000 Binary files a/docs/logos/threatminer.png and /dev/null differ diff --git a/docs/logos/threatstream.png b/docs/logos/threatstream.png deleted file mode 100644 index eb3837ef..00000000 Binary files a/docs/logos/threatstream.png and /dev/null differ diff --git a/docs/logos/trustar.png b/docs/logos/trustar.png deleted file mode 100644 index d4ac5213..00000000 Binary files a/docs/logos/trustar.png and /dev/null differ diff --git a/docs/logos/urlhaus.png b/docs/logos/urlhaus.png deleted file mode 100644 index 3460d818..00000000 Binary files a/docs/logos/urlhaus.png and /dev/null differ diff --git a/docs/logos/urlscan.jpg b/docs/logos/urlscan.jpg deleted file mode 100644 index 52e24e24..00000000 Binary files a/docs/logos/urlscan.jpg and /dev/null differ diff --git a/docs/logos/variot.png b/docs/logos/variot.png deleted file mode 100644 index 717b7e71..00000000 Binary files a/docs/logos/variot.png and /dev/null differ diff --git a/docs/logos/virustotal.png b/docs/logos/virustotal.png deleted file mode 100644 index 935c5ccf..00000000 Binary files a/docs/logos/virustotal.png and /dev/null differ diff --git a/docs/logos/vmray.png b/docs/logos/vmray.png deleted file mode 100644 index e2e9fa17..00000000 Binary files a/docs/logos/vmray.png and /dev/null differ diff --git a/docs/logos/vmware_nsx.png b/docs/logos/vmware_nsx.png deleted file mode 100644 index 4d4ba96e..00000000 Binary files a/docs/logos/vmware_nsx.png and /dev/null differ diff --git a/docs/logos/vulndb.png b/docs/logos/vulndb.png deleted file mode 100644 index bfaf40f8..00000000 Binary files a/docs/logos/vulndb.png and /dev/null differ diff --git a/docs/logos/vulners.png b/docs/logos/vulners.png deleted file mode 100644 index ef9bab4c..00000000 Binary files a/docs/logos/vulners.png and /dev/null differ diff --git a/docs/logos/vysion.png b/docs/logos/vysion.png deleted file mode 100644 index e5fb194e..00000000 Binary files a/docs/logos/vysion.png and /dev/null differ diff --git a/docs/logos/wikidata.png b/docs/logos/wikidata.png deleted file mode 100644 index 0ffb4b15..00000000 Binary files a/docs/logos/wikidata.png and /dev/null differ diff --git a/docs/logos/xforce.png b/docs/logos/xforce.png deleted file mode 100644 index 96db659b..00000000 Binary files a/docs/logos/xforce.png and /dev/null differ diff --git a/docs/logos/xlsx.png b/docs/logos/xlsx.png deleted file mode 100644 index fbe6e13e..00000000 Binary files a/docs/logos/xlsx.png and /dev/null differ diff --git a/docs/logos/yara.png b/docs/logos/yara.png deleted file mode 100644 index c74c314a..00000000 Binary files a/docs/logos/yara.png and /dev/null differ diff --git a/docs/logos/yeti.png b/docs/logos/yeti.png deleted file mode 100644 index 46b77da0..00000000 Binary files a/docs/logos/yeti.png and /dev/null differ diff --git a/documentation/README.md b/documentation/README.md index fd7c3bd1..7f227a69 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -2,219 +2,339 @@ ## Expansion Modules -#### [apiosintds](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apiosintds.py) +#### [Abuse IPDB](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/abuseipdb.py) + +AbuseIPDB MISP expansion module +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/abuseipdb.py)] + +- **features**: +> + +- **config**: +> - api_key +> - max_age_in_days +> - abuse_threshold + +----- + +#### [OSINT DigitalSide](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apiosintds.py) On demand query API for OSINT.digitalside.it project. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apiosintds.py)] + - **features**: >The module simply queries the API of OSINT.digitalside.it with a domain, ip, url or hash attribute. > >The result of the query is then parsed to extract additional hashes or urls. A module parameters also allows to parse the hashes related to the urls. > >Furthermore, it is possible to cache the urls and hashes collected over the last 7 days by OSINT.digitalside.it + +- **config**: +> - STIX2_details +> - import_related +> - cache +> - cache_directory +> - cache_timeout_h +> - local_directory + - **input**: >A domain, ip, url or hash attribute. + - **output**: >Hashes and urls resulting from the query to OSINT.digitalside.it + - **references**: >https://osint.digitalside.it/#About + - **requirements**: >The apiosintDS python library to query the OSINT.digitalside.it API. ----- -#### [apivoid](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apivoid.py) +#### [APIVoid](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apivoid.py) Module to query APIVoid with some domain attributes. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apivoid.py)] + - **features**: >This module takes a domain name and queries API Void to get the related DNS records and the SSL certificates. It returns then those pieces of data as MISP objects that can be added to the event. > >To make it work, a valid API key and enough credits to proceed 2 queries (0.06 + 0.07 credits) are required. + +- **config**: +>apikey + - **input**: >A domain attribute. + - **output**: >DNS records and SSL certificates related to the domain. + - **references**: >https://www.apivoid.com/ + - **requirements**: >A valid APIVoid API key with enough credits to proceed 2 queries ----- -#### [assemblyline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_query.py) +#### [AssemblyLine Query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_query.py) A module tu query the AssemblyLine API with a submission ID to get the submission report and parse it. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_query.py)] + - **features**: >The module requires the address of the AssemblyLine server you want to query as well as your credentials used for this instance. Credentials include the used-ID and an API key or the password associated to the user-ID. > >The submission ID extracted from the submission link is then used to query AssemblyLine and get the full submission report. This report is parsed to extract file objects and the associated IPs, domains or URLs the files are connecting to. > >Some more data may be parsed in the future. + +- **config**: +> - apiurl +> - user_id +> - apikey +> - password +> - verifyssl + - **input**: >Link of an AssemblyLine submission report. + - **output**: >MISP attributes & objects parsed from the AssemblyLine submission. + - **references**: >https://www.cyber.gc.ca/en/assemblyline + - **requirements**: >assemblyline_client: Python library to query the AssemblyLine rest API. ----- -#### [assemblyline_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_submit.py) +#### [AssemblyLine Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_submit.py) A module to submit samples and URLs to AssemblyLine for advanced analysis, and return the link of the submission. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_submit.py)] + - **features**: >The module requires the address of the AssemblyLine server you want to query as well as your credentials used for this instance. Credentials include the user-ID and an API key or the password associated to the user-ID. > >If the sample or url is correctly submitted, you get then the link of the submission. + +- **config**: +> - apiurl +> - user_id +> - apikey +> - password +> - verifyssl + - **input**: >Sample, or url to submit to AssemblyLine. + - **output**: >Link of the report generated in AssemblyLine. + - **references**: >https://www.cyber.gc.ca/en/assemblyline + - **requirements**: >assemblyline_client: Python library to query the AssemblyLine rest API. ----- -#### [backscatter_io](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/backscatter_io.py) +#### [Backscatter.io](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/backscatter_io.py) -Query backscatter.io (https://backscatter.io/). +Backscatter.io module to bring mass-scanning observations into MISP. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/backscatter_io.py)] + - **features**: >The module takes a source or destination IP address as input and displays the information known by backscatter.io. + +- **config**: +>api_key + - **input**: >IP addresses. + - **output**: >Text containing a history of the IP addresses especially on scanning based on backscatter.io information . + - **references**: >https://pypi.org/project/backscatter/ + - **requirements**: >backscatter python library ----- -#### [bgpranking](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/bgpranking.py) - -Query BGP Ranking (https://bgpranking-ng.circl.lu/). -- **features**: ->The module takes an AS number attribute as input and displays its description as well as its ranking position in BGP Ranking for a given day. -- **input**: ->Autonomous system number. -- **output**: ->An asn object with its related bgp-ranking object. -- **references**: ->https://github.com/D4-project/BGP-Ranking/ -- **requirements**: ->pybgpranking python library - ------ - -#### [btc_scam_check](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_scam_check.py) +#### [BTC Scam Check](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_scam_check.py) An expansion hover module to query a special dns blacklist to check if a bitcoin address has been abused. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_scam_check.py)] + - **features**: >The module queries a dns blacklist directly with the bitcoin address and get a response if the address has been abused. + - **input**: >btc address attribute. + - **output**: >Text to indicate if the BTC address has been abused. + - **references**: >https://btcblack.it/ + - **requirements**: >dnspython3: dns python library ----- -#### [btc_steroids](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_steroids.py) +#### [BTC Steroids](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_steroids.py) An expansion hover module to get a blockchain balance from a BTC address in MISP. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_steroids.py)] + +- **features**: +> + - **input**: >btc address attribute. + - **output**: >Text to describe the blockchain balance and the transactions related to the btc address in input. ----- -#### [censys_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/censys_enrich.py) +#### [Censys Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/censys_enrich.py) An expansion module to enrich attributes in MISP by quering the censys.io API +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/censys_enrich.py)] + - **features**: >This module takes an IP, hostname or a certificate fingerprint and attempts to enrich it by querying the Censys API. + +- **config**: +> - api_id +> - api_secret + - **input**: >IP, domain or certificate fingerprint (md5, sha1 or sha256) + - **output**: >MISP objects retrieved from censys, including open ports, ASN, Location of the IP, x509 details + - **references**: >https://www.censys.io + - **requirements**: >API credentials to censys.io ----- -#### [circl_passivedns](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivedns.py) +#### [CIRCL Passive DNS](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivedns.py) Module to access CIRCL Passive DNS. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivedns.py)] + - **features**: >This module takes a hostname, domain or ip-address (ip-src or ip-dst) attribute as input, and queries the CIRCL Passive DNS REST API to get the asssociated passive dns entries and return them as MISP objects. > >To make it work a username and a password are thus required to authenticate to the CIRCL Passive DNS API. + +- **config**: +> - username +> - password + - **input**: >Hostname, domain, or ip-address attribute. + - **ouput**: >Passive DNS objects related to the input attribute. + - **references**: > - https://www.circl.lu/services/passive-dns/ > - https://datatracker.ietf.org/doc/draft-dulaunoy-dnsop-passive-dns-cof/ + - **requirements**: > - pypdns: Passive DNS python library > - A CIRCL passive DNS account with username & password ----- -#### [circl_passivessl](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivessl.py) +#### [CIRCL Passive SSL](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivessl.py) Modules to access CIRCL Passive SSL. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivessl.py)] + - **features**: >This module takes an ip-address (ip-src or ip-dst) attribute as input, and queries the CIRCL Passive SSL REST API to gather the related certificates and return the corresponding MISP objects. > >To make it work a username and a password are required to authenticate to the CIRCL Passive SSL API. + +- **config**: +> - username +> - password + - **input**: >IP address attribute. + - **output**: >x509 certificate objects seen by the IP address(es). + - **references**: >https://www.circl.lu/services/passive-ssl/ + - **requirements**: > - pypssl: Passive SSL python library > - A CIRCL passive SSL account with username & password ----- -#### [cluster25_expand](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cluster25_expand.py) +#### [ClaamAV](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/clamav.py) + +Submit file to ClamAV +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/clamav.py)] + +- **features**: +> + +- **config**: +>connection + +----- + +#### [Cluster25 Expand](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cluster25_expand.py) Module to query Cluster25 CTI. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cluster25_expand.py)] + - **features**: >This module takes a MISP attribute value as input to query the Cluster25CTI API. The result is then mapped into compatible MISP Objects and relative attributes. > + +- **config**: +> - api_id +> - apikey +> - base_url + - **input**: >An Indicator value of type included in the following list: >- domain @@ -231,79 +351,116 @@ Module to query Cluster25 CTI. >- btc >- xmr > ja3-fingerprint-md5 + - **output**: >A series of c25 MISP Objects with colletion of attributes mapped from Cluster25 CTI query result. + - **references**: > + - **requirements**: >A Cluster25 API access (API id & key) ----- -#### [countrycode](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/countrycode.py) +#### [Country Code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/countrycode.py) Module to expand country codes. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/countrycode.py)] + - **features**: >The module takes a domain or a hostname as input, and returns the country it belongs to. > >For non country domains, a list of the most common possible extensions is used. + - **input**: >Hostname or domain attribute. + - **output**: >Text with the country code the input belongs to. ----- -#### [cpe](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cpe.py) +#### [CPE Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cpe.py) An expansion module to query the CVE search API with a cpe code to get its related vulnerabilities. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cpe.py)] + - **features**: >The module takes a cpe attribute as input and queries the CVE search API to get its related vulnerabilities. >The list of vulnerabilities is then parsed and returned as vulnerability objects. > ->Users can use their own CVE search API url by defining a value to the custom_API_URL parameter. If no custom API url is given, the default cve.circl.lu api url is used. +>Users can use their own CVE search API url by defining a value to the custom_API_URL parameter. If no custom API url is given, the default vulnerability.circl.lu api url is used. > >In order to limit the amount of data returned by CVE serach, users can also the limit parameter. With the limit set, the API returns only the requested number of vulnerabilities, sorted from the highest cvss score to the lowest one. + +- **config**: +> - custom_API_URL +> - limit + - **input**: >CPE attribute. + - **output**: >The vulnerabilities related to the CPE. + - **references**: ->https://cve.circl.lu/api/ +>https://vulnerability.circl.lu/api/ ----- -#### [crowdsec](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdsec.py) +#### [CrowdSec CTI](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdsec.py) -Hover module to lookup an IP in CrowdSec's CTI +Module to access CrowdSec CTI API. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdsec.py)] + - **features**: >This module enables IP lookup from CrowdSec CTI API. It provides information about the IP, such as what kind of attacks it has been participant of as seen by CrowdSec's network. It also includes enrichment by CrowdSec like background noise score, aggressivity over time etc. + +- **config**: +> - api_key +> - add_reputation_tag +> - add_behavior_tag +> - add_classification_tag +> - add_mitre_technique_tag +> - add_cve_tag + - **input**: >An IP address. + - **output**: >IP Lookup information from CrowdSec CTI API + - **references**: > - https://www.crowdsec.net/ > - https://docs.crowdsec.net/docs/cti_api/getting_started > - https://app.crowdsec.net/ + - **requirements**: >A CrowdSec CTI API key. Get yours by following https://docs.crowdsec.net/docs/cti_api/getting_started/#getting-an-api-key ----- -#### [crowdstrike_falcon](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdstrike_falcon.py) +#### [CrowdStrike Falcon](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdstrike_falcon.py) -Module to query Crowdstrike Falcon. +Module to query CrowdStrike Falcon. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdstrike_falcon.py)] + - **features**: >This module takes a MISP attribute as input to query a CrowdStrike Falcon API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes. > >Please note that composite attributes composed by at least one of the input types mentionned below (domains, IPs, hostnames) are also supported. + +- **config**: +> - api_id +> - apikey + - **input**: >A MISP attribute included in the following list: >- domain @@ -326,6 +483,7 @@ Module to query Crowdstrike Falcon. >- user-agent >- whois-registrant-email >- x509-fingerprint-md5 + - **output**: >MISP attributes mapped after the CrowdStrike API has been queried, included in the following list: >- hostname @@ -342,155 +500,231 @@ Module to query Crowdstrike Falcon. >- url >- user-agent >- x509-fingerprint-md5 + - **references**: >https://www.crowdstrike.com/products/crowdstrike-falcon-faq/ + - **requirements**: >A CrowdStrike API access (API id & key) ----- -#### [cuckoo_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cuckoo_submit.py) +#### [Cuckoo Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cuckoo_submit.py) -An expansion module to submit files and URLs to Cuckoo Sandbox. +Submit files and URLs to Cuckoo Sandbox +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cuckoo_submit.py)] + - **features**: >The module takes a malware-sample, attachment, url or domain and submits it to Cuckoo Sandbox. > The returned task id can be used to retrieve results when the analysis completed. + +- **config**: +> - api_url +> - api_key + - **input**: >A malware-sample or attachment for files. A url or domain for URLs. + - **output**: >A text field containing 'Cuckoo task id: ' + - **references**: > - https://cuckoosandbox.org/ > - https://cuckoo.sh/docs/ + - **requirements**: >Access to a Cuckoo Sandbox API and an API key if the API requires it. (api_url and api_key) ----- -#### [cve](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve.py) +#### [CVE Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve.py) An expansion hover module to expand information about CVE id. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve.py)] + - **features**: >The module takes a vulnerability attribute as input and queries the CIRCL CVE search API to get information about the vulnerability as it is described in the list of CVEs. + +- **config**: +>custom_API + - **input**: >Vulnerability attribute. + - **output**: >Text giving information about the CVE related to the Vulnerability. + - **references**: -> - https://cve.circl.lu/ +> - https://vulnerability.circl.lu/ > - https://cve.mitre.org/ ----- -#### [cve_advanced](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve_advanced.py) +#### [CVE Advanced Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve_advanced.py) An expansion module to query the CIRCL CVE search API for more information about a vulnerability (CVE). +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve_advanced.py)] + - **features**: >The module takes a vulnerability attribute as input and queries the CIRCL CVE search API to gather additional information. > >The result of the query is then parsed to return additional information about the vulnerability, like its cvss score or some references, as well as the potential related weaknesses and attack patterns. > >The vulnerability additional data is returned in a vulnerability MISP object, and the related additional information are put into weakness and attack-pattern MISP objects. + +- **config**: +>custom_API + - **input**: >Vulnerability attribute. + - **output**: >Additional information about the vulnerability, such as its cvss score, some references, or the related weaknesses and attack patterns. + - **references**: -> - https://cve.circl.lu +> - https://vulnerability.circl.lu > - https://cve/mitre.org/ ----- -#### [cytomic_orion](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cytomic_orion.py) +#### [Cytomic Orion Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cytomic_orion.py) An expansion module to enrich attributes in MISP by quering the Cytomic Orion API +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cytomic_orion.py)] + - **features**: >This module takes an MD5 hash and searches for occurrences of this hash in the Cytomic Orion database. Returns observed files and machines. + +- **config**: +> - api_url +> - token_url +> - clientid +> - clientsecret +> - clientsecret +> - username +> - password +> - upload_timeframe +> - upload_tag +> - delete_tag +> - upload_ttlDays +> - upload_threat_level_id +> - limit_upload_events +> - limit_upload_attributes + - **input**: >MD5, hash of the sample / malware to search for. + - **output**: >MISP objects with sightings of the hash in Cytomic Orion. Includes files and machines. + - **references**: > - https://www.vanimpe.eu/2020/03/10/integrating-misp-and-cytomic-orion/ > - https://www.cytomicmodel.com/solutions/ + - **requirements**: >Access (license) to Cytomic Orion ----- -#### [dbl_spamhaus](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dbl_spamhaus.py) +#### [DBL Spamhaus Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dbl_spamhaus.py) -Module to check Spamhaus DBL for a domain name. +Checks Spamhaus DBL for a domain name. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dbl_spamhaus.py)] + - **features**: >This modules takes a domain or a hostname in input and queries the Domain Block List provided by Spamhaus to determine what kind of domain it is. > >DBL then returns a response code corresponding to a certain classification of the domain we display. If the queried domain is not in the list, it is also mentionned. > >Please note that composite MISP attributes containing domain or hostname are supported as well. + - **input**: >Domain or hostname attribute. + - **output**: >Information about the nature of the input. + - **references**: >https://www.spamhaus.org/faq/section/Spamhaus%20DBL + - **requirements**: >dnspython3: DNS python3 library ----- -#### [dns](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dns.py) +#### [DNS Resolver](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dns.py) + +jj +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dns.py)] -A simple DNS expansion service to resolve IP address from domain MISP attributes. - **features**: >The module takes a domain of hostname attribute as input, and tries to resolve it. If no error is encountered, the IP address that resolves the domain is returned, otherwise the origin of the error is displayed. > >The address of the DNS resolver to use is also configurable, but if no configuration is set, we use the Google public DNS address (8.8.8.8). > >Please note that composite MISP attributes containing domain or hostname are supported as well. + +- **config**: +>nameserver + - **input**: >Domain or hostname attribute. + - **output**: >IP address resolving the input. + - **requirements**: >dnspython3: DNS python3 library ----- -#### [docx_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/docx_enrich.py) +#### [DOCX Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/docx_enrich.py) Module to extract freetext from a .docx document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/docx_enrich.py)] + - **features**: >The module reads the text contained in a .docx document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a .docx document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: >docx python library ----- -#### [domaintools](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/domaintools.py) +#### [DomainTools Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/domaintools.py) DomainTools MISP expansion module. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/domaintools.py)] + - **features**: >This module takes a MISP attribute as input to query the Domaintools API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes. > >Please note that composite attributes composed by at least one of the input types mentionned below (domains, IPs, hostnames) are also supported. + +- **config**: +> - username +> - api_key + - **input**: >A MISP attribute included in the following list: >- domain @@ -503,6 +737,7 @@ DomainTools MISP expansion module. >- whois-registrant-phone >- ip-src >- ip-dst + - **output**: >MISP attributes mapped after the Domaintools API has been queried, included in the following list: >- whois-registrant-email @@ -512,56 +747,85 @@ DomainTools MISP expansion module. >- whois-creation-date >- text >- domain + - **references**: >https://www.domaintools.com/ + - **requirements**: > - Domaintools python library > - A Domaintools API access (username & apikey) ----- -#### [eql](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eql.py) +#### [EQL Query Generator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eql.py) EQL query generation for a MISP attribute. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eql.py)] + - **features**: >This module adds a new attribute to a MISP event containing an EQL query for a network or file attribute. + - **input**: >A filename or ip attribute. + - **output**: >Attribute containing EQL for a network or file attribute. + - **references**: >https://eql.readthedocs.io/en/latest/ ----- -#### [eupi](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eupi.py) +#### [EUPI Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eupi.py) A module to query the Phishing Initiative service (https://phishing-initiative.lu). +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eupi.py)] + - **features**: >This module takes a domain, hostname or url MISP attribute as input to query the Phishing Initiative API. The API returns then the result of the query with some information about the value queried. > >Please note that composite attributes containing domain or hostname are also supported. + +- **config**: +> - apikey +> - url + - **input**: >A domain, hostname or url MISP attribute. + - **output**: >Text containing information about the input, resulting from the query on Phishing Initiative. + - **references**: >https://phishing-initiative.eu/?lang=en + - **requirements**: > - pyeupi: eupi python library > - An access to the Phishing Initiative API (apikey & url) ----- -#### [farsight_passivedns](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/farsight_passivedns.py) +#### [URL Components Extractor](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/extract_url_components.py) + +Extract URL components +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/extract_url_components.py)] + +- **features**: +> + +----- + +#### [Farsight DNSDB Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/farsight_passivedns.py) Module to access Farsight DNSDB Passive DNS. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/farsight_passivedns.py)] + - **features**: >This module takes a domain, hostname or IP address MISP attribute as input to query the Farsight Passive DNS API. > The results of rdata and rrset lookups are then returned and parsed into passive-dns objects. @@ -569,204 +833,353 @@ Module to access Farsight DNSDB Passive DNS. >An API key is required to submit queries to the API. > It is also possible to define a custom server URL, and to set a limit of results to get. > This limit is set for each lookup, which means we can have an up to the limit number of passive-dns objects resulting from an rdata query about an IP address, but an up to the limit number of passive-dns objects for each lookup queries about a domain or a hostname (== twice the limit). + +- **config**: +> - apikey +> - server +> - limit +> - flex_queries + - **input**: >A domain, hostname or IP address MISP attribute. + - **output**: >Passive-dns objects, resulting from the query on the Farsight Passive DNS API. + - **references**: > - https://www.farsightsecurity.com/ > - https://docs.dnsdb.info/dnsdb-api/ + - **requirements**: >An access to the Farsight Passive DNS API (apikey) ----- -#### [geoip_asn](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_asn.py) +#### [GeoIP ASN Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_asn.py) -- **descrption**: ->An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about its related AS number. + +Query a local copy of the Maxmind Geolite ASN database (MMDB format) +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_asn.py)] + - **features**: >The module takes an IP address attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the related AS number. + +- **config**: +>local_geolite_db + +- **descrption**: +>An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about its related AS number. + - **input**: >An IP address MISP attribute. + - **output**: >Text containing information about the AS number of the IP address. + - **references**: >https://www.maxmind.com/en/home + - **requirements**: >A local copy of Maxmind's Geolite database ----- -#### [geoip_city](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_city.py) +#### [GeoIP City Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_city.py) An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about the city where it is located. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_city.py)] + - **features**: >The module takes an IP address attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the city where this IP address is located. + +- **config**: +>local_geolite_db + - **input**: >An IP address MISP attribute. + - **output**: >Text containing information about the city where the IP address is located. + - **references**: >https://www.maxmind.com/en/home + - **requirements**: >A local copy of Maxmind's Geolite database ----- -#### [geoip_country](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_country.py) +#### [GeoIP Country Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_country.py) -Module to query a local copy of Maxmind's Geolite database. +Query a local copy of Maxminds Geolite database, updated for MMDB format +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_country.py)] + - **features**: >This module takes an IP address MISP attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the location of this IP address. > >Please note that composite attributes domain|ip are also supported. + +- **config**: +>local_geolite_db + - **input**: >An IP address MISP Attribute. + - **output**: >Text containing information about the location of the IP address. + - **references**: >https://www.maxmind.com/en/home + - **requirements**: >A local copy of Maxmind's Geolite database ----- -#### [google_search](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_search.py) +#### [Google Safe Browsing Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_safe_browsing.py) + +Google safe browsing expansion module +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_safe_browsing.py)] + +- **features**: +> + +- **config**: +>api_key + +----- + +#### [Google Search](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_search.py) -- **descrption**: ->A hover module to get information about an url using a Google search. + +An expansion hover module to expand google search information about an URL +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_search.py)] + - **features**: >The module takes an url as input to query the Google search API. The result of the query is then return as raw text. + - **input**: >An url attribute. + - **output**: >Text containing the result of a Google search on the input url. + - **references**: >https://github.com/abenassi/Google-Search-API + - **requirements**: >The python Google Search API library ----- -#### [greynoise](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/greynoise.py) +#### [Google Threat Intelligence Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_threat_intelligence.py) + + + +An expansion module to have the observable's threat score assessed by Google Threat Intelligence. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_threat_intelligence.py)] + +- **features**: +>GTI assessment for the given observable, this include information about level of severity, a clear verdict (malicious, suspicious, undetected and benign) and additional information provided by the Mandiant expertise combined with the VirusTotal database. +> +>[Output example screeshot](https://github.com/MISP/MISP/assets/4747608/e275db2f-bb1e-4413-8cc0-ec3cb05e0414) + +- **config**: +> - apikey +> - event_limit +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + +- **input**: +>A domain, hash (md5, sha1, sha256 or sha512), hostname or IP address attribute. + +- **output**: +>Text fields containing the threat score, the severity, the verdict and the threat label of the observable inspected. + +- **references**: +> - https://www.virustotal.com/ +> - https://gtidocs.virustotal.com/reference + +- **requirements**: +>An access to the Google Threat Intelligence API (apikey), with a high request rate limit. + +----- + +#### [GreyNoise Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/greynoise.py) Module to query IP and CVE information from GreyNoise +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/greynoise.py)] + - **features**: >This module supports: 1) Query an IP from GreyNoise to see if it is internet background noise or a common business service 2) Query a CVE from GreyNoise to see the total number of internet scanners looking for the CVE in the last 7 days. + +- **config**: +> - api_key +> - api_type + - **input**: >An IP address or CVE ID + - **output**: >IP Lookup information or CVE scanning profile for past 7 days + - **references**: > - https://greynoise.io/ > - https://docs.greyniose.io/ > - https://www.greynoise.io/viz/account/ + - **requirements**: >A Greynoise API key. Both Enterprise (Paid) and Community (Free) API keys are supported, however Community API users will only be able to perform IP lookups. ----- -#### [hashdd](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashdd.py) +#### [Hashdd Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashdd.py) A hover module to check hashes against hashdd.com including NSLR dataset. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashdd.py)] + - **features**: >This module takes a hash attribute as input to check its known level, using the hashdd API. This information is then displayed. + - **input**: >A hash MISP attribute (md5). + - **output**: >Text describing the known level of the hash in the hashdd databases. + - **references**: >https://hashdd.com/ ----- -#### [hashlookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashlookup.py) +#### [CIRCL Hashlookup Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashlookup.py) An expansion module to query the CIRCL hashlookup services to find it if a hash is part of a known set such as NSRL. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashlookup.py)] + - **features**: >The module takes file hashes as input such as a MD5 or SHA1. > It queries the public CIRCL.lu hashlookup service and return all the hits if the hashes are known in an existing dataset. The module can be configured with a custom hashlookup url if required. > The module can be used an hover module but also an expansion model to add related MISP objects. > + +- **config**: +>custom_API + - **input**: >File hashes (MD5, SHA1) + - **output**: >Object with the filename associated hashes if the hash is part of a known set. + - **references**: >https://www.circl.lu/services/hashlookup/ ----- -#### [hibp](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hibp.py) +#### [Have I Been Pwned Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hibp.py) Module to access haveibeenpwned.com API. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hibp.py)] + - **features**: >The module takes an email address as input and queries haveibeenpwned.com API to find additional information about it. This additional information actually tells if any account using the email address has already been compromised in a data breach. + +- **config**: +>api_key + - **input**: >An email address + - **output**: >Additional information about the email address. + - **references**: >https://haveibeenpwned.com/ ----- -#### [html_to_markdown](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/html_to_markdown.py) +#### [HTML to Markdown](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/html_to_markdown.py) Expansion module to fetch the html content from an url and convert it into markdown. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/html_to_markdown.py)] + - **features**: >The module take an URL as input and the HTML content is fetched from it. This content is then converted into markdown that is returned as text. + - **input**: >URL attribute. + - **output**: >Markdown content converted from the HTML fetched from the url. + - **requirements**: >The markdownify python library ----- -#### [hyasinsight](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hyasinsight.py) +#### [HYAS Insight Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hyasinsight.py) HYAS Insight integration to MISP provides direct, high volume access to HYAS Insight data. It enables investigators and analysts to understand and defend against cyber adversaries and their infrastructure. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hyasinsight.py)] + - **features**: >This Module takes the IP Address, Domain, URL, Email, Phone Number, MD5, SHA1, Sha256, SHA512 MISP Attributes as input to query the HYAS Insight API. > The results of the HYAS Insight API are than are then returned and parsed into Hyas Insight Objects. > >An API key is required to submit queries to the HYAS Insight API. > + +- **config**: +>apikey + - **input**: >A MISP attribute of type IP Address(ip-src, ip-dst), Domain(hostname, domain), Email Address(email, email-src, email-dst, target-email, whois-registrant-email), Phone Number(phone-number, whois-registrant-phone), MDS(md5, x509-fingerprint-md5, ja3-fingerprint-md5, hassh-md5, hasshserver-md5), SHA1(sha1, x509-fingerprint-sha1), SHA256(sha256, x509-fingerprint-sha256), SHA512(sha512) + - **output**: >Hyas Insight objects, resulting from the query on the HYAS Insight API. + - **references**: >https://www.hyas.com/hyas-insight/ + - **requirements**: >A HYAS Insight API Key. ----- -#### [intel471](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intel471.py) +#### [Intel471 Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intel471.py) -- **descrption**: ->An expansion module to query Intel471 in order to get additional information about a domain, ip address, email address, url or hash. + +Module to access Intel 471 +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intel471.py)] + - **features**: >The module uses the Intel471 python library to query the Intel471 API with the value of the input attribute. The result of the query is then returned as freetext so the Freetext import parses it. + +- **config**: +> - email +> - authkey + +- **descrption**: +>An expansion module to query Intel471 in order to get additional information about a domain, ip address, email address, url or hash. + - **input**: >A MISP attribute whose type is included in the following list: >- hostname @@ -782,80 +1195,78 @@ HYAS Insight integration to MISP provides direct, high volume access to HYAS Ins >- md5 >- sha1 >- sha256 + - **output**: >Freetext + - **references**: >https://public.intel471.com/ + - **requirements**: >The intel471 python library ----- -#### [intelmq_eventdb](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intelmq_eventdb.py) - - - -Module to access intelmqs eventdb. -- **features**: ->/!\ EXPERIMENTAL MODULE, some features may not work /!\ -> ->This module takes a domain, hostname, IP address or Autonomous system MISP attribute as input to query the IntelMQ database. The result of the query gives then additional information about the input. -- **input**: ->A hostname, domain, IP address or AS attribute. -- **output**: ->Text giving information about the input using IntelMQ database. -- **references**: -> - https://github.com/certtools/intelmq -> - https://intelmq.readthedocs.io/en/latest/Developers-Guide/ -- **requirements**: -> - psycopg2: Python library to support PostgreSQL -> - An access to the IntelMQ database (username, password, hostname and database reference) - ------ - -#### [ip2locationio](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ip2locationio.py) +#### [IP2Location.io Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ip2locationio.py) An expansion module to query IP2Location.io to gather more information on a given IP address. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ip2locationio.py)] + - **features**: >The module takes an IP address attribute as input and queries the IP2Location.io API. >Free plan user will get the basic geolocation informaiton, and different subsription plan will get more information on the IP address. > Refer to [pricing page](https://www.ip2location.io/pricing) for more information on data available for each plan. > >More information on the responses content is available in the [documentation](https://www.ip2location.io/ip2location-documentation). + +- **config**: +>key + - **input**: >IP address attribute. + - **output**: >Additional information on the IP address, such as geolocation, proxy and so on. Refer to the Response Format section in https://www.ip2location.io/ip2location-documentation to find out the full format of the data returned. + - **references**: >https://www.ip2location.io/ip2location-documentation + - **requirements**: >An IP2Location.io token ----- -#### [ipasn](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipasn.py) +#### [IPASN-History Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipasn.py) Module to query an IP ASN history service (https://github.com/D4-project/IPASN-History). +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipasn.py)] + - **features**: >This module takes an IP address attribute as input and queries the CIRCL IPASN service. The result of the query is the latest asn related to the IP address, that is returned as a MISP object. + - **input**: >An IP address MISP attribute. + - **output**: >Asn object(s) objects related to the IP address used as input. + - **references**: >https://github.com/D4-project/IPASN-History + - **requirements**: >pyipasnhistory: Python library to access IPASN-history instance ----- -#### [ipinfo](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipinfo.py) +#### [IPInfo.io Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipinfo.py) An expansion module to query ipinfo.io to gather more information on a given IP address. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipinfo.py)] + - **features**: >The module takes an IP address attribute as input and queries the ipinfo.io API. >The geolocation information on the IP address is always returned. @@ -865,60 +1276,95 @@ An expansion module to query ipinfo.io to gather more information on a given IP >- With a paid subscription, the AS information is returned in the `asn` field with additional AS information, and depending on which plan the user has, you can also get information on the privacy method used to protect the IP address, the related domains, or the point of contact related to the IP address in case of an abuse. > >More information on the responses content is available in the [documentation](https://ipinfo.io/developers). + +- **config**: +>token + - **input**: >IP address attribute. + - **output**: >Additional information on the IP address, like its geolocation, the autonomous system it is included in, and the related domain(s). + - **references**: >https://ipinfo.io/developers + - **requirements**: >An ipinfo.io token ----- -#### [ipqs_fraud_and_risk_scoring](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py) +#### [IPQualityScore Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py) IPQualityScore MISP Expansion Module for IP reputation, Email Validation, Phone Number Validation, Malicious Domain and Malicious URL Scanner. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py)] + - **features**: >This Module takes the IP Address, Domain, URL, Email and Phone Number MISP Attributes as input to query the IPQualityScore API. > The results of the IPQualityScore API are than returned as IPQS Fraud and Risk Scoring Object. > The object contains a copy of the enriched attribute with added tags presenting the verdict based on fraud score,risk score and other attributes from IPQualityScore. + +- **config**: +>apikey + - **input**: >A MISP attribute of type IP Address(ip-src, ip-dst), Domain(hostname, domain), URL(url, uri), Email Address(email, email-src, email-dst, target-email, whois-registrant-email) and Phone Number(phone-number, whois-registrant-phone). + - **output**: >IPQualityScore object, resulting from the query on the IPQualityScore API. + - **references**: >https://www.ipqualityscore.com/ + - **requirements**: >A IPQualityScore API Key. ----- -#### [iprep](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/iprep.py) +#### [IPRep Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/iprep.py) Module to query IPRep data for IP addresses. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/iprep.py)] + - **features**: >This module takes an IP address attribute as input and queries the database from packetmail.net to get some information about the reputation of the IP. + +- **config**: +>apikey + - **input**: >An IP address MISP attribute. + - **output**: >Text describing additional information about the input after a query on the IPRep API. + - **references**: >https://github.com/mahesh557/packetmail + - **requirements**: >An access to the packetmail API (apikey) ----- -#### [joesandbox_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) +#### [Ninja Template Rendering](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/jinja_template_rendering.py) + +Render the template with the data passed +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/jinja_template_rendering.py)] + +- **features**: +> + +----- + +#### [Joe Sandbox Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) Query Joe Sandbox API with a submission url to get the json report and extract its data that is parsed and converted into MISP attributes and objects. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py)] -This url can by the way come from the result of the [joesandbox_submit expansion module](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py). - **features**: >Module using the new format of modules able to return attributes and objects. > @@ -927,84 +1373,128 @@ This url can by the way come from the result of the [joesandbox_submit expansion >Even if the introspection will allow all kinds of links to call this module, obviously only the ones presenting a sample or url submission in the Joe Sandbox API will return results. > >To make it work you will need to fill the 'apikey' configuration with your Joe Sandbox API key and provide a valid link as input. + +- **config**: +> - apiurl +> - apikey +> - import_executable +> - import_mitre_attack + - **input**: >Link of a Joe Sandbox sample or url submission. + - **output**: >MISP attributes & objects parsed from the analysis report. + - **references**: > - https://www.joesecurity.org > - https://www.joesandbox.com/ + - **requirements**: >jbxapi: Joe Sandbox API python3 library ----- -#### [joesandbox_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py) +#### [Joe Sandbox Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py) A module to submit files or URLs to Joe Sandbox for an advanced analysis, and return the link of the submission. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py)] + - **features**: >The module requires a Joe Sandbox API key to submit files or URL, and returns the link of the submitted analysis. > >It is then possible, when the analysis is completed, to query the Joe Sandbox API to get the data related to the analysis, using the [joesandbox_query module](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) directly on this submission link. + +- **config**: +> - apiurl +> - apikey +> - accept-tac +> - report-cache +> - systems + - **input**: >Sample, url (or domain) to submit to Joe Sandbox for an advanced analysis. + - **output**: >Link of the report generated in Joe Sandbox. + - **references**: > - https://www.joesecurity.org > - https://www.joesandbox.com/ + - **requirements**: >jbxapi: Joe Sandbox API python3 library ----- -#### [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) +#### [Lastline Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Query Lastline with an analysis link and parse the report into MISP attributes and objects. -The analysis link can also be retrieved from the output of the [lastline_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_submit.py) expansion module. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py)] + - **features**: >The module requires a Lastline Portal `username` and `password`. >The module uses the new format and it is able to return MISP attributes and objects. >The module returns the same results as the [lastline_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/lastline_import.py) import module. + +- **config**: +> - username +> - password +> - verify_ssl + - **input**: >Link to a Lastline analysis. + - **output**: >MISP attributes and objects parsed from the analysis report. + - **references**: >https://www.lastline.com ----- -#### [lastline_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_submit.py) +#### [Lastline Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_submit.py) Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Module to submit a file or URL to Lastline. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_submit.py)] + - **features**: >The module requires a Lastline Analysis `api_token` and `key`. >When the analysis is completed, it is possible to import the generated report by feeding the analysis link to the [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) module. + +- **config**: +> - url +> - api_token +> - key + - **input**: >File or URL to submit to Lastline. + - **output**: >Link to the report generated by Lastline. + - **references**: >https://www.lastline.com ----- -#### [macaddress_io](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macaddress_io.py) +#### [Macaddress.io Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macaddress_io.py) MISP hover module for macaddress.io +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macaddress_io.py)] + - **features**: >This module takes a MAC address attribute as input and queries macaddress.io for additional information. > @@ -1012,181 +1502,290 @@ MISP hover module for macaddress.io >- MAC address details >- Vendor details >- Block details + +- **config**: +>api_key + - **input**: >MAC address MISP attribute. + - **output**: >Text containing information on the MAC address fetched from a query on macaddress.io. + - **references**: > - https://macaddress.io/ > - https://github.com/CodeLineFi/maclookup-python + - **requirements**: > - maclookup: macaddress.io python library > - An access to the macaddress.io API (apikey) ----- -#### [macvendors](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macvendors.py) +#### [Macvendors Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macvendors.py) Module to access Macvendors API. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macvendors.py)] + - **features**: >The module takes a MAC address as input and queries macvendors.com for some information about it. The API returns the name of the vendor related to the address. + +- **config**: +>user-agent + - **input**: >A MAC address. + - **output**: >Additional information about the MAC address. + - **references**: > - https://macvendors.com/ > - https://macvendors.com/api ----- -#### [malwarebazaar](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malwarebazaar.py) +#### [MalShare Upload](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malshare_upload.py) + +Module to push malware samples to MalShare +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malshare_upload.py)] + +- **config**: +>malshare_apikey + +- **requirements**: +>requests library + +----- + +#### [Malware Bazaar Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malwarebazaar.py) + +Query Malware Bazaar to get additional information about the input hash. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malwarebazaar.py)] -Query the MALWAREbazaar API to get additional information about the input hash attribute. - **features**: >The module takes a hash attribute as input and queries MALWAREbazaar's API to fetch additional data about it. The result, if the payload is known on the databases, is at least one file object describing the file the input hash is related to. > >The module is using the new format of modules able to return object since the result is one or multiple MISP object(s). + - **input**: >A hash attribute (md5, sha1 or sha256). + - **output**: >File object(s) related to the input attribute found on MALWAREbazaar databases. + - **references**: >https://bazaar.abuse.ch/ ----- -#### [mmdb_lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mmdb_lookup.py) +#### [McAfee MVISION Insights Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mcafee_insights_enrich.py) + +Lookup McAfee MVISION Insights Details +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mcafee_insights_enrich.py)] + +- **features**: +> + +- **config**: +> - api_key +> - client_id +> - client_secret + +----- + +#### [GeoIP Enrichment](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mmdb_lookup.py) A hover and expansion module to enrich an ip with geolocation and ASN information from an mmdb server instance, such as CIRCL's ip.circl.lu. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mmdb_lookup.py)] + - **features**: >The module takes an IP address related attribute as input. > It queries the public CIRCL.lu mmdb-server instance, available at ip.circl.lu, by default. The module can be configured with a custom mmdb server url if required. > It is also possible to filter results on 1 db_source by configuring db_source_filter. + +- **config**: +> - custom_API +> - db_source_filter + - **input**: >An IP address attribute (for example ip-src or ip-src|port). + - **output**: >Geolocation and asn objects. + - **references**: > - https://data.public.lu/fr/datasets/geo-open-ip-address-geolocation-per-country-in-mmdb-format/ > - https://github.com/adulau/mmdb-server ----- -#### [mwdb](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mwdb.py) +#### [MWDB Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mwdb.py) Module to push malware samples to a MWDB instance +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mwdb.py)] + - **features**: >An expansion module to push malware samples to a MWDB (https://github.com/CERT-Polska/mwdb-core) instance. This module does not push samples to a sandbox. This can be achieved via Karton (connected to the MWDB). Does: * Upload of attachment or malware sample to MWDB * Tags of events and/or attributes are added to MWDB. * Comment of the MISP attribute is added to MWDB. * A link back to the MISP event is added to MWDB via the MWDB attribute. * A link to the MWDB attribute is added as an enrichted attribute to the MISP event. + +- **config**: +> - mwdb_apikey +> - mwdb_url +> - mwdb_misp_attribute +> - mwdb_public +> - include_tags_event +> - include_tags_attribute + - **input**: >Attachment or malware sample + - **output**: >Link attribute that points to the sample at the MWDB instane + - **requirements**: >* mwdblib installed (pip install mwdblib) ; * (optional) keys.py file to add tags of events/attributes to MWDB * (optional) MWDB attribute created for the link back to MISP (defined in mwdb_misp_attribute) ----- -#### [ocr_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ocr_enrich.py) +#### [OCR Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ocr_enrich.py) Module to process some optical character recognition on pictures. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ocr_enrich.py)] + - **features**: >The module takes an attachment attributes as input and process some optical character recognition on it. The text found is then passed to the Freetext importer to extract potential IoCs. + - **input**: >A picture attachment. + - **output**: >Text and freetext fetched from the input picture. + - **requirements**: >cv2: The OpenCV python library. ----- -#### [ods_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ods_enrich.py) +#### [ODS Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ods_enrich.py) Module to extract freetext from a .ods document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ods_enrich.py)] + - **features**: >The module reads the text contained in a .ods document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a .ods document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: > - ezodf: Python package to create/manipulate OpenDocumentFormat files. > - pandas_ods_reader: Python library to read in ODS files. ----- -#### [odt_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/odt_enrich.py) +#### [ODT Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/odt_enrich.py) Module to extract freetext from a .odt document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/odt_enrich.py)] + - **features**: >The module reads the text contained in a .odt document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a .odt document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: >ODT reader python library. ----- -#### [onyphe](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe.py) +#### [Onyphe Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe.py) Module to process a query on Onyphe. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe.py)] + - **features**: >This module takes a domain, hostname, or IP address attribute as input in order to query the Onyphe API. Data fetched from the query is then parsed and MISP attributes are extracted. + +- **config**: +>apikey + - **input**: >A domain, hostname or IP address MISP attribute. + - **output**: >MISP attributes fetched from the Onyphe query. + - **references**: > - https://www.onyphe.io/ > - https://github.com/sebdraven/pyonyphe + - **requirements**: > - onyphe python library > - An access to the Onyphe API (apikey) ----- -#### [onyphe_full](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe_full.py) +#### [Onyphe Full Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe_full.py) Module to process a full query on Onyphe. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe_full.py)] + - **features**: >This module takes a domain, hostname, or IP address attribute as input in order to query the Onyphe API. Data fetched from the query is then parsed and MISP attributes are extracted. > >The parsing is here more advanced than the one on onyphe module, and is returning more attributes, since more fields of the query result are watched and parsed. + +- **config**: +>apikey + - **input**: >A domain, hostname or IP address MISP attribute. + - **output**: >MISP attributes fetched from the Onyphe query. + - **references**: > - https://www.onyphe.io/ > - https://github.com/sebdraven/pyonyphe + - **requirements**: > - onyphe python library > - An access to the Onyphe API (apikey) ----- -#### [otx](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/otx.py) +#### [AlienVault OTX Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/otx.py) Module to get information from AlienVault OTX. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/otx.py)] + - **features**: >This module takes a MISP attribute as input to query the OTX Alienvault API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes. + +- **config**: +>apikey + - **input**: >A MISP attribute included in the following list: >- hostname @@ -1197,6 +1796,7 @@ Module to get information from AlienVault OTX. >- sha1 >- sha256 >- sha512 + - **output**: >MISP attributes mapped from the result of the query on OTX, included in the following list: >- domain @@ -1208,39 +1808,44 @@ Module to get information from AlienVault OTX. >- sha256 >- sha512 >- email + - **references**: >https://www.alienvault.com/open-threat-exchange + - **requirements**: >An access to the OTX API (apikey) ----- -#### [passivessh](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passivessh.py) +#### [Passive SSH Enrichment](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passive_ssh.py) - +An expansion module to enrich, SSH key fingerprints and IP addresses with information collected by passive-ssh +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passive_ssh.py)] -An expansion module to query the CIRCL Passive SSH. - **features**: ->The module queries the Passive SSH service from CIRCL. -> -> The module can be used an hover module but also an expansion model to add related MISP objects. > -- **input**: ->IP addresses or SSH fingerprints -- **output**: ->SSH key materials, complementary IP addresses with similar SSH key materials -- **references**: ->https://github.com/D4-project/passive-ssh + +- **config**: +> - custom_api_url +> - api_user +> - api_key ----- -#### [passivetotal](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passivetotal.py) +#### [PassiveTotal Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passivetotal.py) +The PassiveTotal MISP expansion module brings the datasets derived from Internet scanning directly into your MISP instance. This module supports passive DNS, historic SSL, WHOIS, and host attributes. In order to use the module, you must have a valid PassiveTotal account username and API key. Registration is free and can be done by visiting https://www.passivetotal.org/register +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passivetotal.py)] - **features**: >The PassiveTotal MISP expansion module brings the datasets derived from Internet scanning directly into your MISP instance. This module supports passive DNS, historic SSL, WHOIS, and host attributes. In order to use the module, you must have a valid PassiveTotal account username and API key. Registration is free and can be done by visiting https://www.passivetotal.org/register + +- **config**: +> - username +> - api_key + - **input**: >A MISP attribute included in the following list: >- hostname @@ -1257,6 +1862,7 @@ An expansion module to query the CIRCL Passive SSH. >- whois-registrant-name >- whois-registrar >- whois-creation-date + - **output**: >MISP attributes mapped from the result of the query on PassiveTotal, included in the following list: >- hostname @@ -1277,164 +1883,240 @@ An expansion module to query the CIRCL Passive SSH. >- sha1 >- sha256 >- link + - **references**: >https://www.passivetotal.org/register + - **requirements**: > - Passivetotal python library > - An access to the PassiveTotal API (apikey) ----- -#### [pdf_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pdf_enrich.py) +#### [PDF Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pdf_enrich.py) Module to extract freetext from a PDF document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pdf_enrich.py)] + - **features**: >The module reads the text contained in a PDF document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a PDF document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: >pdftotext: Python library to extract text from PDF. ----- -#### [pptx_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pptx_enrich.py) +#### [PPTX Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pptx_enrich.py) Module to extract freetext from a .pptx document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pptx_enrich.py)] + - **features**: >The module reads the text contained in a .pptx document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a .pptx document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: >pptx: Python library to read PowerPoint files. ----- -#### [qintel_qsentry](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qintel_qsentry.py) +#### [Qintel QSentry Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qintel_qsentry.py) A hover and expansion module which queries Qintel QSentry for ip reputation data +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qintel_qsentry.py)] + - **features**: >This module takes an ip-address (ip-src or ip-dst) attribute as input, and queries the Qintel QSentry API to retrieve ip reputation data + +- **config**: +> - token +> - remote + - **input**: >ip address attribute + - **ouput**: >Objects containing the enriched IP, threat tags, last seen attributes and associated Autonomous System information + - **references**: >https://www.qintel.com/products/qsentry/ + - **requirements**: >A Qintel API token ----- -#### [qrcode](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qrcode.py) +#### [QR Code Decode](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qrcode.py) Module to decode QR codes. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qrcode.py)] + - **features**: >The module reads the QR code and returns the related address, which can be an URL or a bitcoin address. + - **input**: >A QR code stored as attachment attribute. + - **output**: >The URL or bitcoin address the QR code is pointing to. + - **requirements**: > - cv2: The OpenCV python library. > - pyzbar: Python library to read QR codes. ----- -#### [ransomcoindb](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ransomcoindb.py) -- **descrption**: ->Module to access the ransomcoinDB with a hash or btc address attribute and get the associated btc address of hashes. +#### [RandomcoinDB Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ransomcoindb.py) + +Module to access the ransomcoinDB (see https://ransomcoindb.concinnity-risks.com) +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ransomcoindb.py)] + - **features**: >The module takes either a hash attribute or a btc attribute as input to query the ransomcoinDB API for some additional data. > >If the input is a btc address, we will get the associated hashes returned in a file MISP object. If we query ransomcoinDB with a hash, the response contains the associated btc addresses returned as single MISP btc attributes. + +- **config**: +>api-key + +- **descrption**: +>Module to access the ransomcoinDB with a hash or btc address attribute and get the associated btc address of hashes. + - **input**: >A hash (md5, sha1 or sha256) or btc attribute. + - **output**: >Hashes associated to a btc address or btc addresses associated to a hash. + - **references**: >https://ransomcoindb.concinnity-risks.com + - **requirements**: >A ransomcoinDB API key. ----- -#### [rbl](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/rbl.py) +#### [Real-time Blackhost Lists Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/rbl.py) Module to check an IPv4 address against known RBLs. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/rbl.py)] + - **features**: >This module takes an IP address attribute as input and queries multiple know Real-time Blackhost Lists to check if they have already seen this IP address. > >We display then all the information we get from those different sources. + +- **config**: +>timeout + - **input**: >IP address attribute. + - **output**: >Text with additional data from Real-time Blackhost Lists about the IP address. + - **references**: >[RBLs list](https://github.com/MISP/misp-modules/blob/8817de476572a10a9c9d03258ec81ca70f3d926d/misp_modules/modules/expansion/rbl.py#L20) + - **requirements**: >dnspython3: DNS python3 library ----- -#### [recordedfuture](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/recordedfuture.py) +#### [Recorded Future Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/recordedfuture.py) Module to enrich attributes with threat intelligence from Recorded Future. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/recordedfuture.py)] + - **features**: >Enrich an attribute to add a custom enrichment object to the event. The object contains a copy of the enriched attribute with added tags presenting risk score and triggered risk rules from Recorded Future. Malware and Threat Actors related to the enriched indicator in Recorded Future is matched against MISP's galaxy clusters and applied as galaxy tags. The custom enrichment object also includes a list of related indicators from Recorded Future (IP's, domains, hashes, URL's and vulnerabilities) added as additional attributes. + +- **config**: +> - token +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + - **input**: >A MISP attribute of one of the following types: ip, ip-src, ip-dst, domain, hostname, md5, sha1, sha256, uri, url, vulnerability, weakness. + - **output**: >A MISP object containing a copy of the enriched attribute with added tags from Recorded Future and a list of new attributes related to the enriched attribute. + - **references**: >https://www.recordedfuture.com/ + - **requirements**: >A Recorded Future API token. ----- -#### [reversedns](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/reversedns.py) +#### [Reverse DNS](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/reversedns.py) Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/reversedns.py)] + - **features**: >The module takes an IP address as input and tries to find the hostname this IP address is resolved into. > >The address of the DNS resolver to use is also configurable, but if no configuration is set, we use the Google public DNS address (8.8.8.8). > >Please note that composite MISP attributes containing IP addresses are supported as well. + +- **config**: +>nameserver + - **input**: >An IP address attribute. + - **output**: >Hostname attribute the input is resolved into. + - **requirements**: >DNS python library ----- -#### [securitytrails](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/securitytrails.py) +#### [SecurityTrails Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/securitytrails.py) An expansion modules for SecurityTrails. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/securitytrails.py)] + - **features**: >The module takes a domain, hostname or IP address attribute as input and queries the SecurityTrails API with it. > >Multiple parsing operations are then processed on the result of the query to extract a much information as possible. > >From this data extracted are then mapped MISP attributes. + +- **config**: +>apikey + - **input**: >A domain, hostname or IP address attribute. + - **output**: >MISP attributes resulting from the query on SecurityTrails API, included in the following list: >- hostname @@ -1448,189 +2130,246 @@ An expansion modules for SecurityTrails. >- whois-registrar >- whois-creation-date >- domain + - **references**: >https://securitytrails.com/ + - **requirements**: > - dnstrails python library > - An access to the SecurityTrails API (apikey) ----- -#### [shodan](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/shodan.py) +#### [Shodan Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/shodan.py) Module to query on Shodan. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/shodan.py)] + - **features**: >The module takes an IP address as input and queries the Shodan API to get some additional data about it. + +- **config**: +>apikey + - **input**: >An IP address MISP attribute. + - **output**: >Text with additional data about the input, resulting from the query on Shodan. + - **references**: >https://www.shodan.io/ + - **requirements**: > - shodan python library > - An access to the Shodan API (apikey) ----- -#### [sigma_queries](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_queries.py) +#### [Sigma Rule Converter](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_queries.py) An expansion hover module to display the result of sigma queries. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_queries.py)] + - **features**: >This module takes a Sigma rule attribute as input and tries all the different queries available to convert it into different formats recognized by SIEMs. + - **input**: >A Sigma attribute. + - **output**: >Text displaying results of queries on the Sigma attribute. + - **references**: >https://github.com/Neo23x0/sigma/wiki + - **requirements**: >Sigma python library ----- -#### [sigma_syntax_validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_syntax_validator.py) +#### [Sigma Syntax Validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_syntax_validator.py) An expansion hover module to perform a syntax check on sigma rules. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_syntax_validator.py)] + - **features**: >This module takes a Sigma rule attribute as input and performs a syntax check on it. > >It displays then that the rule is valid if it is the case, and the error related to the rule otherwise. + - **input**: >A Sigma attribute. + - **output**: >Text describing the validity of the Sigma rule. + - **references**: >https://github.com/Neo23x0/sigma/wiki + - **requirements**: > - Sigma python library > - Yaml python library ----- -#### [sigmf-expand](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigmf-expand.py) +#### [SigMF Expansion](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigmf_expand.py) + +Expands a SigMF Recording object into a SigMF Expanded Recording object, extracts a SigMF archive into a SigMF Recording object. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigmf_expand.py)] -Enrichs a SigMF Recording or extracts a SigMF Archive into a SigMF Recording. - **features**: ->This module can be used to expand a SigMF Recording object into a SigMF Expanded Recording object with a waterfall plot or to extract a SigMF Archive object into a SigMF Recording objet. -- **input**: ->Object of sigmf-archive or sigmf-recording template. -- **output**: ->Object of sigmf-expanded-recording or sigmf-recording template. -- **references**: ->https://github.com/sigmf/SigMF -- **requirements**: -> - matplotlib: For plotting the waterfall plot of the recording. -> - numpy: For the waterfall plot of the recording. -> - sigmf: For validating SigMF files. +> ----- -#### [socialscan](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/socialscan.py) +#### [Socialscan Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/socialscan.py) A hover module to get information on the availability of an email address or username on some online platforms. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/socialscan.py)] + - **features**: >The module takes an email address or username as input and check its availability on some online platforms. The results for each platform are then returned to see if the email address or the username is used, available or if there is an issue with it. + - **input**: >An email address or usename attribute. + - **output**: >Text containing information about the availability of an email address or a username in some online platforms. + - **references**: >https://github.com/iojw/socialscan + - **requirements**: >The socialscan python library ----- -#### [sophoslabs_intelix](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sophoslabs_intelix.py) +#### [SophosLabs Intelix Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sophoslabs_intelix.py) An expansion module to query the Sophoslabs intelix API to get additional information about an ip address, url, domain or sha256 attribute. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sophoslabs_intelix.py)] + - **features**: >The module takes an ip address, url, domain or sha256 attribute and queries the SophosLabs Intelix API with the attribute value. The result of this query is a SophosLabs Intelix hash report, or an ip or url lookup, that is then parsed and returned in a MISP object. + +- **config**: +> - client_id +> - client_secret + - **input**: >An ip address, url, domain or sha256 attribute. + - **output**: >SophosLabs Intelix report and lookup objects + - **references**: >https://aws.amazon.com/marketplace/pp/B07SLZPMCS + - **requirements**: >A client_id and client_secret pair to authenticate to the SophosLabs Intelix API ----- -#### [sourcecache](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sourcecache.py) +#### [URL Archiver](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sourcecache.py) Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sourcecache.py)] + - **features**: >This module takes a link or url attribute as input and caches the related web page. It returns then a link of the cached page. + +- **config**: +>archivepath + - **input**: >A link or url attribute. + - **output**: >A malware-sample attribute describing the cached page. + - **references**: >https://github.com/adulau/url_archiver + - **requirements**: >urlarchiver: python library to fetch and archive URL on the file-system ----- -#### [stairwell](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stairwell.py) +#### [Stairwell Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stairwell.py) -An expansion module to enrich hash observables with the Stairwell API. +Module to query the Stairwell API to get additional information about the input hash attribute +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stairwell.py)] + - **features**: ->This module takes a file hash as input and queries the Stairwell API. It will create a misp-object with the additional enrichment intel. +>The module takes a hash attribute as input and queries Stariwell's API to fetch additional data about it. The result, if the payload is observed in Stariwell, is a file object describing the file the input hash is related to. + +- **config**: +>apikey + - **input**: ->MD5, SHA1, or SHA256 +>A hash attribute (md5, sha1, sha256). + - **output**: ->A stairwell misp-object with additional enrichment intel. +>File object related to the input attribute found on Stairwell platform. + - **references**: ->https://docs.stairwell.com +> - https://stairwell.com +> - https://docs.stairwell.com + - **requirements**: ->- json ->- pymisp ->- requests +>Access to Stairwell platform (apikey) ----- -#### [stix2_pattern_syntax_validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py) +#### [STIX2 Pattern Syntax Validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py) An expansion hover module to perform a syntax check on stix2 patterns. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py)] + - **features**: >This module takes a STIX2 pattern attribute as input and performs a syntax check on it. > >It displays then that the rule is valid if it is the case, and the error related to the rule otherwise. + - **input**: >A STIX2 pattern attribute. + - **output**: >Text describing the validity of the STIX2 pattern. + - **references**: >[STIX2.0 patterning specifications](http://docs.oasis-open.org/cti/stix/v2.0/cs01/part5-stix-patterning/stix-v2.0-cs01-part5-stix-patterning.html) + - **requirements**: >stix2patterns python library ----- -#### [threatcrowd](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatcrowd.py) +#### [ThreatCrowd Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatcrowd.py) Module to get information from ThreatCrowd. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatcrowd.py)] + - **features**: >This module takes a MISP attribute as input and queries ThreatCrowd with it. > >The result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute. + - **input**: >A MISP attribute included in the following list: >- hostname @@ -1642,6 +2381,7 @@ Module to get information from ThreatCrowd. >- sha256 >- sha512 >- whois-registrant-email + - **output**: >MISP attributes mapped from the result of the query on ThreatCrowd, included in the following list: >- domain @@ -1654,20 +2394,34 @@ Module to get information from ThreatCrowd. >- sha512 >- hostname >- whois-registrant-email + - **references**: >https://www.threatcrowd.org/ ----- -#### [threatminer](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatminer.py) +#### [ThreadFox Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatfox.py) + +Module to search for an IOC on ThreatFox by abuse.ch. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatfox.py)] + +- **features**: +> + +----- + +#### [ThreatMiner Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatminer.py) Module to get information from ThreatMiner. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatminer.py)] + - **features**: >This module takes a MISP attribute as input and queries ThreatMiner with it. > >The result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute. + - **input**: >A MISP attribute included in the following list: >- hostname @@ -1678,6 +2432,7 @@ Module to get information from ThreatMiner. >- sha1 >- sha256 >- sha512 + - **output**: >MISP attributes mapped from the result of the query on ThreatMiner, included in the following list: >- domain @@ -1694,20 +2449,40 @@ Module to get information from ThreatMiner. >- whois-registrant-email >- url >- link + - **references**: >https://www.threatminer.org/ ----- -#### [trustar_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/trustar_enrich.py) +#### [Triage Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/triage_submit.py) + +Module to submit samples to tria.ge +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/triage_submit.py)] + +- **config**: +> - apikey +> - url_mode + +----- + +#### [TruSTAR Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/trustar_enrich.py) Module to get enrich indicators with TruSTAR. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/trustar_enrich.py)] + - **features**: >This module enriches MISP attributes with scoring and metadata from TruSTAR. > >The TruSTAR indicator summary is appended to the attributes along with links to any associated reports. + +- **config**: +> - user_api_key +> - user_api_secret +> - enclave_ids + - **input**: >Any of the following MISP attributes: >- btc @@ -1721,78 +2496,105 @@ Module to get enrich indicators with TruSTAR. >- sha1 >- sha256 >- url + - **output**: >MISP attributes enriched with indicator summary data from the TruSTAR API. Data includes a severity level score and additional source and scoring info. + - **references**: >https://docs.trustar.co/api/v13/indicators/get_indicator_summaries.html ----- -#### [urlhaus](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlhaus.py) +#### [URLhaus Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlhaus.py) Query of the URLhaus API to get additional information about the input attribute. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlhaus.py)] + - **features**: >Module using the new format of modules able to return attributes and objects. > >The module takes one of the attribute type specified as input, and query the URLhaus API with it. If any result is returned by the API, attributes and objects are created accordingly. + - **input**: >A domain, hostname, url, ip, md5 or sha256 attribute. + - **output**: >MISP attributes & objects fetched from the result of the URLhaus API query. + - **references**: >https://urlhaus.abuse.ch/ ----- -#### [urlscan](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlscan.py) +#### [URLScan Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlscan.py) An expansion module to query urlscan.io. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlscan.py)] + - **features**: >This module takes a MISP attribute as input and queries urlscan.io with it. > >The result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute. + +- **config**: +>apikey + - **input**: >A domain, hostname or url attribute. + - **output**: >MISP attributes mapped from the result of the query on urlscan.io. + - **references**: >https://urlscan.io/ + - **requirements**: >An access to the urlscan.io API ----- -#### [variotdbs](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/variotdbs.py) +#### [VARIoT db Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/variotdbs.py) An expansion module to query the VARIoT db API for more information about a vulnerability. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/variotdbs.py)] + - **features**: >The module takes a vulnerability attribute as input and queries que VARIoT db API to gather additional information. > >The `vuln` endpoint is queried first to look for additional information about the vulnerability itself. > >The `exploits` endpoint is also queried then to look for the information of the potential related exploits, which are parsed and added to the results using the `exploit` object template. + +- **config**: +>API_key + - **input**: >Vulnerability attribute. + - **output**: >Additional information about the vulnerability, as it is stored on the VARIoT db, about the vulnerability itself, and the potential related exploits. + - **references**: >https://www.variotdbs.pl/ + - **requirements**: >A VARIoT db API key (if you do not want to be limited to 100 queries / day) ----- -#### [virustotal](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal.py) +#### [VirusTotal v3 Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal.py) -Module to get advanced information from virustotal. +Enrich observables with the VirusTotal v3 API +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal.py)] + - **features**: >New format of modules able to return attributes and objects. > @@ -1801,23 +2603,37 @@ Module to get advanced information from virustotal. >Compared to the [standard VirusTotal expansion module](https://github.com/MISP/misp-modules/blob/main/misp_modules/modules/expansion/virustotal_public.py), this module is made for advanced parsing of VirusTotal report, with a recursive analysis of the elements found after the first request. > >Thus, it requires a higher request rate limit to avoid the API to return a 204 error (Request rate limit exceeded), and the data parsed from the different requests are returned as MISP attributes and objects, with the corresponding relations between each one of them. + +- **config**: +> - apikey +> - event_limit +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + - **input**: >A domain, hash (md5, sha1, sha256 or sha512), hostname or IP address attribute. + - **output**: >MISP attributes and objects resulting from the parsing of the VirusTotal report concerning the input attribute. + - **references**: > - https://www.virustotal.com/ -> - https://developers.virustotal.com/reference +> - https://docs.virustotal.com/reference/overview + - **requirements**: >An access to the VirusTotal API (apikey), with a high request rate limit. ----- -#### [virustotal_public](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_public.py) +#### [VirusTotal Public API Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_public.py) -Module to get information from VirusTotal. +Enrich observables with the VirusTotal v3 public API +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_public.py)] + - **features**: >New format of modules able to return attributes and objects. > @@ -1826,29 +2642,66 @@ Module to get information from VirusTotal. >Compared to the [more advanced VirusTotal expansion module](https://github.com/MISP/misp-modules/blob/main/misp_modules/modules/expansion/virustotal.py), this module is made for VirusTotal users who have a low request rate limit. > >Thus, it only queries the API once and returns the results that is parsed into MISP attributes and objects. + +- **config**: +> - apikey +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + - **input**: >A domain, hostname, ip, url or hash (md5, sha1, sha256 or sha512) attribute. + - **output**: >MISP attributes and objects resulting from the parsing of the VirusTotal report concerning the input attribute. + - **references**: > - https://www.virustotal.com -> - https://developers.virustotal.com/reference +> - https://docs.virustotal.com/reference/overview + - **requirements**: >An access to the VirusTotal API (apikey) ----- -#### [vmray_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmray_submit.py) +#### [VirusTotal Upload](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_upload.py) + + + +Module to push malware samples to VirusTotal +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_upload.py)] + +- **config**: +>virustotal_apikey + +- **requirements**: +>requests library + +----- + +#### [VMRay Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmray_submit.py) Module to submit a sample to VMRay. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmray_submit.py)] + - **features**: >This module takes an attachment or malware-sample attribute as input to query the VMRay API. > >The sample contained within the attribute in then enriched with data from VMRay mapped into MISP attributes. + +- **config**: +> - apikey +> - url +> - shareable +> - do_not_reanalyze +> - do_not_include_vmrayjobids + - **input**: >An attachment or malware-sample attribute. + - **output**: >MISP attributes mapped from the result of the query on VMRay API, included in the following list: >- text @@ -1856,125 +2709,208 @@ Module to submit a sample to VMRay. >- sha256 >- md5 >- link + - **references**: >https://www.vmray.com/ + - **requirements**: >An access to the VMRay API (apikey & url) ----- -#### [vmware_nsx](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmware_nsx.py) +#### [VMware NSX Defender Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmware_nsx.py) Module to enrich a file or URL with VMware NSX Defender. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmware_nsx.py)] + - **features**: >This module takes an IoC such as file hash, file attachment, malware-sample or url as input to query VMware NSX Defender. > >The IoC is then enriched with data from VMware NSX Defender. + +- **config**: +> - analysis_url +> - analysis_verify_ssl +> - analysis_key +> - analysis_api_token +> - vt_key +> - misp_url +> - misp_verify_ssl +> - misp_key + - **input**: >File hash, attachment or URL to be enriched with VMware NSX Defender. + - **output**: >Objects and tags generated by VMware NSX Defender. + - **references**: >https://www.vmware.com + - **requirements**: >The module requires a VMware NSX Defender Analysis `api_token` and `key`. ----- -#### [vulndb](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulndb.py) +#### [VulnDB Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulndb.py) Module to query VulnDB (RiskBasedSecurity.com). +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulndb.py)] + - **features**: >This module takes a vulnerability attribute as input and queries VulnDB in order to get some additional data about it. > >The API gives the result of the query which can be displayed in the screen, and/or mapped into MISP attributes to add in the event. + +- **config**: +> - apikey +> - apisecret +> - discard_dates +> - discard_external_references +> - discard_cvss +> - discard_productinformation +> - discard_classification +> - discard_cpe + - **input**: >A vulnerability attribute. + - **output**: >Additional data enriching the CVE input, fetched from VulnDB. + - **references**: >https://vulndb.cyberriskanalytics.com/ + - **requirements**: >An access to the VulnDB API (apikey, apisecret) ----- -#### [vulners](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulners.py) +#### [Vulnerability Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulnerability_lookup.py) + +An expansion module to query Vulnerability Lookup +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulnerability_lookup.py)] + +- **features**: +> + +----- + +#### [Vulners Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulners.py) An expansion hover module to expand information about CVE id using Vulners API. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulners.py)] + - **features**: >This module takes a vulnerability attribute as input and queries the Vulners API in order to get some additional data about it. > >The API then returns details about the vulnerability. + +- **config**: +>apikey + - **input**: >A vulnerability attribute. + - **output**: >Text giving additional information about the CVE in input. + - **references**: >https://vulners.com/ + - **requirements**: > - Vulners python library > - An access to the Vulners API ----- -#### [Vysion](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vysion.py) +#### [Vysion Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vysion.py) Module to enrich the information by making use of the Vysion API. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vysion.py)] + - **features**: ->This module gets correlated information from our dark web intelligence database. With this you will get several objects containing information related to, for example, an organization victim of a ransomware attack. ->MISP objects containing title, link to our webapp and TOR, i2p or clearnet URLs. +>This module gets correlated information from Byron Labs' dark web intelligence database. With this you will get several objects containing information related to, for example, an organization victim of a ransomware attack. + +- **config**: +> - apikey +> - event_limit +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + - **input**: ->MISP Attribute which include: company(target-org), country, info. +>company(target-org), country, info, BTC, XMR and DASH address. + - **output**: >MISP objects containing title, link to our webapp and TOR, i2p or clearnet URLs. + - **references**: ->https://vysion.ai/ +> - https://vysion.ai/ +> - https://developers.vysion.ai/ +> - https://github.com/ByronLabs/vysion-cti/tree/main + - **requirements**: -> Vysion python library -> Vysion API Key +> - Vysion python library +> - Vysion API Key ----- -#### [whois](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whois.py) +#### [Whois Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whois.py) Module to query a local instance of uwhois (https://github.com/rafiot/uwhoisd). +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whois.py)] + - **features**: >This module takes a domain or IP address attribute as input and queries a 'Univseral Whois proxy server' to get the correct details of the Whois query on the input value (check the references for more details about this whois server). + +- **config**: +> - server +> - port + - **input**: >A domain or IP address attribute. + - **output**: >Text describing the result of a whois request for the input value. + - **references**: ->https://github.com/rafiot/uwhoisd +>https://github.com/Lookyloo/uwhoisd + - **requirements**: >uwhois: A whois python library ----- -#### [whoisfreaks](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whoisfreaks.py) +#### [WhoisFreaks Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whoisfreaks.py) An expansion module for https://whoisfreaks.com/ that will provide an enriched analysis of the provided domain, including WHOIS and DNS information. -Our Whois service, DNS Lookup API, and SSL analysis, equips organizations with comprehensive threat intelligence and attack surface analysis capabilities for enhanced security. -Explore our website's product section at https://whoisfreaks.com/ for a wide range of additional services catering to threat intelligence and attack surface analysis needs. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whoisfreaks.py)] + - **features**: >The module takes a domain as input and queries the Whoisfreaks API with it. > >Some parsing operations are then processed on the result of the query to extract as much information as possible. > >After this we map the extracted data to MISP attributes. + +- **config**: +>apikey + - **input**: >A domain whose Data is required + - **output**: >MISP attributes resulting from the query on Whoisfreaks API, included in the following list: >- domain @@ -1985,38 +2921,53 @@ Explore our website's product section at https://whoisfreaks.com/ for a wide ran >- whois-registrar >- whois-creation-date >- domain + - **references**: >https://whoisfreaks.com/ + - **requirements**: >An access to the Whoisfreaks API_KEY ----- -#### [wiki](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/wiki.py) +#### [Wikidata Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/wiki.py) An expansion hover module to extract information from Wikidata to have additional information about particular term for analysis. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/wiki.py)] + - **features**: >This module takes a text attribute as input and queries the Wikidata API. If the text attribute is clear enough to define a specific term, the API returns a wikidata link in response. + - **input**: >Text attribute. + - **output**: >Text attribute. + - **references**: >https://www.wikidata.org + - **requirements**: >SPARQLWrapper python library ----- -#### [xforceexchange](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xforceexchange.py) +#### [IBM X-Force Exchange Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xforceexchange.py) An expansion module for IBM X-Force Exchange. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xforceexchange.py)] + - **features**: >This module takes a MISP attribute as input to query the X-Force API. The API returns then additional information known in their threats data, that is mapped into MISP attributes. + +- **config**: +> - apikey +> - apipassword + - **input**: >A MISP attribute included in the following list: >- ip-src @@ -2025,83 +2976,116 @@ An expansion module for IBM X-Force Exchange. >- md5 >- sha1 >- sha256 + - **output**: >MISP attributes mapped from the result of the query on X-Force Exchange. + - **references**: >https://exchange.xforce.ibmcloud.com/ + - **requirements**: >An access to the X-Force API (apikey) ----- -#### [xlsx_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xlsx_enrich.py) +#### [XLXS Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xlsx_enrich.py) Module to extract freetext from a .xlsx document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xlsx_enrich.py)] + - **features**: >The module reads the text contained in a .xlsx document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a .xlsx document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: >pandas: Python library to perform data analysis, time series and statistics. ----- -#### [yara_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_query.py) +#### [YARA Rule Generator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_query.py) -An expansion & hover module to translate any hash attribute into a yara rule. +jj +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_query.py)] + - **features**: >The module takes a hash attribute (md5, sha1, sha256, imphash) as input, and is returning a YARA rule from it. This YARA rule is also validated using the same method as in 'yara_syntax_validator' module. >Both hover and expansion functionalities are supported with this module, where the hover part is displaying the resulting YARA rule and the expansion part allows you to add the rule as a new attribute, as usual with expansion modules. + - **input**: >MISP Hash attribute (md5, sha1, sha256, imphash, or any of the composite attribute with filename and one of the previous hash type). + - **output**: >YARA rule. + - **references**: > - https://virustotal.github.io/yara/ > - https://github.com/virustotal/yara-python + +- **require_standard_format**: +>True + - **requirements**: >yara-python python library ----- -#### [yara_syntax_validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_syntax_validator.py) +#### [YARA Syntax Validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_syntax_validator.py) An expansion hover module to perform a syntax check on if yara rules are valid or not. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_syntax_validator.py)] + - **features**: >This modules simply takes a YARA rule as input, and checks its syntax. It returns then a confirmation if the syntax is valid, otherwise the syntax error is displayed. + - **input**: >YARA rule attribute. + - **output**: >Text to inform users if their rule is valid. + - **references**: >http://virustotal.github.io/yara/ + - **requirements**: >yara_python python library ----- -#### [yeti](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yeti.py) +#### [Yeti Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yeti.py) Module to process a query on Yeti. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yeti.py)] + - **features**: >This module add context and links between observables using yeti + +- **config**: +> - apikey +> - url + - **input**: >A domain, hostname,IP, sha256,sha1, md5, url of MISP attribute. + - **output**: >MISP attributes and objects fetched from the Yeti instances. + - **references**: > - https://github.com/yeti-platform/yeti > - https://github.com/sebdraven/pyeti + - **requirements**: > - pyeti > - API key @@ -2110,58 +3094,91 @@ Module to process a query on Yeti. ## Export Modules -#### [cef_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cef_export.py) +#### [CEF Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cef_export.py) Module to export a MISP event in CEF format. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cef_export.py)] + - **features**: >The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in Common Event Format. >Thus, there is no particular feature concerning MISP Events since any event can be exported. However, 4 configuration parameters recognized by CEF format are required and should be provided by users before exporting data: the device vendor, product and version, as well as the default severity of data. + +- **config**: +> - Default_Severity +> - Device_Vendor +> - Device_Product +> - Device_Version + - **input**: >MISP Event attributes + - **output**: >Common Event Format file + - **references**: >https://community.softwaregrp.com/t5/ArcSight-Connectors/ArcSight-Common-Event-Format-CEF-Guide/ta-p/1589306?attachment-id=65537 ----- -#### [cisco_firesight_manager_ACL_rule_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py) +#### [Cisco fireSIGHT blockrule Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py) Module to export malicious network activity attributes to Cisco fireSIGHT manager block rules. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py)] + - **features**: >The module goes through the attributes to find all the network activity ones in order to create block rules for the Cisco fireSIGHT manager. + +- **config**: +> - fmc_ip_addr +> - fmc_login +> - fmc_pass +> - domain_id +> - acpolicy_id + - **input**: >Network activity attributes (IPs, URLs). + - **output**: >Cisco fireSIGHT manager block rules. + - **requirements**: >Firesight manager console credentials ----- -#### [defender_endpoint_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/defender_endpoint_export.py) +#### [Microsoft Defender for Endpoint KQL Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/defender_endpoint_export.py) Defender for Endpoint KQL hunting query export module +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/defender_endpoint_export.py)] + - **features**: >This module export an event as Defender for Endpoint KQL queries that can then be used in your own python3 or Powershell tool. If you are using Microsoft Sentinel, you can directly connect your MISP instance to Sentinel and then create queries using the `ThreatIntelligenceIndicator` table to match events against imported IOC. + +- **config**: +>Period + - **input**: >MISP Event attributes + - **output**: >Defender for Endpoint KQL queries + - **references**: >https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/advanced-hunting-schema-reference ----- -#### [goamlexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/goamlexport.py) +#### [GoAML Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/goamlexport.py) This module is used to export MISP events containing transaction objects into GoAML format. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/goamlexport.py)] + - **features**: >The module works as long as there is at least one transaction object in the Event. > @@ -2181,79 +3198,115 @@ This module is used to export MISP events containing transaction objects into Go > - 'entity': Entity owning the bank account - optional. >- person: > - 'address': Address of a person - optional. + +- **config**: +>rentity_id + - **input**: >MISP objects (transaction, bank-account, person, legal-entity, geolocation), with references, describing financial transactions and their origin and target. + - **output**: >GoAML format file, describing financial transactions, with their origin and target (bank accounts, persons or entities). + - **references**: >http://goaml.unodc.org/ + +- **require_standard_format**: +>True + - **requirements**: > - PyMISP > - MISP objects ----- -#### [liteexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/liteexport.py) +#### [Lite Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/liteexport.py) Lite export of a MISP event. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/liteexport.py)] + - **features**: >This module is simply producing a json MISP event format file, but exporting only Attributes from the Event. Thus, MISP Events exported with this module should have attributes that are not internal references, otherwise the resulting event would be empty. + +- **config**: +>indent_json_export + - **input**: >MISP Event attributes + - **output**: >Lite MISP Event ----- -#### [mass_eql_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/mass_eql_export.py) +#### [EQL Query Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/mass_eql_export.py) -Mass EQL query export for a MISP event. +Export MISP event in Event Query Language +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/mass_eql_export.py)] + - **features**: >This module produces EQL queries for all relevant attributes in a MISP event. + - **input**: >MISP Event attributes + - **output**: >Text file containing one or more EQL queries + - **references**: >https://eql.readthedocs.io/en/latest/ ----- -#### [nexthinkexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/nexthinkexport.py) +#### [Nexthink NXQL Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/nexthinkexport.py) Nexthink NXQL query export module +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/nexthinkexport.py)] + - **features**: >This module export an event as Nexthink NXQL queries that can then be used in your own python3 tool or from wget/powershell + +- **config**: +>Period + - **input**: >MISP Event attributes + - **output**: >Nexthink NXQL queries + - **references**: >https://doc.nexthink.com/Documentation/Nexthink/latest/APIAndIntegrations/IntroducingtheWebAPIV2 ----- -#### [osqueryexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/osqueryexport.py) +#### [OSQuery Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/osqueryexport.py) OSQuery export of a MISP event. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/osqueryexport.py)] + - **features**: >This module export an event as osquery queries that can be used in packs or in fleet management solution like Kolide. + - **input**: >MISP Event attributes + - **output**: >osquery SQL queries ----- -#### [pdfexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/pdfexport.py) +#### [Event to PDF Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/pdfexport.py) Simple export of a MISP event to PDF. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/pdfexport.py)] + - **features**: >The module takes care of the PDF file building, and work with any MISP Event. Except the requirement of reportlab, used to create the file, there is no special feature concerning the Event. Some parameters can be given through the config dict. 'MISP_base_url_for_dynamic_link' is your MISP URL, to attach an hyperlink to your event on your MISP instance from the PDF. Keep it clear to avoid hyperlinks in the generated pdf. > 'MISP_name_for_metadata' is your CERT or MISP instance name. Used as text in the PDF' metadata @@ -2262,297 +3315,543 @@ Simple export of a MISP event to PDF. > 'Activate_related_events' is a boolean (True or void) to activate the description of related event. Be aware this might leak information on confidential events linked to the current event ! > 'Activate_internationalization_fonts' is a boolean (True or void) to activate Noto fonts instead of default fonts (Helvetica). This allows the support of CJK alphabet. Be sure to have followed the procedure to download Noto fonts (~70Mo) in the right place (/tools/pdf_fonts/Noto_TTF), to allow PyMisp to find and use them during PDF generation. > 'Custom_fonts_path' is a text (path or void) to the TTF file of your choice, to create the PDF with it. Be aware the PDF won't support bold/italic/special style anymore with this option + +- **config**: +> - MISP_base_url_for_dynamic_link +> - MISP_name_for_metadata +> - Activate_textual_description +> - Activate_galaxy_description +> - Activate_related_events +> - Activate_internationalization_fonts +> - Custom_fonts_path + - **input**: >MISP Event + - **output**: >MISP Event in a PDF file. + - **references**: >https://acrobat.adobe.com/us/en/acrobat/about-adobe-pdf.html + +- **require_standard_format**: +>True + - **requirements**: > - PyMISP > - reportlab ----- -#### [testexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/testexport.py) - -Skeleton export module. - ------ - -#### [threatStream_misp_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threatStream_misp_export.py) +#### [ThreatStream Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threatStream_misp_export.py) Module to export a structured CSV file for uploading to threatStream. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threatStream_misp_export.py)] + - **features**: >The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in a CSV format recognized by ThreatStream. + - **input**: >MISP Event attributes + - **output**: >ThreatStream CSV format file + - **references**: > - https://www.anomali.com/platform/threatstream > - https://github.com/threatstream + - **requirements**: >csv ----- -#### [threat_connect_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threat_connect_export.py) +#### [ThreadConnect Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threat_connect_export.py) Module to export a structured CSV file for uploading to ThreatConnect. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threat_connect_export.py)] + - **features**: >The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in a CSV format recognized by ThreatConnect. >Users should then provide, as module configuration, the source of data they export, because it is required by the output format. + +- **config**: +>Default_Source + - **input**: >MISP Event attributes + - **output**: >ThreatConnect CSV format file + - **references**: >https://www.threatconnect.com + - **requirements**: >csv ----- -#### [virustotal_collections](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/virustotal_collections.py) +#### [VirusTotal Collections Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/virustotal_collections.py) Creates a VT Collection from an event iocs. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/virustotal_collections.py)] + - **features**: >This export module which takes advantage of a new endpoint in VT APIv3 to create VT Collections from IOCs contained in a MISP event. With this module users will be able to create a collection just using the Download as... button. + +- **config**: +> - vt_api_key +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + - **input**: >A domain, hash (md5, sha1, sha256 or sha512), hostname, url or IP address attribute. + - **output**: >A VirusTotal collection in VT. + - **references**: > - https://www.virustotal.com/ > - https://blog.virustotal.com/2021/11/introducing-virustotal-collections.html + - **requirements**: >An access to the VirusTotal API (apikey). ----- -#### [vt_graph](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/vt_graph.py) +#### [VirusTotal Graph Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/vt_graph.py) This module is used to create a VirusTotal Graph from a MISP event. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/vt_graph.py)] + - **features**: >The module takes the MISP event as input and queries the VirusTotal Graph API to create a new graph out of the event. > >Once the graph is ready, we get the url of it, which is returned so we can view it on VirusTotal. + +- **config**: +> - vt_api_key +> - fetch_information +> - private +> - fetch_vt_enterprise +> - expand_one_level +> - user_editors +> - user_viewers +> - group_editors +> - group_viewers + - **input**: >A MISP event. + - **output**: >Link of the VirusTotal Graph created for the event. + - **references**: >https://www.virustotal.com/gui/graph-overview + - **requirements**: >vt_graph_api, the python library to query the VirusTotal graph API ----- +#### [YARA Rule Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/yara_export.py) + + + +This module is used to export MISP events to YARA. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/yara_export.py)] + +- **features**: +>The module will dynamically generate YARA rules for attributes that are marked as to IDS. Basic metadata about the event is added to the rule. +>Attributes that are already YARA rules are also exported, with a rewritten rule name. + +- **input**: +>Attributes and Objects. + +- **output**: +>A YARA file that can be used with the YARA scanning tool. + +- **references**: +>https://virustotal.github.io/yara/ + +- **requirements**: +>yara-python python library + +----- + ## Import Modules -#### [cof2misp](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cof2misp.py) +#### [PDNS COF Importer](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cof2misp.py) Passive DNS Common Output Format (COF) MISP importer +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cof2misp.py)] + - **features**: >Takes as input a valid COF file or the output of the dnsdbflex utility and creates MISP objects for the input. + - **input**: >Passive DNS output in Common Output Format (COF) + - **output**: >MISP objects + - **references**: >https://tools.ietf.org/id/draft-dulaunoy-dnsop-passive-dns-cof-08.html + - **requirements**: >PyMISP ----- -#### [csvimport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/csvimport.py) +#### [CSV Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/csvimport.py) Module to import MISP attributes from a csv file. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/csvimport.py)] + - **features**: >In order to parse data from a csv file, a header is required to let the module know which column is matching with known attribute fields / MISP types. > >This header either comes from the csv file itself or is part of the configuration of the module and should be filled out in MISP plugin settings, each field separated by COMMAS. Fields that do not match with any type known in MISP or are not MISP attribute fields should be ignored in import, using a space or simply nothing between two separators (example: 'ip-src, , comment, '). > >If the csv file already contains a header that does not start by a '#', you should tick the checkbox 'has_header' to avoid importing it and have potential issues. You can also redefine the header even if it is already contained in the file, by following the rules for headers explained earlier. One reason why you would redefine a header is for instance when you want to skip some fields, or some fields are not valid types. + - **input**: >CSV format file. + - **output**: >MISP Event attributes + - **references**: > - https://tools.ietf.org/html/rfc4180 > - https://tools.ietf.org/html/rfc7111 + - **requirements**: >PyMISP ----- -#### [cuckooimport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cuckooimport.py) +#### [Cuckoo Sandbox Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cuckooimport.py) Module to import Cuckoo JSON. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cuckooimport.py)] + - **features**: ->The module simply imports MISP Attributes from a Cuckoo JSON format file. There is thus no special feature to make it work. +>Import a Cuckoo archive (zipfile or bzip2 tarball), either downloaded manually or exported from the API (/tasks/report//all). + - **input**: >Cuckoo JSON file + - **output**: >MISP Event attributes + - **references**: > - https://cuckoosandbox.org/ > - https://github.com/cuckoosandbox/cuckoo ----- -#### [email_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/email_import.py) +#### [Email Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/email_import.py) + +Email import module for MISP +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/email_import.py)] -Module to import emails in MISP. - **features**: >This module can be used to import e-mail text as well as attachments and urls. >3 configuration parameters are then used to unzip attachments, guess zip attachment passwords, and extract urls: set each one of them to True or False to process or not the respective corresponding actions. + +- **config**: +> - unzip_attachments +> - guess_zip_attachment_passwords +> - extract_urls + - **input**: >E-mail file + - **output**: >MISP Event attributes ----- -#### [goamlimport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/goamlimport.py) +#### [GoAML Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/goamlimport.py) Module to import MISP objects about financial transactions from GoAML files. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/goamlimport.py)] + - **features**: >Unlike the GoAML export module, there is here no special feature to import data from GoAML external files, since the module will import MISP Objects with their References on its own, as it is required for the export module to rebuild a valid GoAML document. + - **input**: >GoAML format file, describing financial transactions, with their origin and target (bank accounts, persons or entities). + - **output**: >MISP objects (transaction, bank-account, person, legal-entity, geolocation), with references, describing financial transactions and their origin and target. + - **references**: >http://goaml.unodc.org/ + - **requirements**: >PyMISP ----- -#### [joe_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/joe_import.py) +#### [Import Blueprint](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/import_blueprint.py) + +Generic blueprint to be copy-pasted to quickly boostrap creation of import module. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/import_blueprint.py)] + +- **features**: +> + +----- + +#### [Joe Sandbox Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/joe_import.py) A module to import data from a Joe Sandbox analysis json report. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/joe_import.py)] + - **features**: >Module using the new format of modules able to return attributes and objects. > >The module returns the same results as the expansion module [joesandbox_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) using the submission link of the analysis to get the json report. + - **input**: >Json report of a Joe Sandbox analysis. + - **output**: >MISP attributes & objects parsed from the analysis report. + - **references**: > - https://www.joesecurity.org > - https://www.joesandbox.com/ ----- -#### [lastline_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/lastline_import.py) +#### [Lastline Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/lastline_import.py) Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Module to import and parse reports from Lastline analysis links. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/lastline_import.py)] + - **features**: >The module requires a Lastline Portal `username` and `password`. >The module uses the new format and it is able to return MISP attributes and objects. >The module returns the same results as the [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) expansion module. + +- **config**: +> - username +> - password +> - verify_ssl + - **input**: >Link to a Lastline analysis. + - **output**: >MISP attributes and objects parsed from the analysis report. + - **references**: >https://www.lastline.com ----- -#### [mispjson](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/mispjson.py) +#### [MISP JSON Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/mispjson.py) Module to import MISP JSON format for merging MISP events. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/mispjson.py)] + - **features**: >The module simply imports MISP Attributes from an other MISP Event in order to merge events together. There is thus no special feature to make it work. + - **input**: >MISP Event + - **output**: >MISP Event attributes ----- -#### [ocr](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/ocr.py) +#### [OCR Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/ocr.py) Optical Character Recognition (OCR) module for MISP. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/ocr.py)] + - **features**: >The module tries to recognize some text from an image and import the result as a freetext attribute, there is then no special feature asked to users to make it work. + - **input**: >Image + - **output**: >freetext MISP attribute ----- -#### [openiocimport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/openiocimport.py) +#### [OpenIOC Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/openiocimport.py) Module to import OpenIOC packages. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/openiocimport.py)] + - **features**: >The module imports MISP Attributes from OpenIOC packages, there is then no special feature for users to make it work. + - **input**: >OpenIOC packages + - **output**: >MISP Event attributes + - **references**: >https://www.fireeye.com/blog/threat-research/2013/10/openioc-basics.html + - **requirements**: >PyMISP ----- -#### [threatanalyzer_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/threatanalyzer_import.py) +#### [TAXII 2.1 Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/taxii21.py) + +Import content from a TAXII 2.1 server +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/taxii21.py)] + +- **features**: +> + +- **config**: +>stix_object_limit + +----- + +#### [ThreadAnalyzer Sandbox Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/threatanalyzer_import.py) Module to import ThreatAnalyzer archive.zip / analysis.json files. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/threatanalyzer_import.py)] + - **features**: >The module imports MISP Attributes from a ThreatAnalyzer format file. This file can be either ZIP, or JSON format. >There is by the way no special feature for users to make the module work. + - **input**: >ThreatAnalyzer format file + - **output**: >MISP Event attributes + - **references**: >https://www.threattrack.com/malware-analysis.aspx ----- -#### [vmray_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_import.py) +#### [URL Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/url_import.py) + +Simple URL import tool with Faup +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/url_import.py)] + +- **features**: +> + +----- + +#### [VMRay API Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_import.py) Module to import VMRay (VTI) results. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_import.py)] + - **features**: >The module imports MISP Attributes from VMRay format, using the VMRay api. >Users should then provide as the module configuration the API Key as well as the server url in order to fetch their data to import. + +- **config**: +> - apikey +> - url +> - disable_tags +> - disable_misp_objects +> - ignore_analysis_finished + - **input**: >VMRay format + - **output**: >MISP Event attributes + - **references**: >https://www.vmray.com/ + - **requirements**: >vmray_rest_api ----- + +#### [VMRay Summary JSON Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_summary_json_import.py) + +Import a VMRay Summary JSON report. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_summary_json_import.py)] + +- **features**: +> + +- **config**: +>disable_tags + +----- + +## Action Modules + +#### [Mattermost](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/mattermost.py) + +Simplistic module to send message to a Mattermost channel. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/mattermost.py)] + +- **features**: +> + +- **config**: +>{'params': {'mattermost_hostname': {'type': 'string', 'description': 'The Mattermost domain or URL', 'value': 'example.mattermost.com'}, 'bot_access_token': {'type': 'string', 'description': 'Access token generated when you created the bot account'}, 'channel_id': {'type': 'string', 'description': 'The channel you added the bot to'}, 'message_template': {'type': 'large_string', 'description': 'The template to be used to generate the message to be posted', 'value': 'The **template** will be rendered using *Jinja2*!', 'jinja_supported': True}}, 'blocking': False, 'support_filters': True, 'expect_misp_core_format': False} + +----- + +#### [Slack](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/slack.py) + +Simplistic module to send messages to a Slack channel. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/slack.py)] + +- **features**: +> + +- **config**: +>{'params': {'slack_bot_token': {'type': 'string', 'description': 'The Slack bot token generated when you created the bot account'}, 'channel_id': {'type': 'string', 'description': 'The channel ID you want to post messages to'}, 'message_template': {'type': 'large_string', 'description': 'The template to be used to generate the message to be posted', 'value': 'The **template** will be rendered using *Jinja2*!', 'jinja_supported': True}}, 'blocking': False, 'support_filters': True, 'expect_misp_core_format': False} + +----- + +#### [Test action](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/testaction.py) + +This module is merely a test, always returning true. Triggers on event publishing. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/testaction.py)] + +- **features**: +> + +- **config**: +>{'params': {'foo': {'type': 'string', 'description': 'blablabla', 'value': 'xyz'}, 'Data extraction path': {'type': 'hash_path', 'description': 'Only post content extracted from this path', 'value': 'Attribute.{n}.AttributeTag.{n}.Tag.name'}}, 'blocking': False, 'support_filters': False, 'expect_misp_core_format': False} + +----- diff --git a/documentation/generate_documentation.py b/documentation/generate_documentation.py old mode 100644 new mode 100755 index c6b1cc7c..efab7cca --- a/documentation/generate_documentation.py +++ b/documentation/generate_documentation.py @@ -1,55 +1,108 @@ # -*- coding: utf-8 -*- import os -import json -import sys from pathlib import Path +import importlib +import copy -module_types = ['expansion', 'export_mod', 'import_mod'] -titles = ['Expansion Modules', 'Export Modules', 'Import Modules'] +module_types = ['expansion', 'export_mod', 'import_mod', 'action_mod'] +titles = ['Expansion Modules', 'Export Modules', 'Import Modules', 'Action Modules'] githublink = 'https://github.com/MISP/misp-modules/tree/main/misp_modules/modules' +githubiolink = 'https://misp.github.io/misp-modules' + +moduleinfo_to_ignore = ['module-type', 'author', 'version'] + +_all_moduleinfo = {} + + +def get_all_moduleinfo(): + ''' + Get all module information from the modules. + Behaves like a singleton, so it will only load the modules once. + ''' + if not _all_moduleinfo: + for module_type in module_types: + _all_moduleinfo[module_type] = {} + module_type_module = importlib.import_module(f"misp_modules.modules.{module_type}") + module_type_module.__all__.sort() + for module_name in module_type_module.__all__: + module_package_name = f"misp_modules.modules.{module_type}.{module_name}" + try: + module = importlib.import_module(module_package_name) + moduleinfo = copy.deepcopy(module.version()) + except Exception: + continue # skip if we have issues loading the module + + moduleinfo = dict(sorted(moduleinfo.items())) + _all_moduleinfo[module_type][module_name] = moduleinfo + + return _all_moduleinfo def generate_doc(module_type, root_path, logo_path='logos'): markdown = [] - current_path = os.path.join(root_path, 'website', module_type) - files = sorted(os.listdir(current_path)) + # current_path = os.path.join(root_path, 'website', module_type) + # files = sorted(os.listdir(current_path)) githubpath = f'{githublink}/{module_type}' - for filename in files: - modulename = filename.split('.json')[0] - githubref = f'{githubpath}/{modulename}.py' - markdown.append(f'\n#### [{modulename}]({githubref})\n') - filename = os.path.join(current_path, filename) - print(f'Processing {filename}') - with open(filename, 'rt') as f: - definition = json.loads(f.read()) - if 'logo' in definition: - logo = os.path.join(logo_path, definition.pop('logo')) + + for module_name, moduleinfo in get_all_moduleinfo()[module_type].items(): + githubref = f'{githubpath}/{module_name}.py' + + moduleinfo = copy.deepcopy(moduleinfo) # ensure to not modify the original data + for i in moduleinfo_to_ignore: + moduleinfo.pop(i) + + try: + module_name_pretty = moduleinfo.pop('name') + except KeyError: + exit(f"ERROR: Issue with module {module_name} - no field 'name' provided") + if module_name_pretty == '': + module_name_pretty = module_name + + markdown.append(f'\n#### [{module_name_pretty}]({githubref})\n') + if moduleinfo['logo'] != '': + logo = os.path.join(logo_path, moduleinfo.pop('logo')) markdown.append(f"\n\n") - if 'description' in definition: - markdown.append(f"\n{definition.pop('description')}\n") - for field, value in sorted(definition.items()): + if 'description' in moduleinfo: + markdown.append(f"\n{moduleinfo.pop('description')}\n") + markdown.append(f"[[source code]({githubref})]\n") + if 'features' in moduleinfo: + markdown.append(get_single_value('features', str(moduleinfo.pop('features')).replace('\n', '\n>'))) + for field, value in sorted(moduleinfo.items()): if not value: continue if isinstance(value, list): markdown.append(handle_list(field, value)) continue - markdown.append(get_single_value(field, value.replace('\n', '\n>'))) + markdown.append(get_single_value(field, str(value).replace('\n', '\n>'))) markdown.append('\n-----\n') return markdown +def generate_index_doc(module_type, root_path): + markdown = [] + for module_name, moduleinfo in get_all_moduleinfo()[module_type].items(): + module_name_pretty = moduleinfo.get('name') + if module_name_pretty == '': + module_name_pretty = module_name + + anchor_ref = f"{githubiolink}/{module_type}/#{module_name_pretty.replace(' ', '-').lower()}" + description_without_newlines = moduleinfo.get("description").replace('\n', ' ') + markdown.append(f'* [{module_name_pretty}]({anchor_ref}) - {description_without_newlines}\n') + return markdown + + def get_single_value(field, value): - return f"- **{field}**:\n>{value}\n" + return f"\n- **{field}**:\n>{value}\n" def handle_list(field, values): if len(values) == 1: return get_single_value(field, values[0]) values = '\n> - '.join(values) - return f"- **{field}**:\n> - {values}\n" + return f"\n- **{field}**:\n> - {values}\n" -def write_doc(root_path): +def write_doc_for_readme(root_path): markdown = ["# MISP modules documentation\n"] for _path, title in zip(module_types, titles): markdown.append(f'\n## {title}\n') @@ -65,7 +118,61 @@ def write_docs_for_mkdocs(root_path): w.write(''.join(markdown)) +def update_docs_for_mkdocs_index(root_path): + with open(root_path / 'mkdocs' / 'index.md', 'r') as r: + old_doc = r.readlines() + + new_doc = [] + skip = False + for line in old_doc: + if skip and not line.startswith('## '): # find next title + continue # skip lines, as we're in the block that we're auto-generating + + skip = False + new_doc.append(line) + + if line.startswith('## Existing MISP modules'): + skip = True + # generate the updated content + for _path, title in zip(module_types, titles): + new_doc.append(f'\n### {title}\n') + new_doc.extend(generate_index_doc(_path, root_path)) + new_doc.append('\n\n') + + with open(root_path / 'mkdocs' / 'index.md', 'w') as w: + w.write(''.join(new_doc)) + pass + + +def update_readme(root_path): + with open(root_path / 'README.md', 'r') as r: + old_readme = r.readlines() + + new_doc = [] + skip = False + for line in old_readme: + if skip and not line.startswith('# List of MISP modules'): # find next title + continue # skip lines, as we're in the block that we're auto-generating + + new_doc.append(line) + + if line.startswith('# List of MISP modules'): + skip = True + # generate the updated content + for _path, title in zip(module_types, titles): + new_doc.append(f'\n## {title}\n') + new_doc.extend(generate_index_doc(_path, root_path)) + new_doc.append('\n\n') + + with open(root_path / 'README.md', 'w') as w: + w.write(''.join(new_doc)) + pass + + if __name__ == '__main__': root_path = Path(__file__).resolve().parent - write_doc(root_path) + + write_doc_for_readme(root_path) write_docs_for_mkdocs(root_path) + update_docs_for_mkdocs_index(root_path) + update_readme(root_path.parent) diff --git a/docs/img/favicon.ico b/documentation/img/favicon.ico similarity index 100% rename from docs/img/favicon.ico rename to documentation/img/favicon.ico diff --git a/docs/img/misp.png b/documentation/img/misp.png similarity index 100% rename from docs/img/misp.png rename to documentation/img/misp.png diff --git a/documentation/logos/google_threat_intelligence.png b/documentation/logos/google_threat_intelligence.png new file mode 100644 index 00000000..9a2067b2 Binary files /dev/null and b/documentation/logos/google_threat_intelligence.png differ diff --git a/docs/logos/misp-modules-full-small.png b/documentation/logos/misp-modules-full-small.png similarity index 100% rename from docs/logos/misp-modules-full-small.png rename to documentation/logos/misp-modules-full-small.png diff --git a/docs/logos/misp-modules-full.png b/documentation/logos/misp-modules-full.png similarity index 100% rename from docs/logos/misp-modules-full.png rename to documentation/logos/misp-modules-full.png diff --git a/docs/logos/misp-modules-full.svg b/documentation/logos/misp-modules-full.svg similarity index 100% rename from docs/logos/misp-modules-full.svg rename to documentation/logos/misp-modules-full.svg diff --git a/docs/logos/misp-modules-small.png b/documentation/logos/misp-modules-small.png similarity index 100% rename from docs/logos/misp-modules-small.png rename to documentation/logos/misp-modules-small.png diff --git a/docs/logos/misp-modules.svg b/documentation/logos/misp-modules.svg similarity index 100% rename from docs/logos/misp-modules.svg rename to documentation/logos/misp-modules.svg diff --git a/documentation/logos/virustotal.png b/documentation/logos/virustotal.png index 935c5ccf..1bb597f0 100644 Binary files a/documentation/logos/virustotal.png and b/documentation/logos/virustotal.png differ diff --git a/documentation/mkdocs/REQUIREMENTS.txt b/documentation/mkdocs/REQUIREMENTS.txt deleted file mode 100644 index ad07dd16..00000000 --- a/documentation/mkdocs/REQUIREMENTS.txt +++ /dev/null @@ -1,3 +0,0 @@ -mkdocs -mkdocs-material -markdown_include \ No newline at end of file diff --git a/documentation/mkdocs/action_mod.md b/documentation/mkdocs/action_mod.md new file mode 100644 index 00000000..68c509a0 --- /dev/null +++ b/documentation/mkdocs/action_mod.md @@ -0,0 +1,39 @@ + +#### [Mattermost](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/mattermost.py) + +Simplistic module to send message to a Mattermost channel. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/mattermost.py)] + +- **features**: +> + +- **config**: +>{'params': {'mattermost_hostname': {'type': 'string', 'description': 'The Mattermost domain or URL', 'value': 'example.mattermost.com'}, 'bot_access_token': {'type': 'string', 'description': 'Access token generated when you created the bot account'}, 'channel_id': {'type': 'string', 'description': 'The channel you added the bot to'}, 'message_template': {'type': 'large_string', 'description': 'The template to be used to generate the message to be posted', 'value': 'The **template** will be rendered using *Jinja2*!', 'jinja_supported': True}}, 'blocking': False, 'support_filters': True, 'expect_misp_core_format': False} + +----- + +#### [Slack](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/slack.py) + +Simplistic module to send messages to a Slack channel. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/slack.py)] + +- **features**: +> + +- **config**: +>{'params': {'slack_bot_token': {'type': 'string', 'description': 'The Slack bot token generated when you created the bot account'}, 'channel_id': {'type': 'string', 'description': 'The channel ID you want to post messages to'}, 'message_template': {'type': 'large_string', 'description': 'The template to be used to generate the message to be posted', 'value': 'The **template** will be rendered using *Jinja2*!', 'jinja_supported': True}}, 'blocking': False, 'support_filters': True, 'expect_misp_core_format': False} + +----- + +#### [Test action](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/testaction.py) + +This module is merely a test, always returning true. Triggers on event publishing. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/action_mod/testaction.py)] + +- **features**: +> + +- **config**: +>{'params': {'foo': {'type': 'string', 'description': 'blablabla', 'value': 'xyz'}, 'Data extraction path': {'type': 'hash_path', 'description': 'Only post content extracted from this path', 'value': 'Attribute.{n}.AttributeTag.{n}.Tag.name'}}, 'blocking': False, 'support_filters': False, 'expect_misp_core_format': False} + +----- diff --git a/documentation/mkdocs/contribute.md b/documentation/mkdocs/contribute.md index ef312f6a..de499663 100644 --- a/documentation/mkdocs/contribute.md +++ b/documentation/mkdocs/contribute.md @@ -1,6 +1,6 @@ ## How to add your own MISP modules? -Create your module in [misp_modules/modules/expansion/](https://github.com/MISP/misp-modules/tree/master/misp_modules/modules/expansion/), [misp_modules/modules/export_mod/](https://github.com/MISP/misp-modules/tree/master/misp_modules/modules/export_mod/), or [misp_modules/modules/import_mod/](https://github.com/MISP/misp-modules/tree/master/misp_modules/modules/import_mod/). The module should have at minimum three functions: +Create your module in [misp_modules/modules/expansion/](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/), [misp_modules/modules/export_mod/](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/), or [misp_modules/modules/import_mod/](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/). The module should have at minimum three functions: * **introspection** function that returns a dict of the supported attributes (input and output) by your expansion module. * **handler** function which accepts a JSON document to expand the values and return a dictionary of the expanded values. @@ -309,22 +309,27 @@ Recommended Plugin.Import_ocr_enabled true Enable or disable the ocr In this same menu set any other plugin settings that are required for testing. +## Install misp-module on an offline instance. +First, you need to grab all necessary packages for example like this : +Use pip wheel to create an archive +~~~ +mkdir misp-modules-offline +pip3 wheel -r REQUIREMENTS shodan --wheel-dir=./misp-modules-offline +tar -cjvf misp-module-bundeled.tar.bz2 ./misp-modules-offline/* +~~~ +On offline machine : +~~~ +mkdir misp-modules-bundle +tar xvf misp-module-bundeled.tar.bz2 -C misp-modules-bundle +cd misp-modules-bundle +ls -1|while read line; do sudo pip3 install --force-reinstall --ignore-installed --upgrade --no-index --no-deps ${line};done +~~~ +Next you can follow standard install procedure. -## Documentation +## How to contribute your own module? -In order to provide documentation about some modules that require specific input / output / configuration, the [doc](https://github.com/MISP/misp-modules/tree/master/doc) directory contains detailed information about the general purpose, requirements, features, input and output of each of these modules: - -- ***description** - quick description of the general purpose of the module, as the one given by the moduleinfo -- **requirements** - special libraries needed to make the module work -- **features** - description of the way to use the module, with the required MISP features to make the module give the intended result -- **references** - link(s) giving additional information about the format concerned in the module -- **input** - description of the format of data used in input -- **output** - description of the format given as the result of the module execution - -In addition to the module documentation please add your module to [docs/index.md](https://github.com/MISP/misp-modules/tree/master/docs/index.md). - -There are also [complementary slides](https://www.misp-project.org/misp-training/3.1-misp-modules.pdf) for the creation of MISP modules. +Fork the project, add your module, test it and make a pull-request. Modules can be also private as you can add a module in your own MISP installation. ## Tips for developers creating modules @@ -334,7 +339,7 @@ Download a pre-built virtual image from the [MISP training materials](https://ww - Create a Host-Only adapter in VirtualBox - Set your Misp OVA to that Host-Only adapter - Start the virtual machine -- Get the IP address of the virutal machine +- Get the IP address of the virtual machine - SSH into the machine (Login info on training page) - Go into the misp-modules directory @@ -352,16 +357,18 @@ sudo git checkout MyModBranch Remove the contents of the build directory and re-install misp-modules. -~~~python +~~~bash sudo rm -fr build/* -sudo pip3 install --upgrade . +sudo -u www-data /var/www/MISP/venv/bin/pip install --upgrade . ~~~ SSH in with a different terminal and run `misp-modules` with debugging enabled. -~~~python -sudo killall misp-modules -misp-modules -d +~~~bash +# In case misp-modules is not a service do: +# sudo killall misp-modules +sudo systemctl disable --now misp-modules +sudo -u www-data /var/www/MISP/venv/bin/misp-modules -d ~~~ @@ -372,3 +379,17 @@ cd tests/ curl -s http://127.0.0.1:6666/query -H "Content-Type: application/json" --data @MY_TEST_FILE.json -X POST cd ../ ~~~ + +## Documentation + +In order to provide documentation about some modules that require specific input / output / configuration, the [index.md](index.md) file contains detailed information about the general purpose, requirements, features, input and ouput of each of these modules: + +- **description** - quick description of the general purpose of the module, as the one given by the moduleinfo +- **requirements** - special libraries needed to make the module work +- **features** - description of the way to use the module, with the required MISP features to make the module give the intended result +- **references** - link(s) giving additional information about the format concerned in the module +- **input** - description of the format of data used in input +- **output** - description of the format given as the result of the module execution + +## Licenses +For further Information see also the [license file](license/). diff --git a/documentation/mkdocs/expansion.md b/documentation/mkdocs/expansion.md index 5379c823..4b24cab7 100644 --- a/documentation/mkdocs/expansion.md +++ b/documentation/mkdocs/expansion.md @@ -1,217 +1,337 @@ -#### [apiosintds](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apiosintds.py) +#### [Abuse IPDB](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/abuseipdb.py) + +AbuseIPDB MISP expansion module +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/abuseipdb.py)] + +- **features**: +> + +- **config**: +> - api_key +> - max_age_in_days +> - abuse_threshold + +----- + +#### [OSINT DigitalSide](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apiosintds.py) On demand query API for OSINT.digitalside.it project. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apiosintds.py)] + - **features**: >The module simply queries the API of OSINT.digitalside.it with a domain, ip, url or hash attribute. > >The result of the query is then parsed to extract additional hashes or urls. A module parameters also allows to parse the hashes related to the urls. > >Furthermore, it is possible to cache the urls and hashes collected over the last 7 days by OSINT.digitalside.it + +- **config**: +> - STIX2_details +> - import_related +> - cache +> - cache_directory +> - cache_timeout_h +> - local_directory + - **input**: >A domain, ip, url or hash attribute. + - **output**: >Hashes and urls resulting from the query to OSINT.digitalside.it + - **references**: >https://osint.digitalside.it/#About + - **requirements**: >The apiosintDS python library to query the OSINT.digitalside.it API. ----- -#### [apivoid](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apivoid.py) +#### [APIVoid](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apivoid.py) Module to query APIVoid with some domain attributes. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/apivoid.py)] + - **features**: >This module takes a domain name and queries API Void to get the related DNS records and the SSL certificates. It returns then those pieces of data as MISP objects that can be added to the event. > >To make it work, a valid API key and enough credits to proceed 2 queries (0.06 + 0.07 credits) are required. + +- **config**: +>apikey + - **input**: >A domain attribute. + - **output**: >DNS records and SSL certificates related to the domain. + - **references**: >https://www.apivoid.com/ + - **requirements**: >A valid APIVoid API key with enough credits to proceed 2 queries ----- -#### [assemblyline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_query.py) +#### [AssemblyLine Query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_query.py) A module tu query the AssemblyLine API with a submission ID to get the submission report and parse it. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_query.py)] + - **features**: >The module requires the address of the AssemblyLine server you want to query as well as your credentials used for this instance. Credentials include the used-ID and an API key or the password associated to the user-ID. > >The submission ID extracted from the submission link is then used to query AssemblyLine and get the full submission report. This report is parsed to extract file objects and the associated IPs, domains or URLs the files are connecting to. > >Some more data may be parsed in the future. + +- **config**: +> - apiurl +> - user_id +> - apikey +> - password +> - verifyssl + - **input**: >Link of an AssemblyLine submission report. + - **output**: >MISP attributes & objects parsed from the AssemblyLine submission. + - **references**: >https://www.cyber.gc.ca/en/assemblyline + - **requirements**: >assemblyline_client: Python library to query the AssemblyLine rest API. ----- -#### [assemblyline_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_submit.py) +#### [AssemblyLine Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_submit.py) A module to submit samples and URLs to AssemblyLine for advanced analysis, and return the link of the submission. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/assemblyline_submit.py)] + - **features**: >The module requires the address of the AssemblyLine server you want to query as well as your credentials used for this instance. Credentials include the user-ID and an API key or the password associated to the user-ID. > >If the sample or url is correctly submitted, you get then the link of the submission. + +- **config**: +> - apiurl +> - user_id +> - apikey +> - password +> - verifyssl + - **input**: >Sample, or url to submit to AssemblyLine. + - **output**: >Link of the report generated in AssemblyLine. + - **references**: >https://www.cyber.gc.ca/en/assemblyline + - **requirements**: >assemblyline_client: Python library to query the AssemblyLine rest API. ----- -#### [backscatter_io](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/backscatter_io.py) +#### [Backscatter.io](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/backscatter_io.py) -Query backscatter.io (https://backscatter.io/). +Backscatter.io module to bring mass-scanning observations into MISP. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/backscatter_io.py)] + - **features**: >The module takes a source or destination IP address as input and displays the information known by backscatter.io. + +- **config**: +>api_key + - **input**: >IP addresses. + - **output**: >Text containing a history of the IP addresses especially on scanning based on backscatter.io information . + - **references**: >https://pypi.org/project/backscatter/ + - **requirements**: >backscatter python library ----- -#### [bgpranking](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/bgpranking.py) - -Query BGP Ranking (https://bgpranking-ng.circl.lu/). -- **features**: ->The module takes an AS number attribute as input and displays its description as well as its ranking position in BGP Ranking for a given day. -- **input**: ->Autonomous system number. -- **output**: ->An asn object with its related bgp-ranking object. -- **references**: ->https://github.com/D4-project/BGP-Ranking/ -- **requirements**: ->pybgpranking python library - ------ - -#### [btc_scam_check](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_scam_check.py) +#### [BTC Scam Check](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_scam_check.py) An expansion hover module to query a special dns blacklist to check if a bitcoin address has been abused. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_scam_check.py)] + - **features**: >The module queries a dns blacklist directly with the bitcoin address and get a response if the address has been abused. + - **input**: >btc address attribute. + - **output**: >Text to indicate if the BTC address has been abused. + - **references**: >https://btcblack.it/ + - **requirements**: >dnspython3: dns python library ----- -#### [btc_steroids](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_steroids.py) +#### [BTC Steroids](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_steroids.py) An expansion hover module to get a blockchain balance from a BTC address in MISP. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_steroids.py)] + +- **features**: +> + - **input**: >btc address attribute. + - **output**: >Text to describe the blockchain balance and the transactions related to the btc address in input. ----- -#### [censys_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/censys_enrich.py) +#### [Censys Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/censys_enrich.py) An expansion module to enrich attributes in MISP by quering the censys.io API +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/censys_enrich.py)] + - **features**: >This module takes an IP, hostname or a certificate fingerprint and attempts to enrich it by querying the Censys API. + +- **config**: +> - api_id +> - api_secret + - **input**: >IP, domain or certificate fingerprint (md5, sha1 or sha256) + - **output**: >MISP objects retrieved from censys, including open ports, ASN, Location of the IP, x509 details + - **references**: >https://www.censys.io + - **requirements**: >API credentials to censys.io ----- -#### [circl_passivedns](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivedns.py) +#### [CIRCL Passive DNS](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivedns.py) Module to access CIRCL Passive DNS. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivedns.py)] + - **features**: >This module takes a hostname, domain or ip-address (ip-src or ip-dst) attribute as input, and queries the CIRCL Passive DNS REST API to get the asssociated passive dns entries and return them as MISP objects. > >To make it work a username and a password are thus required to authenticate to the CIRCL Passive DNS API. + +- **config**: +> - username +> - password + - **input**: >Hostname, domain, or ip-address attribute. + - **ouput**: >Passive DNS objects related to the input attribute. + - **references**: > - https://www.circl.lu/services/passive-dns/ > - https://datatracker.ietf.org/doc/draft-dulaunoy-dnsop-passive-dns-cof/ + - **requirements**: > - pypdns: Passive DNS python library > - A CIRCL passive DNS account with username & password ----- -#### [circl_passivessl](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivessl.py) +#### [CIRCL Passive SSL](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivessl.py) Modules to access CIRCL Passive SSL. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivessl.py)] + - **features**: >This module takes an ip-address (ip-src or ip-dst) attribute as input, and queries the CIRCL Passive SSL REST API to gather the related certificates and return the corresponding MISP objects. > >To make it work a username and a password are required to authenticate to the CIRCL Passive SSL API. + +- **config**: +> - username +> - password + - **input**: >IP address attribute. + - **output**: >x509 certificate objects seen by the IP address(es). + - **references**: >https://www.circl.lu/services/passive-ssl/ + - **requirements**: > - pypssl: Passive SSL python library > - A CIRCL passive SSL account with username & password ----- -#### [cluster25_expand](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cluster25_expand.py) +#### [ClaamAV](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/clamav.py) + +Submit file to ClamAV +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/clamav.py)] + +- **features**: +> + +- **config**: +>connection + +----- + +#### [Cluster25 Expand](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cluster25_expand.py) Module to query Cluster25 CTI. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cluster25_expand.py)] + - **features**: >This module takes a MISP attribute value as input to query the Cluster25CTI API. The result is then mapped into compatible MISP Objects and relative attributes. > + +- **config**: +> - api_id +> - apikey +> - base_url + - **input**: >An Indicator value of type included in the following list: >- domain @@ -228,79 +348,116 @@ Module to query Cluster25 CTI. >- btc >- xmr > ja3-fingerprint-md5 + - **output**: >A series of c25 MISP Objects with colletion of attributes mapped from Cluster25 CTI query result. + - **references**: > + - **requirements**: >A Cluster25 API access (API id & key) ----- -#### [countrycode](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/countrycode.py) +#### [Country Code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/countrycode.py) Module to expand country codes. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/countrycode.py)] + - **features**: >The module takes a domain or a hostname as input, and returns the country it belongs to. > >For non country domains, a list of the most common possible extensions is used. + - **input**: >Hostname or domain attribute. + - **output**: >Text with the country code the input belongs to. ----- -#### [cpe](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cpe.py) +#### [CPE Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cpe.py) An expansion module to query the CVE search API with a cpe code to get its related vulnerabilities. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cpe.py)] + - **features**: >The module takes a cpe attribute as input and queries the CVE search API to get its related vulnerabilities. >The list of vulnerabilities is then parsed and returned as vulnerability objects. > ->Users can use their own CVE search API url by defining a value to the custom_API_URL parameter. If no custom API url is given, the default cve.circl.lu api url is used. +>Users can use their own CVE search API url by defining a value to the custom_API_URL parameter. If no custom API url is given, the default vulnerability.circl.lu api url is used. > >In order to limit the amount of data returned by CVE serach, users can also the limit parameter. With the limit set, the API returns only the requested number of vulnerabilities, sorted from the highest cvss score to the lowest one. + +- **config**: +> - custom_API_URL +> - limit + - **input**: >CPE attribute. + - **output**: >The vulnerabilities related to the CPE. + - **references**: ->https://cve.circl.lu/api/ +>https://vulnerability.circl.lu/api/ ----- -#### [crowdsec](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdsec.py) +#### [CrowdSec CTI](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdsec.py) -Hover module to lookup an IP in CrowdSec's CTI +Module to access CrowdSec CTI API. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdsec.py)] + - **features**: >This module enables IP lookup from CrowdSec CTI API. It provides information about the IP, such as what kind of attacks it has been participant of as seen by CrowdSec's network. It also includes enrichment by CrowdSec like background noise score, aggressivity over time etc. + +- **config**: +> - api_key +> - add_reputation_tag +> - add_behavior_tag +> - add_classification_tag +> - add_mitre_technique_tag +> - add_cve_tag + - **input**: >An IP address. + - **output**: >IP Lookup information from CrowdSec CTI API + - **references**: > - https://www.crowdsec.net/ > - https://docs.crowdsec.net/docs/cti_api/getting_started > - https://app.crowdsec.net/ + - **requirements**: >A CrowdSec CTI API key. Get yours by following https://docs.crowdsec.net/docs/cti_api/getting_started/#getting-an-api-key ----- -#### [crowdstrike_falcon](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdstrike_falcon.py) +#### [CrowdStrike Falcon](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdstrike_falcon.py) -Module to query Crowdstrike Falcon. +Module to query CrowdStrike Falcon. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdstrike_falcon.py)] + - **features**: >This module takes a MISP attribute as input to query a CrowdStrike Falcon API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes. > >Please note that composite attributes composed by at least one of the input types mentionned below (domains, IPs, hostnames) are also supported. + +- **config**: +> - api_id +> - apikey + - **input**: >A MISP attribute included in the following list: >- domain @@ -323,6 +480,7 @@ Module to query Crowdstrike Falcon. >- user-agent >- whois-registrant-email >- x509-fingerprint-md5 + - **output**: >MISP attributes mapped after the CrowdStrike API has been queried, included in the following list: >- hostname @@ -339,155 +497,231 @@ Module to query Crowdstrike Falcon. >- url >- user-agent >- x509-fingerprint-md5 + - **references**: >https://www.crowdstrike.com/products/crowdstrike-falcon-faq/ + - **requirements**: >A CrowdStrike API access (API id & key) ----- -#### [cuckoo_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cuckoo_submit.py) +#### [Cuckoo Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cuckoo_submit.py) -An expansion module to submit files and URLs to Cuckoo Sandbox. +Submit files and URLs to Cuckoo Sandbox +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cuckoo_submit.py)] + - **features**: >The module takes a malware-sample, attachment, url or domain and submits it to Cuckoo Sandbox. > The returned task id can be used to retrieve results when the analysis completed. + +- **config**: +> - api_url +> - api_key + - **input**: >A malware-sample or attachment for files. A url or domain for URLs. + - **output**: >A text field containing 'Cuckoo task id: ' + - **references**: > - https://cuckoosandbox.org/ > - https://cuckoo.sh/docs/ + - **requirements**: >Access to a Cuckoo Sandbox API and an API key if the API requires it. (api_url and api_key) ----- -#### [cve](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve.py) +#### [CVE Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve.py) An expansion hover module to expand information about CVE id. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve.py)] + - **features**: >The module takes a vulnerability attribute as input and queries the CIRCL CVE search API to get information about the vulnerability as it is described in the list of CVEs. + +- **config**: +>custom_API + - **input**: >Vulnerability attribute. + - **output**: >Text giving information about the CVE related to the Vulnerability. + - **references**: -> - https://cve.circl.lu/ +> - https://vulnerability.circl.lu/ > - https://cve.mitre.org/ ----- -#### [cve_advanced](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve_advanced.py) +#### [CVE Advanced Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve_advanced.py) An expansion module to query the CIRCL CVE search API for more information about a vulnerability (CVE). +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve_advanced.py)] + - **features**: >The module takes a vulnerability attribute as input and queries the CIRCL CVE search API to gather additional information. > >The result of the query is then parsed to return additional information about the vulnerability, like its cvss score or some references, as well as the potential related weaknesses and attack patterns. > >The vulnerability additional data is returned in a vulnerability MISP object, and the related additional information are put into weakness and attack-pattern MISP objects. + +- **config**: +>custom_API + - **input**: >Vulnerability attribute. + - **output**: >Additional information about the vulnerability, such as its cvss score, some references, or the related weaknesses and attack patterns. + - **references**: -> - https://cve.circl.lu +> - https://vulnerability.circl.lu > - https://cve/mitre.org/ ----- -#### [cytomic_orion](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cytomic_orion.py) +#### [Cytomic Orion Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cytomic_orion.py) An expansion module to enrich attributes in MISP by quering the Cytomic Orion API +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cytomic_orion.py)] + - **features**: >This module takes an MD5 hash and searches for occurrences of this hash in the Cytomic Orion database. Returns observed files and machines. + +- **config**: +> - api_url +> - token_url +> - clientid +> - clientsecret +> - clientsecret +> - username +> - password +> - upload_timeframe +> - upload_tag +> - delete_tag +> - upload_ttlDays +> - upload_threat_level_id +> - limit_upload_events +> - limit_upload_attributes + - **input**: >MD5, hash of the sample / malware to search for. + - **output**: >MISP objects with sightings of the hash in Cytomic Orion. Includes files and machines. + - **references**: > - https://www.vanimpe.eu/2020/03/10/integrating-misp-and-cytomic-orion/ > - https://www.cytomicmodel.com/solutions/ + - **requirements**: >Access (license) to Cytomic Orion ----- -#### [dbl_spamhaus](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dbl_spamhaus.py) +#### [DBL Spamhaus Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dbl_spamhaus.py) -Module to check Spamhaus DBL for a domain name. +Checks Spamhaus DBL for a domain name. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dbl_spamhaus.py)] + - **features**: >This modules takes a domain or a hostname in input and queries the Domain Block List provided by Spamhaus to determine what kind of domain it is. > >DBL then returns a response code corresponding to a certain classification of the domain we display. If the queried domain is not in the list, it is also mentionned. > >Please note that composite MISP attributes containing domain or hostname are supported as well. + - **input**: >Domain or hostname attribute. + - **output**: >Information about the nature of the input. + - **references**: >https://www.spamhaus.org/faq/section/Spamhaus%20DBL + - **requirements**: >dnspython3: DNS python3 library ----- -#### [dns](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dns.py) +#### [DNS Resolver](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dns.py) + +jj +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dns.py)] -A simple DNS expansion service to resolve IP address from domain MISP attributes. - **features**: >The module takes a domain of hostname attribute as input, and tries to resolve it. If no error is encountered, the IP address that resolves the domain is returned, otherwise the origin of the error is displayed. > >The address of the DNS resolver to use is also configurable, but if no configuration is set, we use the Google public DNS address (8.8.8.8). > >Please note that composite MISP attributes containing domain or hostname are supported as well. + +- **config**: +>nameserver + - **input**: >Domain or hostname attribute. + - **output**: >IP address resolving the input. + - **requirements**: >dnspython3: DNS python3 library ----- -#### [docx_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/docx_enrich.py) +#### [DOCX Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/docx_enrich.py) Module to extract freetext from a .docx document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/docx_enrich.py)] + - **features**: >The module reads the text contained in a .docx document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a .docx document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: >docx python library ----- -#### [domaintools](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/domaintools.py) +#### [DomainTools Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/domaintools.py) DomainTools MISP expansion module. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/domaintools.py)] + - **features**: >This module takes a MISP attribute as input to query the Domaintools API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes. > >Please note that composite attributes composed by at least one of the input types mentionned below (domains, IPs, hostnames) are also supported. + +- **config**: +> - username +> - api_key + - **input**: >A MISP attribute included in the following list: >- domain @@ -500,6 +734,7 @@ DomainTools MISP expansion module. >- whois-registrant-phone >- ip-src >- ip-dst + - **output**: >MISP attributes mapped after the Domaintools API has been queried, included in the following list: >- whois-registrant-email @@ -509,56 +744,85 @@ DomainTools MISP expansion module. >- whois-creation-date >- text >- domain + - **references**: >https://www.domaintools.com/ + - **requirements**: > - Domaintools python library > - A Domaintools API access (username & apikey) ----- -#### [eql](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eql.py) +#### [EQL Query Generator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eql.py) EQL query generation for a MISP attribute. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eql.py)] + - **features**: >This module adds a new attribute to a MISP event containing an EQL query for a network or file attribute. + - **input**: >A filename or ip attribute. + - **output**: >Attribute containing EQL for a network or file attribute. + - **references**: >https://eql.readthedocs.io/en/latest/ ----- -#### [eupi](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eupi.py) +#### [EUPI Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eupi.py) A module to query the Phishing Initiative service (https://phishing-initiative.lu). +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eupi.py)] + - **features**: >This module takes a domain, hostname or url MISP attribute as input to query the Phishing Initiative API. The API returns then the result of the query with some information about the value queried. > >Please note that composite attributes containing domain or hostname are also supported. + +- **config**: +> - apikey +> - url + - **input**: >A domain, hostname or url MISP attribute. + - **output**: >Text containing information about the input, resulting from the query on Phishing Initiative. + - **references**: >https://phishing-initiative.eu/?lang=en + - **requirements**: > - pyeupi: eupi python library > - An access to the Phishing Initiative API (apikey & url) ----- -#### [farsight_passivedns](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/farsight_passivedns.py) +#### [URL Components Extractor](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/extract_url_components.py) + +Extract URL components +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/extract_url_components.py)] + +- **features**: +> + +----- + +#### [Farsight DNSDB Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/farsight_passivedns.py) Module to access Farsight DNSDB Passive DNS. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/farsight_passivedns.py)] + - **features**: >This module takes a domain, hostname or IP address MISP attribute as input to query the Farsight Passive DNS API. > The results of rdata and rrset lookups are then returned and parsed into passive-dns objects. @@ -566,204 +830,353 @@ Module to access Farsight DNSDB Passive DNS. >An API key is required to submit queries to the API. > It is also possible to define a custom server URL, and to set a limit of results to get. > This limit is set for each lookup, which means we can have an up to the limit number of passive-dns objects resulting from an rdata query about an IP address, but an up to the limit number of passive-dns objects for each lookup queries about a domain or a hostname (== twice the limit). + +- **config**: +> - apikey +> - server +> - limit +> - flex_queries + - **input**: >A domain, hostname or IP address MISP attribute. + - **output**: >Passive-dns objects, resulting from the query on the Farsight Passive DNS API. + - **references**: > - https://www.farsightsecurity.com/ > - https://docs.dnsdb.info/dnsdb-api/ + - **requirements**: >An access to the Farsight Passive DNS API (apikey) ----- -#### [geoip_asn](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_asn.py) +#### [GeoIP ASN Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_asn.py) -- **descrption**: ->An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about its related AS number. + +Query a local copy of the Maxmind Geolite ASN database (MMDB format) +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_asn.py)] + - **features**: >The module takes an IP address attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the related AS number. + +- **config**: +>local_geolite_db + +- **descrption**: +>An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about its related AS number. + - **input**: >An IP address MISP attribute. + - **output**: >Text containing information about the AS number of the IP address. + - **references**: >https://www.maxmind.com/en/home + - **requirements**: >A local copy of Maxmind's Geolite database ----- -#### [geoip_city](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_city.py) +#### [GeoIP City Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_city.py) An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about the city where it is located. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_city.py)] + - **features**: >The module takes an IP address attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the city where this IP address is located. + +- **config**: +>local_geolite_db + - **input**: >An IP address MISP attribute. + - **output**: >Text containing information about the city where the IP address is located. + - **references**: >https://www.maxmind.com/en/home + - **requirements**: >A local copy of Maxmind's Geolite database ----- -#### [geoip_country](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_country.py) +#### [GeoIP Country Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_country.py) -Module to query a local copy of Maxmind's Geolite database. +Query a local copy of Maxminds Geolite database, updated for MMDB format +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_country.py)] + - **features**: >This module takes an IP address MISP attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the location of this IP address. > >Please note that composite attributes domain|ip are also supported. + +- **config**: +>local_geolite_db + - **input**: >An IP address MISP Attribute. + - **output**: >Text containing information about the location of the IP address. + - **references**: >https://www.maxmind.com/en/home + - **requirements**: >A local copy of Maxmind's Geolite database ----- -#### [google_search](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_search.py) +#### [Google Safe Browsing Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_safe_browsing.py) + +Google safe browsing expansion module +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_safe_browsing.py)] + +- **features**: +> + +- **config**: +>api_key + +----- + +#### [Google Search](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_search.py) -- **descrption**: ->A hover module to get information about an url using a Google search. + +An expansion hover module to expand google search information about an URL +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_search.py)] + - **features**: >The module takes an url as input to query the Google search API. The result of the query is then return as raw text. + - **input**: >An url attribute. + - **output**: >Text containing the result of a Google search on the input url. + - **references**: >https://github.com/abenassi/Google-Search-API + - **requirements**: >The python Google Search API library ----- -#### [greynoise](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/greynoise.py) +#### [Google Threat Intelligence Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_threat_intelligence.py) + + + +An expansion module to have the observable's threat score assessed by Google Threat Intelligence. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/google_threat_intelligence.py)] + +- **features**: +>GTI assessment for the given observable, this include information about level of severity, a clear verdict (malicious, suspicious, undetected and benign) and additional information provided by the Mandiant expertise combined with the VirusTotal database. +> +>[Output example screeshot](https://github.com/MISP/MISP/assets/4747608/e275db2f-bb1e-4413-8cc0-ec3cb05e0414) + +- **config**: +> - apikey +> - event_limit +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + +- **input**: +>A domain, hash (md5, sha1, sha256 or sha512), hostname or IP address attribute. + +- **output**: +>Text fields containing the threat score, the severity, the verdict and the threat label of the observable inspected. + +- **references**: +> - https://www.virustotal.com/ +> - https://gtidocs.virustotal.com/reference + +- **requirements**: +>An access to the Google Threat Intelligence API (apikey), with a high request rate limit. + +----- + +#### [GreyNoise Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/greynoise.py) Module to query IP and CVE information from GreyNoise +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/greynoise.py)] + - **features**: >This module supports: 1) Query an IP from GreyNoise to see if it is internet background noise or a common business service 2) Query a CVE from GreyNoise to see the total number of internet scanners looking for the CVE in the last 7 days. + +- **config**: +> - api_key +> - api_type + - **input**: >An IP address or CVE ID + - **output**: >IP Lookup information or CVE scanning profile for past 7 days + - **references**: > - https://greynoise.io/ > - https://docs.greyniose.io/ > - https://www.greynoise.io/viz/account/ + - **requirements**: >A Greynoise API key. Both Enterprise (Paid) and Community (Free) API keys are supported, however Community API users will only be able to perform IP lookups. ----- -#### [hashdd](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashdd.py) +#### [Hashdd Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashdd.py) A hover module to check hashes against hashdd.com including NSLR dataset. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashdd.py)] + - **features**: >This module takes a hash attribute as input to check its known level, using the hashdd API. This information is then displayed. + - **input**: >A hash MISP attribute (md5). + - **output**: >Text describing the known level of the hash in the hashdd databases. + - **references**: >https://hashdd.com/ ----- -#### [hashlookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashlookup.py) +#### [CIRCL Hashlookup Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashlookup.py) An expansion module to query the CIRCL hashlookup services to find it if a hash is part of a known set such as NSRL. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashlookup.py)] + - **features**: >The module takes file hashes as input such as a MD5 or SHA1. > It queries the public CIRCL.lu hashlookup service and return all the hits if the hashes are known in an existing dataset. The module can be configured with a custom hashlookup url if required. > The module can be used an hover module but also an expansion model to add related MISP objects. > + +- **config**: +>custom_API + - **input**: >File hashes (MD5, SHA1) + - **output**: >Object with the filename associated hashes if the hash is part of a known set. + - **references**: >https://www.circl.lu/services/hashlookup/ ----- -#### [hibp](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hibp.py) +#### [Have I Been Pwned Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hibp.py) Module to access haveibeenpwned.com API. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hibp.py)] + - **features**: >The module takes an email address as input and queries haveibeenpwned.com API to find additional information about it. This additional information actually tells if any account using the email address has already been compromised in a data breach. + +- **config**: +>api_key + - **input**: >An email address + - **output**: >Additional information about the email address. + - **references**: >https://haveibeenpwned.com/ ----- -#### [html_to_markdown](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/html_to_markdown.py) +#### [HTML to Markdown](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/html_to_markdown.py) Expansion module to fetch the html content from an url and convert it into markdown. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/html_to_markdown.py)] + - **features**: >The module take an URL as input and the HTML content is fetched from it. This content is then converted into markdown that is returned as text. + - **input**: >URL attribute. + - **output**: >Markdown content converted from the HTML fetched from the url. + - **requirements**: >The markdownify python library ----- -#### [hyasinsight](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hyasinsight.py) +#### [HYAS Insight Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hyasinsight.py) HYAS Insight integration to MISP provides direct, high volume access to HYAS Insight data. It enables investigators and analysts to understand and defend against cyber adversaries and their infrastructure. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hyasinsight.py)] + - **features**: >This Module takes the IP Address, Domain, URL, Email, Phone Number, MD5, SHA1, Sha256, SHA512 MISP Attributes as input to query the HYAS Insight API. > The results of the HYAS Insight API are than are then returned and parsed into Hyas Insight Objects. > >An API key is required to submit queries to the HYAS Insight API. > + +- **config**: +>apikey + - **input**: >A MISP attribute of type IP Address(ip-src, ip-dst), Domain(hostname, domain), Email Address(email, email-src, email-dst, target-email, whois-registrant-email), Phone Number(phone-number, whois-registrant-phone), MDS(md5, x509-fingerprint-md5, ja3-fingerprint-md5, hassh-md5, hasshserver-md5), SHA1(sha1, x509-fingerprint-sha1), SHA256(sha256, x509-fingerprint-sha256), SHA512(sha512) + - **output**: >Hyas Insight objects, resulting from the query on the HYAS Insight API. + - **references**: >https://www.hyas.com/hyas-insight/ + - **requirements**: >A HYAS Insight API Key. ----- -#### [intel471](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intel471.py) +#### [Intel471 Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intel471.py) -- **descrption**: ->An expansion module to query Intel471 in order to get additional information about a domain, ip address, email address, url or hash. + +Module to access Intel 471 +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intel471.py)] + - **features**: >The module uses the Intel471 python library to query the Intel471 API with the value of the input attribute. The result of the query is then returned as freetext so the Freetext import parses it. + +- **config**: +> - email +> - authkey + +- **descrption**: +>An expansion module to query Intel471 in order to get additional information about a domain, ip address, email address, url or hash. + - **input**: >A MISP attribute whose type is included in the following list: >- hostname @@ -779,80 +1192,78 @@ HYAS Insight integration to MISP provides direct, high volume access to HYAS Ins >- md5 >- sha1 >- sha256 + - **output**: >Freetext + - **references**: >https://public.intel471.com/ + - **requirements**: >The intel471 python library ----- -#### [intelmq_eventdb](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intelmq_eventdb.py) - - - -Module to access intelmqs eventdb. -- **features**: ->/!\ EXPERIMENTAL MODULE, some features may not work /!\ -> ->This module takes a domain, hostname, IP address or Autonomous system MISP attribute as input to query the IntelMQ database. The result of the query gives then additional information about the input. -- **input**: ->A hostname, domain, IP address or AS attribute. -- **output**: ->Text giving information about the input using IntelMQ database. -- **references**: -> - https://github.com/certtools/intelmq -> - https://intelmq.readthedocs.io/en/latest/Developers-Guide/ -- **requirements**: -> - psycopg2: Python library to support PostgreSQL -> - An access to the IntelMQ database (username, password, hostname and database reference) - ------ - -#### [ip2locationio](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ip2locationio.py) +#### [IP2Location.io Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ip2locationio.py) An expansion module to query IP2Location.io to gather more information on a given IP address. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ip2locationio.py)] + - **features**: >The module takes an IP address attribute as input and queries the IP2Location.io API. >Free plan user will get the basic geolocation informaiton, and different subsription plan will get more information on the IP address. > Refer to [pricing page](https://www.ip2location.io/pricing) for more information on data available for each plan. > >More information on the responses content is available in the [documentation](https://www.ip2location.io/ip2location-documentation). + +- **config**: +>key + - **input**: >IP address attribute. + - **output**: >Additional information on the IP address, such as geolocation, proxy and so on. Refer to the Response Format section in https://www.ip2location.io/ip2location-documentation to find out the full format of the data returned. + - **references**: >https://www.ip2location.io/ip2location-documentation + - **requirements**: >An IP2Location.io token ----- -#### [ipasn](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipasn.py) +#### [IPASN-History Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipasn.py) Module to query an IP ASN history service (https://github.com/D4-project/IPASN-History). +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipasn.py)] + - **features**: >This module takes an IP address attribute as input and queries the CIRCL IPASN service. The result of the query is the latest asn related to the IP address, that is returned as a MISP object. + - **input**: >An IP address MISP attribute. + - **output**: >Asn object(s) objects related to the IP address used as input. + - **references**: >https://github.com/D4-project/IPASN-History + - **requirements**: >pyipasnhistory: Python library to access IPASN-history instance ----- -#### [ipinfo](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipinfo.py) +#### [IPInfo.io Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipinfo.py) An expansion module to query ipinfo.io to gather more information on a given IP address. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipinfo.py)] + - **features**: >The module takes an IP address attribute as input and queries the ipinfo.io API. >The geolocation information on the IP address is always returned. @@ -862,60 +1273,95 @@ An expansion module to query ipinfo.io to gather more information on a given IP >- With a paid subscription, the AS information is returned in the `asn` field with additional AS information, and depending on which plan the user has, you can also get information on the privacy method used to protect the IP address, the related domains, or the point of contact related to the IP address in case of an abuse. > >More information on the responses content is available in the [documentation](https://ipinfo.io/developers). + +- **config**: +>token + - **input**: >IP address attribute. + - **output**: >Additional information on the IP address, like its geolocation, the autonomous system it is included in, and the related domain(s). + - **references**: >https://ipinfo.io/developers + - **requirements**: >An ipinfo.io token ----- -#### [ipqs_fraud_and_risk_scoring](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py) +#### [IPQualityScore Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py) IPQualityScore MISP Expansion Module for IP reputation, Email Validation, Phone Number Validation, Malicious Domain and Malicious URL Scanner. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py)] + - **features**: >This Module takes the IP Address, Domain, URL, Email and Phone Number MISP Attributes as input to query the IPQualityScore API. > The results of the IPQualityScore API are than returned as IPQS Fraud and Risk Scoring Object. > The object contains a copy of the enriched attribute with added tags presenting the verdict based on fraud score,risk score and other attributes from IPQualityScore. + +- **config**: +>apikey + - **input**: >A MISP attribute of type IP Address(ip-src, ip-dst), Domain(hostname, domain), URL(url, uri), Email Address(email, email-src, email-dst, target-email, whois-registrant-email) and Phone Number(phone-number, whois-registrant-phone). + - **output**: >IPQualityScore object, resulting from the query on the IPQualityScore API. + - **references**: >https://www.ipqualityscore.com/ + - **requirements**: >A IPQualityScore API Key. ----- -#### [iprep](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/iprep.py) +#### [IPRep Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/iprep.py) Module to query IPRep data for IP addresses. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/iprep.py)] + - **features**: >This module takes an IP address attribute as input and queries the database from packetmail.net to get some information about the reputation of the IP. + +- **config**: +>apikey + - **input**: >An IP address MISP attribute. + - **output**: >Text describing additional information about the input after a query on the IPRep API. + - **references**: >https://github.com/mahesh557/packetmail + - **requirements**: >An access to the packetmail API (apikey) ----- -#### [joesandbox_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) +#### [Ninja Template Rendering](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/jinja_template_rendering.py) + +Render the template with the data passed +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/jinja_template_rendering.py)] + +- **features**: +> + +----- + +#### [Joe Sandbox Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) Query Joe Sandbox API with a submission url to get the json report and extract its data that is parsed and converted into MISP attributes and objects. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py)] -This url can by the way come from the result of the [joesandbox_submit expansion module](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py). - **features**: >Module using the new format of modules able to return attributes and objects. > @@ -924,84 +1370,128 @@ This url can by the way come from the result of the [joesandbox_submit expansion >Even if the introspection will allow all kinds of links to call this module, obviously only the ones presenting a sample or url submission in the Joe Sandbox API will return results. > >To make it work you will need to fill the 'apikey' configuration with your Joe Sandbox API key and provide a valid link as input. + +- **config**: +> - apiurl +> - apikey +> - import_executable +> - import_mitre_attack + - **input**: >Link of a Joe Sandbox sample or url submission. + - **output**: >MISP attributes & objects parsed from the analysis report. + - **references**: > - https://www.joesecurity.org > - https://www.joesandbox.com/ + - **requirements**: >jbxapi: Joe Sandbox API python3 library ----- -#### [joesandbox_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py) +#### [Joe Sandbox Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py) A module to submit files or URLs to Joe Sandbox for an advanced analysis, and return the link of the submission. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py)] + - **features**: >The module requires a Joe Sandbox API key to submit files or URL, and returns the link of the submitted analysis. > >It is then possible, when the analysis is completed, to query the Joe Sandbox API to get the data related to the analysis, using the [joesandbox_query module](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) directly on this submission link. + +- **config**: +> - apiurl +> - apikey +> - accept-tac +> - report-cache +> - systems + - **input**: >Sample, url (or domain) to submit to Joe Sandbox for an advanced analysis. + - **output**: >Link of the report generated in Joe Sandbox. + - **references**: > - https://www.joesecurity.org > - https://www.joesandbox.com/ + - **requirements**: >jbxapi: Joe Sandbox API python3 library ----- -#### [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) +#### [Lastline Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Query Lastline with an analysis link and parse the report into MISP attributes and objects. -The analysis link can also be retrieved from the output of the [lastline_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_submit.py) expansion module. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py)] + - **features**: >The module requires a Lastline Portal `username` and `password`. >The module uses the new format and it is able to return MISP attributes and objects. >The module returns the same results as the [lastline_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/lastline_import.py) import module. + +- **config**: +> - username +> - password +> - verify_ssl + - **input**: >Link to a Lastline analysis. + - **output**: >MISP attributes and objects parsed from the analysis report. + - **references**: >https://www.lastline.com ----- -#### [lastline_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_submit.py) +#### [Lastline Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_submit.py) Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Module to submit a file or URL to Lastline. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_submit.py)] + - **features**: >The module requires a Lastline Analysis `api_token` and `key`. >When the analysis is completed, it is possible to import the generated report by feeding the analysis link to the [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) module. + +- **config**: +> - url +> - api_token +> - key + - **input**: >File or URL to submit to Lastline. + - **output**: >Link to the report generated by Lastline. + - **references**: >https://www.lastline.com ----- -#### [macaddress_io](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macaddress_io.py) +#### [Macaddress.io Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macaddress_io.py) MISP hover module for macaddress.io +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macaddress_io.py)] + - **features**: >This module takes a MAC address attribute as input and queries macaddress.io for additional information. > @@ -1009,181 +1499,290 @@ MISP hover module for macaddress.io >- MAC address details >- Vendor details >- Block details + +- **config**: +>api_key + - **input**: >MAC address MISP attribute. + - **output**: >Text containing information on the MAC address fetched from a query on macaddress.io. + - **references**: > - https://macaddress.io/ > - https://github.com/CodeLineFi/maclookup-python + - **requirements**: > - maclookup: macaddress.io python library > - An access to the macaddress.io API (apikey) ----- -#### [macvendors](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macvendors.py) +#### [Macvendors Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macvendors.py) Module to access Macvendors API. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macvendors.py)] + - **features**: >The module takes a MAC address as input and queries macvendors.com for some information about it. The API returns the name of the vendor related to the address. + +- **config**: +>user-agent + - **input**: >A MAC address. + - **output**: >Additional information about the MAC address. + - **references**: > - https://macvendors.com/ > - https://macvendors.com/api ----- -#### [malwarebazaar](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malwarebazaar.py) +#### [MalShare Upload](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malshare_upload.py) + +Module to push malware samples to MalShare +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malshare_upload.py)] + +- **config**: +>malshare_apikey + +- **requirements**: +>requests library + +----- + +#### [Malware Bazaar Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malwarebazaar.py) + +Query Malware Bazaar to get additional information about the input hash. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/malwarebazaar.py)] -Query the MALWAREbazaar API to get additional information about the input hash attribute. - **features**: >The module takes a hash attribute as input and queries MALWAREbazaar's API to fetch additional data about it. The result, if the payload is known on the databases, is at least one file object describing the file the input hash is related to. > >The module is using the new format of modules able to return object since the result is one or multiple MISP object(s). + - **input**: >A hash attribute (md5, sha1 or sha256). + - **output**: >File object(s) related to the input attribute found on MALWAREbazaar databases. + - **references**: >https://bazaar.abuse.ch/ ----- -#### [mmdb_lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mmdb_lookup.py) +#### [McAfee MVISION Insights Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mcafee_insights_enrich.py) + +Lookup McAfee MVISION Insights Details +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mcafee_insights_enrich.py)] + +- **features**: +> + +- **config**: +> - api_key +> - client_id +> - client_secret + +----- + +#### [GeoIP Enrichment](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mmdb_lookup.py) A hover and expansion module to enrich an ip with geolocation and ASN information from an mmdb server instance, such as CIRCL's ip.circl.lu. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mmdb_lookup.py)] + - **features**: >The module takes an IP address related attribute as input. > It queries the public CIRCL.lu mmdb-server instance, available at ip.circl.lu, by default. The module can be configured with a custom mmdb server url if required. > It is also possible to filter results on 1 db_source by configuring db_source_filter. + +- **config**: +> - custom_API +> - db_source_filter + - **input**: >An IP address attribute (for example ip-src or ip-src|port). + - **output**: >Geolocation and asn objects. + - **references**: > - https://data.public.lu/fr/datasets/geo-open-ip-address-geolocation-per-country-in-mmdb-format/ > - https://github.com/adulau/mmdb-server ----- -#### [mwdb](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mwdb.py) +#### [MWDB Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mwdb.py) Module to push malware samples to a MWDB instance +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/mwdb.py)] + - **features**: >An expansion module to push malware samples to a MWDB (https://github.com/CERT-Polska/mwdb-core) instance. This module does not push samples to a sandbox. This can be achieved via Karton (connected to the MWDB). Does: * Upload of attachment or malware sample to MWDB * Tags of events and/or attributes are added to MWDB. * Comment of the MISP attribute is added to MWDB. * A link back to the MISP event is added to MWDB via the MWDB attribute. * A link to the MWDB attribute is added as an enrichted attribute to the MISP event. + +- **config**: +> - mwdb_apikey +> - mwdb_url +> - mwdb_misp_attribute +> - mwdb_public +> - include_tags_event +> - include_tags_attribute + - **input**: >Attachment or malware sample + - **output**: >Link attribute that points to the sample at the MWDB instane + - **requirements**: >* mwdblib installed (pip install mwdblib) ; * (optional) keys.py file to add tags of events/attributes to MWDB * (optional) MWDB attribute created for the link back to MISP (defined in mwdb_misp_attribute) ----- -#### [ocr_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ocr_enrich.py) +#### [OCR Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ocr_enrich.py) Module to process some optical character recognition on pictures. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ocr_enrich.py)] + - **features**: >The module takes an attachment attributes as input and process some optical character recognition on it. The text found is then passed to the Freetext importer to extract potential IoCs. + - **input**: >A picture attachment. + - **output**: >Text and freetext fetched from the input picture. + - **requirements**: >cv2: The OpenCV python library. ----- -#### [ods_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ods_enrich.py) +#### [ODS Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ods_enrich.py) Module to extract freetext from a .ods document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ods_enrich.py)] + - **features**: >The module reads the text contained in a .ods document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a .ods document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: > - ezodf: Python package to create/manipulate OpenDocumentFormat files. > - pandas_ods_reader: Python library to read in ODS files. ----- -#### [odt_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/odt_enrich.py) +#### [ODT Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/odt_enrich.py) Module to extract freetext from a .odt document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/odt_enrich.py)] + - **features**: >The module reads the text contained in a .odt document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a .odt document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: >ODT reader python library. ----- -#### [onyphe](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe.py) +#### [Onyphe Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe.py) Module to process a query on Onyphe. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe.py)] + - **features**: >This module takes a domain, hostname, or IP address attribute as input in order to query the Onyphe API. Data fetched from the query is then parsed and MISP attributes are extracted. + +- **config**: +>apikey + - **input**: >A domain, hostname or IP address MISP attribute. + - **output**: >MISP attributes fetched from the Onyphe query. + - **references**: > - https://www.onyphe.io/ > - https://github.com/sebdraven/pyonyphe + - **requirements**: > - onyphe python library > - An access to the Onyphe API (apikey) ----- -#### [onyphe_full](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe_full.py) +#### [Onyphe Full Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe_full.py) Module to process a full query on Onyphe. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe_full.py)] + - **features**: >This module takes a domain, hostname, or IP address attribute as input in order to query the Onyphe API. Data fetched from the query is then parsed and MISP attributes are extracted. > >The parsing is here more advanced than the one on onyphe module, and is returning more attributes, since more fields of the query result are watched and parsed. + +- **config**: +>apikey + - **input**: >A domain, hostname or IP address MISP attribute. + - **output**: >MISP attributes fetched from the Onyphe query. + - **references**: > - https://www.onyphe.io/ > - https://github.com/sebdraven/pyonyphe + - **requirements**: > - onyphe python library > - An access to the Onyphe API (apikey) ----- -#### [otx](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/otx.py) +#### [AlienVault OTX Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/otx.py) Module to get information from AlienVault OTX. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/otx.py)] + - **features**: >This module takes a MISP attribute as input to query the OTX Alienvault API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes. + +- **config**: +>apikey + - **input**: >A MISP attribute included in the following list: >- hostname @@ -1194,6 +1793,7 @@ Module to get information from AlienVault OTX. >- sha1 >- sha256 >- sha512 + - **output**: >MISP attributes mapped from the result of the query on OTX, included in the following list: >- domain @@ -1205,39 +1805,44 @@ Module to get information from AlienVault OTX. >- sha256 >- sha512 >- email + - **references**: >https://www.alienvault.com/open-threat-exchange + - **requirements**: >An access to the OTX API (apikey) ----- -#### [passivessh](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passivessh.py) +#### [Passive SSH Enrichment](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passive_ssh.py) - +An expansion module to enrich, SSH key fingerprints and IP addresses with information collected by passive-ssh +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passive_ssh.py)] -An expansion module to query the CIRCL Passive SSH. - **features**: ->The module queries the Passive SSH service from CIRCL. -> -> The module can be used an hover module but also an expansion model to add related MISP objects. > -- **input**: ->IP addresses or SSH fingerprints -- **output**: ->SSH key materials, complementary IP addresses with similar SSH key materials -- **references**: ->https://github.com/D4-project/passive-ssh + +- **config**: +> - custom_api_url +> - api_user +> - api_key ----- -#### [passivetotal](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passivetotal.py) +#### [PassiveTotal Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passivetotal.py) +The PassiveTotal MISP expansion module brings the datasets derived from Internet scanning directly into your MISP instance. This module supports passive DNS, historic SSL, WHOIS, and host attributes. In order to use the module, you must have a valid PassiveTotal account username and API key. Registration is free and can be done by visiting https://www.passivetotal.org/register +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passivetotal.py)] - **features**: >The PassiveTotal MISP expansion module brings the datasets derived from Internet scanning directly into your MISP instance. This module supports passive DNS, historic SSL, WHOIS, and host attributes. In order to use the module, you must have a valid PassiveTotal account username and API key. Registration is free and can be done by visiting https://www.passivetotal.org/register + +- **config**: +> - username +> - api_key + - **input**: >A MISP attribute included in the following list: >- hostname @@ -1254,6 +1859,7 @@ An expansion module to query the CIRCL Passive SSH. >- whois-registrant-name >- whois-registrar >- whois-creation-date + - **output**: >MISP attributes mapped from the result of the query on PassiveTotal, included in the following list: >- hostname @@ -1274,164 +1880,240 @@ An expansion module to query the CIRCL Passive SSH. >- sha1 >- sha256 >- link + - **references**: >https://www.passivetotal.org/register + - **requirements**: > - Passivetotal python library > - An access to the PassiveTotal API (apikey) ----- -#### [pdf_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pdf_enrich.py) +#### [PDF Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pdf_enrich.py) Module to extract freetext from a PDF document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pdf_enrich.py)] + - **features**: >The module reads the text contained in a PDF document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a PDF document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: >pdftotext: Python library to extract text from PDF. ----- -#### [pptx_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pptx_enrich.py) +#### [PPTX Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pptx_enrich.py) Module to extract freetext from a .pptx document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pptx_enrich.py)] + - **features**: >The module reads the text contained in a .pptx document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a .pptx document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: >pptx: Python library to read PowerPoint files. ----- -#### [qintel_qsentry](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qintel_qsentry.py) +#### [Qintel QSentry Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qintel_qsentry.py) A hover and expansion module which queries Qintel QSentry for ip reputation data +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qintel_qsentry.py)] + - **features**: >This module takes an ip-address (ip-src or ip-dst) attribute as input, and queries the Qintel QSentry API to retrieve ip reputation data + +- **config**: +> - token +> - remote + - **input**: >ip address attribute + - **ouput**: >Objects containing the enriched IP, threat tags, last seen attributes and associated Autonomous System information + - **references**: >https://www.qintel.com/products/qsentry/ + - **requirements**: >A Qintel API token ----- -#### [qrcode](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qrcode.py) +#### [QR Code Decode](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qrcode.py) Module to decode QR codes. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qrcode.py)] + - **features**: >The module reads the QR code and returns the related address, which can be an URL or a bitcoin address. + - **input**: >A QR code stored as attachment attribute. + - **output**: >The URL or bitcoin address the QR code is pointing to. + - **requirements**: > - cv2: The OpenCV python library. > - pyzbar: Python library to read QR codes. ----- -#### [ransomcoindb](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ransomcoindb.py) -- **descrption**: ->Module to access the ransomcoinDB with a hash or btc address attribute and get the associated btc address of hashes. +#### [RandomcoinDB Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ransomcoindb.py) + +Module to access the ransomcoinDB (see https://ransomcoindb.concinnity-risks.com) +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ransomcoindb.py)] + - **features**: >The module takes either a hash attribute or a btc attribute as input to query the ransomcoinDB API for some additional data. > >If the input is a btc address, we will get the associated hashes returned in a file MISP object. If we query ransomcoinDB with a hash, the response contains the associated btc addresses returned as single MISP btc attributes. + +- **config**: +>api-key + +- **descrption**: +>Module to access the ransomcoinDB with a hash or btc address attribute and get the associated btc address of hashes. + - **input**: >A hash (md5, sha1 or sha256) or btc attribute. + - **output**: >Hashes associated to a btc address or btc addresses associated to a hash. + - **references**: >https://ransomcoindb.concinnity-risks.com + - **requirements**: >A ransomcoinDB API key. ----- -#### [rbl](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/rbl.py) +#### [Real-time Blackhost Lists Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/rbl.py) Module to check an IPv4 address against known RBLs. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/rbl.py)] + - **features**: >This module takes an IP address attribute as input and queries multiple know Real-time Blackhost Lists to check if they have already seen this IP address. > >We display then all the information we get from those different sources. + +- **config**: +>timeout + - **input**: >IP address attribute. + - **output**: >Text with additional data from Real-time Blackhost Lists about the IP address. + - **references**: >[RBLs list](https://github.com/MISP/misp-modules/blob/8817de476572a10a9c9d03258ec81ca70f3d926d/misp_modules/modules/expansion/rbl.py#L20) + - **requirements**: >dnspython3: DNS python3 library ----- -#### [recordedfuture](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/recordedfuture.py) +#### [Recorded Future Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/recordedfuture.py) Module to enrich attributes with threat intelligence from Recorded Future. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/recordedfuture.py)] + - **features**: >Enrich an attribute to add a custom enrichment object to the event. The object contains a copy of the enriched attribute with added tags presenting risk score and triggered risk rules from Recorded Future. Malware and Threat Actors related to the enriched indicator in Recorded Future is matched against MISP's galaxy clusters and applied as galaxy tags. The custom enrichment object also includes a list of related indicators from Recorded Future (IP's, domains, hashes, URL's and vulnerabilities) added as additional attributes. + +- **config**: +> - token +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + - **input**: >A MISP attribute of one of the following types: ip, ip-src, ip-dst, domain, hostname, md5, sha1, sha256, uri, url, vulnerability, weakness. + - **output**: >A MISP object containing a copy of the enriched attribute with added tags from Recorded Future and a list of new attributes related to the enriched attribute. + - **references**: >https://www.recordedfuture.com/ + - **requirements**: >A Recorded Future API token. ----- -#### [reversedns](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/reversedns.py) +#### [Reverse DNS](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/reversedns.py) Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/reversedns.py)] + - **features**: >The module takes an IP address as input and tries to find the hostname this IP address is resolved into. > >The address of the DNS resolver to use is also configurable, but if no configuration is set, we use the Google public DNS address (8.8.8.8). > >Please note that composite MISP attributes containing IP addresses are supported as well. + +- **config**: +>nameserver + - **input**: >An IP address attribute. + - **output**: >Hostname attribute the input is resolved into. + - **requirements**: >DNS python library ----- -#### [securitytrails](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/securitytrails.py) +#### [SecurityTrails Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/securitytrails.py) An expansion modules for SecurityTrails. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/securitytrails.py)] + - **features**: >The module takes a domain, hostname or IP address attribute as input and queries the SecurityTrails API with it. > >Multiple parsing operations are then processed on the result of the query to extract a much information as possible. > >From this data extracted are then mapped MISP attributes. + +- **config**: +>apikey + - **input**: >A domain, hostname or IP address attribute. + - **output**: >MISP attributes resulting from the query on SecurityTrails API, included in the following list: >- hostname @@ -1445,169 +2127,246 @@ An expansion modules for SecurityTrails. >- whois-registrar >- whois-creation-date >- domain + - **references**: >https://securitytrails.com/ + - **requirements**: > - dnstrails python library > - An access to the SecurityTrails API (apikey) ----- -#### [shodan](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/shodan.py) +#### [Shodan Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/shodan.py) Module to query on Shodan. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/shodan.py)] + - **features**: >The module takes an IP address as input and queries the Shodan API to get some additional data about it. + +- **config**: +>apikey + - **input**: >An IP address MISP attribute. + - **output**: >Text with additional data about the input, resulting from the query on Shodan. + - **references**: >https://www.shodan.io/ + - **requirements**: > - shodan python library > - An access to the Shodan API (apikey) ----- -#### [sigma_queries](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_queries.py) +#### [Sigma Rule Converter](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_queries.py) An expansion hover module to display the result of sigma queries. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_queries.py)] + - **features**: >This module takes a Sigma rule attribute as input and tries all the different queries available to convert it into different formats recognized by SIEMs. + - **input**: >A Sigma attribute. + - **output**: >Text displaying results of queries on the Sigma attribute. + - **references**: >https://github.com/Neo23x0/sigma/wiki + - **requirements**: >Sigma python library ----- -#### [sigma_syntax_validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_syntax_validator.py) +#### [Sigma Syntax Validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_syntax_validator.py) An expansion hover module to perform a syntax check on sigma rules. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_syntax_validator.py)] + - **features**: >This module takes a Sigma rule attribute as input and performs a syntax check on it. > >It displays then that the rule is valid if it is the case, and the error related to the rule otherwise. + - **input**: >A Sigma attribute. + - **output**: >Text describing the validity of the Sigma rule. + - **references**: >https://github.com/Neo23x0/sigma/wiki + - **requirements**: > - Sigma python library > - Yaml python library ----- -#### [sigmf-expand](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigmf-expand.py) +#### [SigMF Expansion](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigmf_expand.py) + +Expands a SigMF Recording object into a SigMF Expanded Recording object, extracts a SigMF archive into a SigMF Recording object. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigmf_expand.py)] -Enrichs a SigMF Recording or extracts a SigMF Archive into a SigMF Recording. - **features**: ->This module can be used to expand a SigMF Recording object into a SigMF Expanded Recording object with a waterfall plot or to extract a SigMF Archive object into a SigMF Recording objet. -- **input**: ->Object of sigmf-archive or sigmf-recording template. -- **output**: ->Object of sigmf-expanded-recording or sigmf-recording template. -- **references**: ->https://github.com/sigmf/SigMF -- **requirements**: -> - matplotlib: For plotting the waterfall plot of the recording. -> - numpy: For the waterfall plot of the recording. -> - sigmf: For validating SigMF files. +> ----- -#### [socialscan](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/socialscan.py) +#### [Socialscan Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/socialscan.py) A hover module to get information on the availability of an email address or username on some online platforms. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/socialscan.py)] + - **features**: >The module takes an email address or username as input and check its availability on some online platforms. The results for each platform are then returned to see if the email address or the username is used, available or if there is an issue with it. + - **input**: >An email address or usename attribute. + - **output**: >Text containing information about the availability of an email address or a username in some online platforms. + - **references**: >https://github.com/iojw/socialscan + - **requirements**: >The socialscan python library ----- -#### [sophoslabs_intelix](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sophoslabs_intelix.py) +#### [SophosLabs Intelix Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sophoslabs_intelix.py) An expansion module to query the Sophoslabs intelix API to get additional information about an ip address, url, domain or sha256 attribute. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sophoslabs_intelix.py)] + - **features**: >The module takes an ip address, url, domain or sha256 attribute and queries the SophosLabs Intelix API with the attribute value. The result of this query is a SophosLabs Intelix hash report, or an ip or url lookup, that is then parsed and returned in a MISP object. + +- **config**: +> - client_id +> - client_secret + - **input**: >An ip address, url, domain or sha256 attribute. + - **output**: >SophosLabs Intelix report and lookup objects + - **references**: >https://aws.amazon.com/marketplace/pp/B07SLZPMCS + - **requirements**: >A client_id and client_secret pair to authenticate to the SophosLabs Intelix API ----- -#### [sourcecache](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sourcecache.py) +#### [URL Archiver](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sourcecache.py) Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sourcecache.py)] + - **features**: >This module takes a link or url attribute as input and caches the related web page. It returns then a link of the cached page. + +- **config**: +>archivepath + - **input**: >A link or url attribute. + - **output**: >A malware-sample attribute describing the cached page. + - **references**: >https://github.com/adulau/url_archiver + - **requirements**: >urlarchiver: python library to fetch and archive URL on the file-system ----- -#### [stix2_pattern_syntax_validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py) +#### [Stairwell Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stairwell.py) + + + +Module to query the Stairwell API to get additional information about the input hash attribute +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stairwell.py)] + +- **features**: +>The module takes a hash attribute as input and queries Stariwell's API to fetch additional data about it. The result, if the payload is observed in Stariwell, is a file object describing the file the input hash is related to. + +- **config**: +>apikey + +- **input**: +>A hash attribute (md5, sha1, sha256). + +- **output**: +>File object related to the input attribute found on Stairwell platform. + +- **references**: +> - https://stairwell.com +> - https://docs.stairwell.com + +- **requirements**: +>Access to Stairwell platform (apikey) + +----- + +#### [STIX2 Pattern Syntax Validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py) An expansion hover module to perform a syntax check on stix2 patterns. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py)] + - **features**: >This module takes a STIX2 pattern attribute as input and performs a syntax check on it. > >It displays then that the rule is valid if it is the case, and the error related to the rule otherwise. + - **input**: >A STIX2 pattern attribute. + - **output**: >Text describing the validity of the STIX2 pattern. + - **references**: >[STIX2.0 patterning specifications](http://docs.oasis-open.org/cti/stix/v2.0/cs01/part5-stix-patterning/stix-v2.0-cs01-part5-stix-patterning.html) + - **requirements**: >stix2patterns python library ----- -#### [threatcrowd](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatcrowd.py) +#### [ThreatCrowd Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatcrowd.py) Module to get information from ThreatCrowd. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatcrowd.py)] + - **features**: >This module takes a MISP attribute as input and queries ThreatCrowd with it. > >The result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute. + - **input**: >A MISP attribute included in the following list: >- hostname @@ -1619,6 +2378,7 @@ Module to get information from ThreatCrowd. >- sha256 >- sha512 >- whois-registrant-email + - **output**: >MISP attributes mapped from the result of the query on ThreatCrowd, included in the following list: >- domain @@ -1631,20 +2391,34 @@ Module to get information from ThreatCrowd. >- sha512 >- hostname >- whois-registrant-email + - **references**: >https://www.threatcrowd.org/ ----- -#### [threatminer](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatminer.py) +#### [ThreadFox Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatfox.py) + +Module to search for an IOC on ThreatFox by abuse.ch. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatfox.py)] + +- **features**: +> + +----- + +#### [ThreatMiner Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatminer.py) Module to get information from ThreatMiner. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatminer.py)] + - **features**: >This module takes a MISP attribute as input and queries ThreatMiner with it. > >The result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute. + - **input**: >A MISP attribute included in the following list: >- hostname @@ -1655,6 +2429,7 @@ Module to get information from ThreatMiner. >- sha1 >- sha256 >- sha512 + - **output**: >MISP attributes mapped from the result of the query on ThreatMiner, included in the following list: >- domain @@ -1671,20 +2446,40 @@ Module to get information from ThreatMiner. >- whois-registrant-email >- url >- link + - **references**: >https://www.threatminer.org/ ----- -#### [trustar_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/trustar_enrich.py) +#### [Triage Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/triage_submit.py) + +Module to submit samples to tria.ge +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/triage_submit.py)] + +- **config**: +> - apikey +> - url_mode + +----- + +#### [TruSTAR Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/trustar_enrich.py) Module to get enrich indicators with TruSTAR. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/trustar_enrich.py)] + - **features**: >This module enriches MISP attributes with scoring and metadata from TruSTAR. > >The TruSTAR indicator summary is appended to the attributes along with links to any associated reports. + +- **config**: +> - user_api_key +> - user_api_secret +> - enclave_ids + - **input**: >Any of the following MISP attributes: >- btc @@ -1698,78 +2493,105 @@ Module to get enrich indicators with TruSTAR. >- sha1 >- sha256 >- url + - **output**: >MISP attributes enriched with indicator summary data from the TruSTAR API. Data includes a severity level score and additional source and scoring info. + - **references**: >https://docs.trustar.co/api/v13/indicators/get_indicator_summaries.html ----- -#### [urlhaus](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlhaus.py) +#### [URLhaus Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlhaus.py) Query of the URLhaus API to get additional information about the input attribute. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlhaus.py)] + - **features**: >Module using the new format of modules able to return attributes and objects. > >The module takes one of the attribute type specified as input, and query the URLhaus API with it. If any result is returned by the API, attributes and objects are created accordingly. + - **input**: >A domain, hostname, url, ip, md5 or sha256 attribute. + - **output**: >MISP attributes & objects fetched from the result of the URLhaus API query. + - **references**: >https://urlhaus.abuse.ch/ ----- -#### [urlscan](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlscan.py) +#### [URLScan Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlscan.py) An expansion module to query urlscan.io. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlscan.py)] + - **features**: >This module takes a MISP attribute as input and queries urlscan.io with it. > >The result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute. + +- **config**: +>apikey + - **input**: >A domain, hostname or url attribute. + - **output**: >MISP attributes mapped from the result of the query on urlscan.io. + - **references**: >https://urlscan.io/ + - **requirements**: >An access to the urlscan.io API ----- -#### [variotdbs](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/variotdbs.py) +#### [VARIoT db Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/variotdbs.py) An expansion module to query the VARIoT db API for more information about a vulnerability. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/variotdbs.py)] + - **features**: >The module takes a vulnerability attribute as input and queries que VARIoT db API to gather additional information. > >The `vuln` endpoint is queried first to look for additional information about the vulnerability itself. > >The `exploits` endpoint is also queried then to look for the information of the potential related exploits, which are parsed and added to the results using the `exploit` object template. + +- **config**: +>API_key + - **input**: >Vulnerability attribute. + - **output**: >Additional information about the vulnerability, as it is stored on the VARIoT db, about the vulnerability itself, and the potential related exploits. + - **references**: >https://www.variotdbs.pl/ + - **requirements**: >A VARIoT db API key (if you do not want to be limited to 100 queries / day) ----- -#### [virustotal](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal.py) +#### [VirusTotal v3 Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal.py) -Module to get advanced information from virustotal. +Enrich observables with the VirusTotal v3 API +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal.py)] + - **features**: >New format of modules able to return attributes and objects. > @@ -1778,23 +2600,37 @@ Module to get advanced information from virustotal. >Compared to the [standard VirusTotal expansion module](https://github.com/MISP/misp-modules/blob/main/misp_modules/modules/expansion/virustotal_public.py), this module is made for advanced parsing of VirusTotal report, with a recursive analysis of the elements found after the first request. > >Thus, it requires a higher request rate limit to avoid the API to return a 204 error (Request rate limit exceeded), and the data parsed from the different requests are returned as MISP attributes and objects, with the corresponding relations between each one of them. + +- **config**: +> - apikey +> - event_limit +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + - **input**: >A domain, hash (md5, sha1, sha256 or sha512), hostname or IP address attribute. + - **output**: >MISP attributes and objects resulting from the parsing of the VirusTotal report concerning the input attribute. + - **references**: > - https://www.virustotal.com/ -> - https://developers.virustotal.com/reference +> - https://docs.virustotal.com/reference/overview + - **requirements**: >An access to the VirusTotal API (apikey), with a high request rate limit. ----- -#### [virustotal_public](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_public.py) +#### [VirusTotal Public API Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_public.py) -Module to get information from VirusTotal. +Enrich observables with the VirusTotal v3 public API +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_public.py)] + - **features**: >New format of modules able to return attributes and objects. > @@ -1803,29 +2639,66 @@ Module to get information from VirusTotal. >Compared to the [more advanced VirusTotal expansion module](https://github.com/MISP/misp-modules/blob/main/misp_modules/modules/expansion/virustotal.py), this module is made for VirusTotal users who have a low request rate limit. > >Thus, it only queries the API once and returns the results that is parsed into MISP attributes and objects. + +- **config**: +> - apikey +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + - **input**: >A domain, hostname, ip, url or hash (md5, sha1, sha256 or sha512) attribute. + - **output**: >MISP attributes and objects resulting from the parsing of the VirusTotal report concerning the input attribute. + - **references**: > - https://www.virustotal.com -> - https://developers.virustotal.com/reference +> - https://docs.virustotal.com/reference/overview + - **requirements**: >An access to the VirusTotal API (apikey) ----- -#### [vmray_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmray_submit.py) +#### [VirusTotal Upload](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_upload.py) + + + +Module to push malware samples to VirusTotal +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_upload.py)] + +- **config**: +>virustotal_apikey + +- **requirements**: +>requests library + +----- + +#### [VMRay Submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmray_submit.py) Module to submit a sample to VMRay. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmray_submit.py)] + - **features**: >This module takes an attachment or malware-sample attribute as input to query the VMRay API. > >The sample contained within the attribute in then enriched with data from VMRay mapped into MISP attributes. + +- **config**: +> - apikey +> - url +> - shareable +> - do_not_reanalyze +> - do_not_include_vmrayjobids + - **input**: >An attachment or malware-sample attribute. + - **output**: >MISP attributes mapped from the result of the query on VMRay API, included in the following list: >- text @@ -1833,105 +2706,208 @@ Module to submit a sample to VMRay. >- sha256 >- md5 >- link + - **references**: >https://www.vmray.com/ + - **requirements**: >An access to the VMRay API (apikey & url) ----- -#### [vmware_nsx](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmware_nsx.py) +#### [VMware NSX Defender Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmware_nsx.py) Module to enrich a file or URL with VMware NSX Defender. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmware_nsx.py)] + - **features**: >This module takes an IoC such as file hash, file attachment, malware-sample or url as input to query VMware NSX Defender. > >The IoC is then enriched with data from VMware NSX Defender. + +- **config**: +> - analysis_url +> - analysis_verify_ssl +> - analysis_key +> - analysis_api_token +> - vt_key +> - misp_url +> - misp_verify_ssl +> - misp_key + - **input**: >File hash, attachment or URL to be enriched with VMware NSX Defender. + - **output**: >Objects and tags generated by VMware NSX Defender. + - **references**: >https://www.vmware.com + - **requirements**: >The module requires a VMware NSX Defender Analysis `api_token` and `key`. ----- -#### [vulndb](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulndb.py) +#### [VulnDB Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulndb.py) Module to query VulnDB (RiskBasedSecurity.com). +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulndb.py)] + - **features**: >This module takes a vulnerability attribute as input and queries VulnDB in order to get some additional data about it. > >The API gives the result of the query which can be displayed in the screen, and/or mapped into MISP attributes to add in the event. + +- **config**: +> - apikey +> - apisecret +> - discard_dates +> - discard_external_references +> - discard_cvss +> - discard_productinformation +> - discard_classification +> - discard_cpe + - **input**: >A vulnerability attribute. + - **output**: >Additional data enriching the CVE input, fetched from VulnDB. + - **references**: >https://vulndb.cyberriskanalytics.com/ + - **requirements**: >An access to the VulnDB API (apikey, apisecret) ----- -#### [vulners](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulners.py) +#### [Vulnerability Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulnerability_lookup.py) + +An expansion module to query Vulnerability Lookup +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulnerability_lookup.py)] + +- **features**: +> + +----- + +#### [Vulners Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulners.py) An expansion hover module to expand information about CVE id using Vulners API. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulners.py)] + - **features**: >This module takes a vulnerability attribute as input and queries the Vulners API in order to get some additional data about it. > >The API then returns details about the vulnerability. + +- **config**: +>apikey + - **input**: >A vulnerability attribute. + - **output**: >Text giving additional information about the CVE in input. + - **references**: >https://vulners.com/ + - **requirements**: > - Vulners python library > - An access to the Vulners API ----- -#### [whois](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whois.py) +#### [Vysion Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vysion.py) + + + +Module to enrich the information by making use of the Vysion API. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vysion.py)] + +- **features**: +>This module gets correlated information from Byron Labs' dark web intelligence database. With this you will get several objects containing information related to, for example, an organization victim of a ransomware attack. + +- **config**: +> - apikey +> - event_limit +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + +- **input**: +>company(target-org), country, info, BTC, XMR and DASH address. + +- **output**: +>MISP objects containing title, link to our webapp and TOR, i2p or clearnet URLs. + +- **references**: +> - https://vysion.ai/ +> - https://developers.vysion.ai/ +> - https://github.com/ByronLabs/vysion-cti/tree/main + +- **requirements**: +> - Vysion python library +> - Vysion API Key + +----- + +#### [Whois Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whois.py) Module to query a local instance of uwhois (https://github.com/rafiot/uwhoisd). +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whois.py)] + - **features**: >This module takes a domain or IP address attribute as input and queries a 'Univseral Whois proxy server' to get the correct details of the Whois query on the input value (check the references for more details about this whois server). + +- **config**: +> - server +> - port + - **input**: >A domain or IP address attribute. + - **output**: >Text describing the result of a whois request for the input value. + - **references**: ->https://github.com/rafiot/uwhoisd +>https://github.com/Lookyloo/uwhoisd + - **requirements**: >uwhois: A whois python library ----- -#### [whoisfreaks](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whoisfreaks.py) +#### [WhoisFreaks Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whoisfreaks.py) An expansion module for https://whoisfreaks.com/ that will provide an enriched analysis of the provided domain, including WHOIS and DNS information. -Our Whois service, DNS Lookup API, and SSL analysis, equips organizations with comprehensive threat intelligence and attack surface analysis capabilities for enhanced security. -Explore our website's product section at https://whoisfreaks.com/ for a wide range of additional services catering to threat intelligence and attack surface analysis needs. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whoisfreaks.py)] + - **features**: >The module takes a domain as input and queries the Whoisfreaks API with it. > >Some parsing operations are then processed on the result of the query to extract as much information as possible. > >After this we map the extracted data to MISP attributes. + +- **config**: +>apikey + - **input**: >A domain whose Data is required + - **output**: >MISP attributes resulting from the query on Whoisfreaks API, included in the following list: >- domain @@ -1942,38 +2918,53 @@ Explore our website's product section at https://whoisfreaks.com/ for a wide ran >- whois-registrar >- whois-creation-date >- domain + - **references**: >https://whoisfreaks.com/ + - **requirements**: >An access to the Whoisfreaks API_KEY ----- -#### [wiki](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/wiki.py) +#### [Wikidata Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/wiki.py) An expansion hover module to extract information from Wikidata to have additional information about particular term for analysis. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/wiki.py)] + - **features**: >This module takes a text attribute as input and queries the Wikidata API. If the text attribute is clear enough to define a specific term, the API returns a wikidata link in response. + - **input**: >Text attribute. + - **output**: >Text attribute. + - **references**: >https://www.wikidata.org + - **requirements**: >SPARQLWrapper python library ----- -#### [xforceexchange](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xforceexchange.py) +#### [IBM X-Force Exchange Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xforceexchange.py) An expansion module for IBM X-Force Exchange. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xforceexchange.py)] + - **features**: >This module takes a MISP attribute as input to query the X-Force API. The API returns then additional information known in their threats data, that is mapped into MISP attributes. + +- **config**: +> - apikey +> - apipassword + - **input**: >A MISP attribute included in the following list: >- ip-src @@ -1982,83 +2973,116 @@ An expansion module for IBM X-Force Exchange. >- md5 >- sha1 >- sha256 + - **output**: >MISP attributes mapped from the result of the query on X-Force Exchange. + - **references**: >https://exchange.xforce.ibmcloud.com/ + - **requirements**: >An access to the X-Force API (apikey) ----- -#### [xlsx_enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xlsx_enrich.py) +#### [XLXS Enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xlsx_enrich.py) Module to extract freetext from a .xlsx document. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xlsx_enrich.py)] + - **features**: >The module reads the text contained in a .xlsx document. The result is passed to the freetext import parser so IoCs can be extracted out of it. + - **input**: >Attachment attribute containing a .xlsx document. + - **output**: >Text and freetext parsed from the document. + - **requirements**: >pandas: Python library to perform data analysis, time series and statistics. ----- -#### [yara_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_query.py) +#### [YARA Rule Generator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_query.py) -An expansion & hover module to translate any hash attribute into a yara rule. +jj +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_query.py)] + - **features**: >The module takes a hash attribute (md5, sha1, sha256, imphash) as input, and is returning a YARA rule from it. This YARA rule is also validated using the same method as in 'yara_syntax_validator' module. >Both hover and expansion functionalities are supported with this module, where the hover part is displaying the resulting YARA rule and the expansion part allows you to add the rule as a new attribute, as usual with expansion modules. + - **input**: >MISP Hash attribute (md5, sha1, sha256, imphash, or any of the composite attribute with filename and one of the previous hash type). + - **output**: >YARA rule. + - **references**: > - https://virustotal.github.io/yara/ > - https://github.com/virustotal/yara-python + +- **require_standard_format**: +>True + - **requirements**: >yara-python python library ----- -#### [yara_syntax_validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_syntax_validator.py) +#### [YARA Syntax Validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_syntax_validator.py) An expansion hover module to perform a syntax check on if yara rules are valid or not. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_syntax_validator.py)] + - **features**: >This modules simply takes a YARA rule as input, and checks its syntax. It returns then a confirmation if the syntax is valid, otherwise the syntax error is displayed. + - **input**: >YARA rule attribute. + - **output**: >Text to inform users if their rule is valid. + - **references**: >http://virustotal.github.io/yara/ + - **requirements**: >yara_python python library ----- -#### [yeti](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yeti.py) +#### [Yeti Lookup](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yeti.py) Module to process a query on Yeti. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yeti.py)] + - **features**: >This module add context and links between observables using yeti + +- **config**: +> - apikey +> - url + - **input**: >A domain, hostname,IP, sha256,sha1, md5, url of MISP attribute. + - **output**: >MISP attributes and objects fetched from the Yeti instances. + - **references**: > - https://github.com/yeti-platform/yeti > - https://github.com/sebdraven/pyeti + - **requirements**: > - pyeti > - API key diff --git a/documentation/mkdocs/export_mod.md b/documentation/mkdocs/export_mod.md index c0848f58..bd369f11 100644 --- a/documentation/mkdocs/export_mod.md +++ b/documentation/mkdocs/export_mod.md @@ -1,56 +1,89 @@ -#### [cef_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cef_export.py) +#### [CEF Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cef_export.py) Module to export a MISP event in CEF format. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cef_export.py)] + - **features**: >The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in Common Event Format. >Thus, there is no particular feature concerning MISP Events since any event can be exported. However, 4 configuration parameters recognized by CEF format are required and should be provided by users before exporting data: the device vendor, product and version, as well as the default severity of data. + +- **config**: +> - Default_Severity +> - Device_Vendor +> - Device_Product +> - Device_Version + - **input**: >MISP Event attributes + - **output**: >Common Event Format file + - **references**: >https://community.softwaregrp.com/t5/ArcSight-Connectors/ArcSight-Common-Event-Format-CEF-Guide/ta-p/1589306?attachment-id=65537 ----- -#### [cisco_firesight_manager_ACL_rule_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py) +#### [Cisco fireSIGHT blockrule Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py) Module to export malicious network activity attributes to Cisco fireSIGHT manager block rules. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py)] + - **features**: >The module goes through the attributes to find all the network activity ones in order to create block rules for the Cisco fireSIGHT manager. + +- **config**: +> - fmc_ip_addr +> - fmc_login +> - fmc_pass +> - domain_id +> - acpolicy_id + - **input**: >Network activity attributes (IPs, URLs). + - **output**: >Cisco fireSIGHT manager block rules. + - **requirements**: >Firesight manager console credentials ----- -#### [defender_endpoint_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/defender_endpoint_export.py) +#### [Microsoft Defender for Endpoint KQL Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/defender_endpoint_export.py) Defender for Endpoint KQL hunting query export module +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/defender_endpoint_export.py)] + - **features**: >This module export an event as Defender for Endpoint KQL queries that can then be used in your own python3 or Powershell tool. If you are using Microsoft Sentinel, you can directly connect your MISP instance to Sentinel and then create queries using the `ThreatIntelligenceIndicator` table to match events against imported IOC. + +- **config**: +>Period + - **input**: >MISP Event attributes + - **output**: >Defender for Endpoint KQL queries + - **references**: >https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/advanced-hunting-schema-reference ----- -#### [goamlexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/goamlexport.py) +#### [GoAML Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/goamlexport.py) This module is used to export MISP events containing transaction objects into GoAML format. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/goamlexport.py)] + - **features**: >The module works as long as there is at least one transaction object in the Event. > @@ -70,79 +103,115 @@ This module is used to export MISP events containing transaction objects into Go > - 'entity': Entity owning the bank account - optional. >- person: > - 'address': Address of a person - optional. + +- **config**: +>rentity_id + - **input**: >MISP objects (transaction, bank-account, person, legal-entity, geolocation), with references, describing financial transactions and their origin and target. + - **output**: >GoAML format file, describing financial transactions, with their origin and target (bank accounts, persons or entities). + - **references**: >http://goaml.unodc.org/ + +- **require_standard_format**: +>True + - **requirements**: > - PyMISP > - MISP objects ----- -#### [liteexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/liteexport.py) +#### [Lite Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/liteexport.py) Lite export of a MISP event. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/liteexport.py)] + - **features**: >This module is simply producing a json MISP event format file, but exporting only Attributes from the Event. Thus, MISP Events exported with this module should have attributes that are not internal references, otherwise the resulting event would be empty. + +- **config**: +>indent_json_export + - **input**: >MISP Event attributes + - **output**: >Lite MISP Event ----- -#### [mass_eql_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/mass_eql_export.py) +#### [EQL Query Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/mass_eql_export.py) -Mass EQL query export for a MISP event. +Export MISP event in Event Query Language +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/mass_eql_export.py)] + - **features**: >This module produces EQL queries for all relevant attributes in a MISP event. + - **input**: >MISP Event attributes + - **output**: >Text file containing one or more EQL queries + - **references**: >https://eql.readthedocs.io/en/latest/ ----- -#### [nexthinkexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/nexthinkexport.py) +#### [Nexthink NXQL Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/nexthinkexport.py) Nexthink NXQL query export module +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/nexthinkexport.py)] + - **features**: >This module export an event as Nexthink NXQL queries that can then be used in your own python3 tool or from wget/powershell + +- **config**: +>Period + - **input**: >MISP Event attributes + - **output**: >Nexthink NXQL queries + - **references**: >https://doc.nexthink.com/Documentation/Nexthink/latest/APIAndIntegrations/IntroducingtheWebAPIV2 ----- -#### [osqueryexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/osqueryexport.py) +#### [OSQuery Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/osqueryexport.py) OSQuery export of a MISP event. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/osqueryexport.py)] + - **features**: >This module export an event as osquery queries that can be used in packs or in fleet management solution like Kolide. + - **input**: >MISP Event attributes + - **output**: >osquery SQL queries ----- -#### [pdfexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/pdfexport.py) +#### [Event to PDF Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/pdfexport.py) Simple export of a MISP event to PDF. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/pdfexport.py)] + - **features**: >The module takes care of the PDF file building, and work with any MISP Event. Except the requirement of reportlab, used to create the file, there is no special feature concerning the Event. Some parameters can be given through the config dict. 'MISP_base_url_for_dynamic_link' is your MISP URL, to attach an hyperlink to your event on your MISP instance from the PDF. Keep it clear to avoid hyperlinks in the generated pdf. > 'MISP_name_for_metadata' is your CERT or MISP instance name. Used as text in the PDF' metadata @@ -151,97 +220,177 @@ Simple export of a MISP event to PDF. > 'Activate_related_events' is a boolean (True or void) to activate the description of related event. Be aware this might leak information on confidential events linked to the current event ! > 'Activate_internationalization_fonts' is a boolean (True or void) to activate Noto fonts instead of default fonts (Helvetica). This allows the support of CJK alphabet. Be sure to have followed the procedure to download Noto fonts (~70Mo) in the right place (/tools/pdf_fonts/Noto_TTF), to allow PyMisp to find and use them during PDF generation. > 'Custom_fonts_path' is a text (path or void) to the TTF file of your choice, to create the PDF with it. Be aware the PDF won't support bold/italic/special style anymore with this option + +- **config**: +> - MISP_base_url_for_dynamic_link +> - MISP_name_for_metadata +> - Activate_textual_description +> - Activate_galaxy_description +> - Activate_related_events +> - Activate_internationalization_fonts +> - Custom_fonts_path + - **input**: >MISP Event + - **output**: >MISP Event in a PDF file. + - **references**: >https://acrobat.adobe.com/us/en/acrobat/about-adobe-pdf.html + +- **require_standard_format**: +>True + - **requirements**: > - PyMISP > - reportlab ----- -#### [testexport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/testexport.py) - -Skeleton export module. - ------ - -#### [threatStream_misp_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threatStream_misp_export.py) +#### [ThreatStream Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threatStream_misp_export.py) Module to export a structured CSV file for uploading to threatStream. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threatStream_misp_export.py)] + - **features**: >The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in a CSV format recognized by ThreatStream. + - **input**: >MISP Event attributes + - **output**: >ThreatStream CSV format file + - **references**: > - https://www.anomali.com/platform/threatstream > - https://github.com/threatstream + - **requirements**: >csv ----- -#### [threat_connect_export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threat_connect_export.py) +#### [ThreadConnect Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threat_connect_export.py) Module to export a structured CSV file for uploading to ThreatConnect. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threat_connect_export.py)] + - **features**: >The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in a CSV format recognized by ThreatConnect. >Users should then provide, as module configuration, the source of data they export, because it is required by the output format. + +- **config**: +>Default_Source + - **input**: >MISP Event attributes + - **output**: >ThreatConnect CSV format file + - **references**: >https://www.threatconnect.com + - **requirements**: >csv ----- -#### [virustotal_collections](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/virustotal_collections.py) +#### [VirusTotal Collections Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/virustotal_collections.py) Creates a VT Collection from an event iocs. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/virustotal_collections.py)] + - **features**: >This export module which takes advantage of a new endpoint in VT APIv3 to create VT Collections from IOCs contained in a MISP event. With this module users will be able to create a collection just using the Download as... button. + +- **config**: +> - vt_api_key +> - proxy_host +> - proxy_port +> - proxy_username +> - proxy_password + - **input**: >A domain, hash (md5, sha1, sha256 or sha512), hostname, url or IP address attribute. + - **output**: >A VirusTotal collection in VT. + - **references**: > - https://www.virustotal.com/ > - https://blog.virustotal.com/2021/11/introducing-virustotal-collections.html + - **requirements**: >An access to the VirusTotal API (apikey). ----- -#### [vt_graph](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/vt_graph.py) +#### [VirusTotal Graph Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/vt_graph.py) This module is used to create a VirusTotal Graph from a MISP event. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/vt_graph.py)] + - **features**: >The module takes the MISP event as input and queries the VirusTotal Graph API to create a new graph out of the event. > >Once the graph is ready, we get the url of it, which is returned so we can view it on VirusTotal. + +- **config**: +> - vt_api_key +> - fetch_information +> - private +> - fetch_vt_enterprise +> - expand_one_level +> - user_editors +> - user_viewers +> - group_editors +> - group_viewers + - **input**: >A MISP event. + - **output**: >Link of the VirusTotal Graph created for the event. + - **references**: >https://www.virustotal.com/gui/graph-overview + - **requirements**: >vt_graph_api, the python library to query the VirusTotal graph API ----- + +#### [YARA Rule Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/yara_export.py) + + + +This module is used to export MISP events to YARA. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/yara_export.py)] + +- **features**: +>The module will dynamically generate YARA rules for attributes that are marked as to IDS. Basic metadata about the event is added to the rule. +>Attributes that are already YARA rules are also exported, with a rewritten rule name. + +- **input**: +>Attributes and Objects. + +- **output**: +>A YARA file that can be used with the YARA scanning tool. + +- **references**: +>https://virustotal.github.io/yara/ + +- **requirements**: +>yara-python python library + +----- diff --git a/documentation/mkdocs/import_mod.md b/documentation/mkdocs/import_mod.md index 8b6fcdf9..64741f42 100644 --- a/documentation/mkdocs/import_mod.md +++ b/documentation/mkdocs/import_mod.md @@ -1,198 +1,323 @@ -#### [cof2misp](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cof2misp.py) +#### [PDNS COF Importer](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cof2misp.py) Passive DNS Common Output Format (COF) MISP importer +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cof2misp.py)] + - **features**: >Takes as input a valid COF file or the output of the dnsdbflex utility and creates MISP objects for the input. + - **input**: >Passive DNS output in Common Output Format (COF) + - **output**: >MISP objects + - **references**: >https://tools.ietf.org/id/draft-dulaunoy-dnsop-passive-dns-cof-08.html + - **requirements**: >PyMISP ----- -#### [csvimport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/csvimport.py) +#### [CSV Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/csvimport.py) Module to import MISP attributes from a csv file. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/csvimport.py)] + - **features**: >In order to parse data from a csv file, a header is required to let the module know which column is matching with known attribute fields / MISP types. > >This header either comes from the csv file itself or is part of the configuration of the module and should be filled out in MISP plugin settings, each field separated by COMMAS. Fields that do not match with any type known in MISP or are not MISP attribute fields should be ignored in import, using a space or simply nothing between two separators (example: 'ip-src, , comment, '). > >If the csv file already contains a header that does not start by a '#', you should tick the checkbox 'has_header' to avoid importing it and have potential issues. You can also redefine the header even if it is already contained in the file, by following the rules for headers explained earlier. One reason why you would redefine a header is for instance when you want to skip some fields, or some fields are not valid types. + - **input**: >CSV format file. + - **output**: >MISP Event attributes + - **references**: > - https://tools.ietf.org/html/rfc4180 > - https://tools.ietf.org/html/rfc7111 + - **requirements**: >PyMISP ----- -#### [cuckooimport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cuckooimport.py) +#### [Cuckoo Sandbox Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cuckooimport.py) Module to import Cuckoo JSON. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cuckooimport.py)] + - **features**: ->The module simply imports MISP Attributes from a Cuckoo JSON format file. There is thus no special feature to make it work. +>Import a Cuckoo archive (zipfile or bzip2 tarball), either downloaded manually or exported from the API (/tasks/report//all). + - **input**: >Cuckoo JSON file + - **output**: >MISP Event attributes + - **references**: > - https://cuckoosandbox.org/ > - https://github.com/cuckoosandbox/cuckoo ----- -#### [email_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/email_import.py) +#### [Email Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/email_import.py) + +Email import module for MISP +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/email_import.py)] -Module to import emails in MISP. - **features**: >This module can be used to import e-mail text as well as attachments and urls. >3 configuration parameters are then used to unzip attachments, guess zip attachment passwords, and extract urls: set each one of them to True or False to process or not the respective corresponding actions. + +- **config**: +> - unzip_attachments +> - guess_zip_attachment_passwords +> - extract_urls + - **input**: >E-mail file + - **output**: >MISP Event attributes ----- -#### [goamlimport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/goamlimport.py) +#### [GoAML Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/goamlimport.py) Module to import MISP objects about financial transactions from GoAML files. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/goamlimport.py)] + - **features**: >Unlike the GoAML export module, there is here no special feature to import data from GoAML external files, since the module will import MISP Objects with their References on its own, as it is required for the export module to rebuild a valid GoAML document. + - **input**: >GoAML format file, describing financial transactions, with their origin and target (bank accounts, persons or entities). + - **output**: >MISP objects (transaction, bank-account, person, legal-entity, geolocation), with references, describing financial transactions and their origin and target. + - **references**: >http://goaml.unodc.org/ + - **requirements**: >PyMISP ----- -#### [joe_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/joe_import.py) +#### [Import Blueprint](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/import_blueprint.py) + +Generic blueprint to be copy-pasted to quickly boostrap creation of import module. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/import_blueprint.py)] + +- **features**: +> + +----- + +#### [Joe Sandbox Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/joe_import.py) A module to import data from a Joe Sandbox analysis json report. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/joe_import.py)] + - **features**: >Module using the new format of modules able to return attributes and objects. > >The module returns the same results as the expansion module [joesandbox_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) using the submission link of the analysis to get the json report. + - **input**: >Json report of a Joe Sandbox analysis. + - **output**: >MISP attributes & objects parsed from the analysis report. + - **references**: > - https://www.joesecurity.org > - https://www.joesandbox.com/ ----- -#### [lastline_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/lastline_import.py) +#### [Lastline Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/lastline_import.py) Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Module to import and parse reports from Lastline analysis links. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/lastline_import.py)] + - **features**: >The module requires a Lastline Portal `username` and `password`. >The module uses the new format and it is able to return MISP attributes and objects. >The module returns the same results as the [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) expansion module. + +- **config**: +> - username +> - password +> - verify_ssl + - **input**: >Link to a Lastline analysis. + - **output**: >MISP attributes and objects parsed from the analysis report. + - **references**: >https://www.lastline.com ----- -#### [mispjson](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/mispjson.py) +#### [MISP JSON Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/mispjson.py) Module to import MISP JSON format for merging MISP events. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/mispjson.py)] + - **features**: >The module simply imports MISP Attributes from an other MISP Event in order to merge events together. There is thus no special feature to make it work. + - **input**: >MISP Event + - **output**: >MISP Event attributes ----- -#### [ocr](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/ocr.py) +#### [OCR Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/ocr.py) Optical Character Recognition (OCR) module for MISP. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/ocr.py)] + - **features**: >The module tries to recognize some text from an image and import the result as a freetext attribute, there is then no special feature asked to users to make it work. + - **input**: >Image + - **output**: >freetext MISP attribute ----- -#### [openiocimport](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/openiocimport.py) +#### [OpenIOC Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/openiocimport.py) Module to import OpenIOC packages. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/openiocimport.py)] + - **features**: >The module imports MISP Attributes from OpenIOC packages, there is then no special feature for users to make it work. + - **input**: >OpenIOC packages + - **output**: >MISP Event attributes + - **references**: >https://www.fireeye.com/blog/threat-research/2013/10/openioc-basics.html + - **requirements**: >PyMISP ----- -#### [threatanalyzer_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/threatanalyzer_import.py) +#### [TAXII 2.1 Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/taxii21.py) + +Import content from a TAXII 2.1 server +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/taxii21.py)] + +- **features**: +> + +- **config**: +>stix_object_limit + +----- + +#### [ThreadAnalyzer Sandbox Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/threatanalyzer_import.py) Module to import ThreatAnalyzer archive.zip / analysis.json files. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/threatanalyzer_import.py)] + - **features**: >The module imports MISP Attributes from a ThreatAnalyzer format file. This file can be either ZIP, or JSON format. >There is by the way no special feature for users to make the module work. + - **input**: >ThreatAnalyzer format file + - **output**: >MISP Event attributes + - **references**: >https://www.threattrack.com/malware-analysis.aspx ----- -#### [vmray_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_import.py) +#### [URL Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/url_import.py) + +Simple URL import tool with Faup +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/url_import.py)] + +- **features**: +> + +----- + +#### [VMRay API Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_import.py) Module to import VMRay (VTI) results. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_import.py)] + - **features**: >The module imports MISP Attributes from VMRay format, using the VMRay api. >Users should then provide as the module configuration the API Key as well as the server url in order to fetch their data to import. + +- **config**: +> - apikey +> - url +> - disable_tags +> - disable_misp_objects +> - ignore_analysis_finished + - **input**: >VMRay format + - **output**: >MISP Event attributes + - **references**: >https://www.vmray.com/ + - **requirements**: >vmray_rest_api ----- + +#### [VMRay Summary JSON Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_summary_json_import.py) + +Import a VMRay Summary JSON report. +[[source code](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_summary_json_import.py)] + +- **features**: +> + +- **config**: +>disable_tags + +----- diff --git a/documentation/mkdocs/index.md b/documentation/mkdocs/index.md index e2c5a13f..ba64730d 100644 --- a/documentation/mkdocs/index.md +++ b/documentation/mkdocs/index.md @@ -1,111 +1,169 @@ # Home -[![Build Status](https://travis-ci.org/MISP/misp-modules.svg?branch=master)](https://travis-ci.org/MISP/misp-modules) -[![Coverage Status](https://coveralls.io/repos/github/MISP/misp-modules/badge.svg?branch=master)](https://coveralls.io/github/MISP/misp-modules?branch=master) +[![Build status](https://github.com/MISP/misp-modules/actions/workflows/test-package.yml/badge.svg)](https://github.com/MISP/misp-modules/actions/workflows/test-package.yml)[![Coverage Status](https://coveralls.io/repos/github/MISP/misp-modules/badge.svg?branch=main)](https://coveralls.io/github/MISP/misp-modules?branch=main) [![codecov](https://codecov.io/gh/MISP/misp-modules/branch/main/graph/badge.svg)](https://codecov.io/gh/MISP/misp-modules) -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%MISP%2Fmisp-modules.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FMISP%2Fmisp-modules?ref=badge_shield) -MISP modules are autonomous modules that can be used for expansion and other services in [MISP](https://github.com/MISP/MISP). +MISP modules are autonomous modules that can be used to extend [MISP](https://github.com/MISP/MISP) for new services such as expansion, import, export and workflow action. + +MISP modules can be also installed and used without MISP as a [standalone tool accessible via a convenient web interface](./website). The modules are written in Python 3 following a simple API interface. The objective is to ease the extensions of MISP functionalities -without modifying core components. The API is available via a simple REST API which is independent from MISP installation or configuration. - -MISP modules support is included in MISP starting from version `2.4.28`. - -For more information: [Extending MISP with Python modules](https://www.circl.lu/assets/files/misp-training/switch2016/2-misp-modules.pdf) slides from MISP training. +without modifying core components. The API is available via a simple REST API which is independent from MISP installation or configuration and can be used with other tools. +For more information: [Extending MISP with Python modules](https://www.misp-project.org/misp-training/3.1-misp-modules.pdf) slides from [MISP training](https://github.com/MISP/misp-training). ## Existing MISP modules -### Expansion modules +### Expansion Modules +* [Abuse IPDB](https://misp.github.io/misp-modules/expansion/#abuse-ipdb) - AbuseIPDB MISP expansion module +* [OSINT DigitalSide](https://misp.github.io/misp-modules/expansion/#osint-digitalside) - On demand query API for OSINT.digitalside.it project. +* [APIVoid](https://misp.github.io/misp-modules/expansion/#apivoid) - Module to query APIVoid with some domain attributes. +* [AssemblyLine Query](https://misp.github.io/misp-modules/expansion/#assemblyline-query) - A module tu query the AssemblyLine API with a submission ID to get the submission report and parse it. +* [AssemblyLine Submit](https://misp.github.io/misp-modules/expansion/#assemblyline-submit) - A module to submit samples and URLs to AssemblyLine for advanced analysis, and return the link of the submission. +* [Backscatter.io](https://misp.github.io/misp-modules/expansion/#backscatter.io) - Backscatter.io module to bring mass-scanning observations into MISP. +* [BTC Scam Check](https://misp.github.io/misp-modules/expansion/#btc-scam-check) - An expansion hover module to query a special dns blacklist to check if a bitcoin address has been abused. +* [BTC Steroids](https://misp.github.io/misp-modules/expansion/#btc-steroids) - An expansion hover module to get a blockchain balance from a BTC address in MISP. +* [Censys Enrich](https://misp.github.io/misp-modules/expansion/#censys-enrich) - An expansion module to enrich attributes in MISP by quering the censys.io API +* [CIRCL Passive DNS](https://misp.github.io/misp-modules/expansion/#circl-passive-dns) - Module to access CIRCL Passive DNS. +* [CIRCL Passive SSL](https://misp.github.io/misp-modules/expansion/#circl-passive-ssl) - Modules to access CIRCL Passive SSL. +* [ClaamAV](https://misp.github.io/misp-modules/expansion/#claamav) - Submit file to ClamAV +* [Cluster25 Expand](https://misp.github.io/misp-modules/expansion/#cluster25-expand) - Module to query Cluster25 CTI. +* [Country Code](https://misp.github.io/misp-modules/expansion/#country-code) - Module to expand country codes. +* [CPE Lookup](https://misp.github.io/misp-modules/expansion/#cpe-lookup) - An expansion module to query the CVE search API with a cpe code to get its related vulnerabilities. +* [CrowdSec CTI](https://misp.github.io/misp-modules/expansion/#crowdsec-cti) - Module to access CrowdSec CTI API. +* [CrowdStrike Falcon](https://misp.github.io/misp-modules/expansion/#crowdstrike-falcon) - Module to query CrowdStrike Falcon. +* [Cuckoo Submit](https://misp.github.io/misp-modules/expansion/#cuckoo-submit) - Submit files and URLs to Cuckoo Sandbox +* [CVE Lookup](https://misp.github.io/misp-modules/expansion/#cve-lookup) - An expansion hover module to expand information about CVE id. +* [CVE Advanced Lookup](https://misp.github.io/misp-modules/expansion/#cve-advanced-lookup) - An expansion module to query the CIRCL CVE search API for more information about a vulnerability (CVE). +* [Cytomic Orion Lookup](https://misp.github.io/misp-modules/expansion/#cytomic-orion-lookup) - An expansion module to enrich attributes in MISP by quering the Cytomic Orion API +* [DBL Spamhaus Lookup](https://misp.github.io/misp-modules/expansion/#dbl-spamhaus-lookup) - Checks Spamhaus DBL for a domain name. +* [DNS Resolver](https://misp.github.io/misp-modules/expansion/#dns-resolver) - jj +* [DOCX Enrich](https://misp.github.io/misp-modules/expansion/#docx-enrich) - Module to extract freetext from a .docx document. +* [DomainTools Lookup](https://misp.github.io/misp-modules/expansion/#domaintools-lookup) - DomainTools MISP expansion module. +* [EQL Query Generator](https://misp.github.io/misp-modules/expansion/#eql-query-generator) - EQL query generation for a MISP attribute. +* [EUPI Lookup](https://misp.github.io/misp-modules/expansion/#eupi-lookup) - A module to query the Phishing Initiative service (https://phishing-initiative.lu). +* [URL Components Extractor](https://misp.github.io/misp-modules/expansion/#url-components-extractor) - Extract URL components +* [Farsight DNSDB Lookup](https://misp.github.io/misp-modules/expansion/#farsight-dnsdb-lookup) - Module to access Farsight DNSDB Passive DNS. +* [GeoIP ASN Lookup](https://misp.github.io/misp-modules/expansion/#geoip-asn-lookup) - Query a local copy of the Maxmind Geolite ASN database (MMDB format) +* [GeoIP City Lookup](https://misp.github.io/misp-modules/expansion/#geoip-city-lookup) - An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about the city where it is located. +* [GeoIP Country Lookup](https://misp.github.io/misp-modules/expansion/#geoip-country-lookup) - Query a local copy of Maxminds Geolite database, updated for MMDB format +* [Google Safe Browsing Lookup](https://misp.github.io/misp-modules/expansion/#google-safe-browsing-lookup) - Google safe browsing expansion module +* [Google Search](https://misp.github.io/misp-modules/expansion/#google-search) - An expansion hover module to expand google search information about an URL +* [Google Threat Intelligence Lookup](https://misp.github.io/misp-modules/expansion/#google-threat-intelligence-lookup) - An expansion module to have the observable's threat score assessed by Google Threat Intelligence. +* [GreyNoise Lookup](https://misp.github.io/misp-modules/expansion/#greynoise-lookup) - Module to query IP and CVE information from GreyNoise +* [Hashdd Lookup](https://misp.github.io/misp-modules/expansion/#hashdd-lookup) - A hover module to check hashes against hashdd.com including NSLR dataset. +* [CIRCL Hashlookup Lookup](https://misp.github.io/misp-modules/expansion/#circl-hashlookup-lookup) - An expansion module to query the CIRCL hashlookup services to find it if a hash is part of a known set such as NSRL. +* [Have I Been Pwned Lookup](https://misp.github.io/misp-modules/expansion/#have-i-been-pwned-lookup) - Module to access haveibeenpwned.com API. +* [HTML to Markdown](https://misp.github.io/misp-modules/expansion/#html-to-markdown) - Expansion module to fetch the html content from an url and convert it into markdown. +* [HYAS Insight Lookup](https://misp.github.io/misp-modules/expansion/#hyas-insight-lookup) - HYAS Insight integration to MISP provides direct, high volume access to HYAS Insight data. It enables investigators and analysts to understand and defend against cyber adversaries and their infrastructure. +* [Intel471 Lookup](https://misp.github.io/misp-modules/expansion/#intel471-lookup) - Module to access Intel 471 +* [IP2Location.io Lookup](https://misp.github.io/misp-modules/expansion/#ip2location.io-lookup) - An expansion module to query IP2Location.io to gather more information on a given IP address. +* [IPASN-History Lookup](https://misp.github.io/misp-modules/expansion/#ipasn-history-lookup) - Module to query an IP ASN history service (https://github.com/D4-project/IPASN-History). +* [IPInfo.io Lookup](https://misp.github.io/misp-modules/expansion/#ipinfo.io-lookup) - An expansion module to query ipinfo.io to gather more information on a given IP address. +* [IPQualityScore Lookup](https://misp.github.io/misp-modules/expansion/#ipqualityscore-lookup) - IPQualityScore MISP Expansion Module for IP reputation, Email Validation, Phone Number Validation, Malicious Domain and Malicious URL Scanner. +* [IPRep Lookup](https://misp.github.io/misp-modules/expansion/#iprep-lookup) - Module to query IPRep data for IP addresses. +* [Ninja Template Rendering](https://misp.github.io/misp-modules/expansion/#ninja-template-rendering) - Render the template with the data passed +* [Joe Sandbox Import](https://misp.github.io/misp-modules/expansion/#joe-sandbox-import) - Query Joe Sandbox API with a submission url to get the json report and extract its data that is parsed and converted into MISP attributes and objects. +* [Joe Sandbox Submit](https://misp.github.io/misp-modules/expansion/#joe-sandbox-submit) - A module to submit files or URLs to Joe Sandbox for an advanced analysis, and return the link of the submission. +* [Lastline Lookup](https://misp.github.io/misp-modules/expansion/#lastline-lookup) - Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Query Lastline with an analysis link and parse the report into MISP attributes and objects. +* [Lastline Submit](https://misp.github.io/misp-modules/expansion/#lastline-submit) - Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Module to submit a file or URL to Lastline. +* [Macaddress.io Lookup](https://misp.github.io/misp-modules/expansion/#macaddress.io-lookup) - MISP hover module for macaddress.io +* [Macvendors Lookup](https://misp.github.io/misp-modules/expansion/#macvendors-lookup) - Module to access Macvendors API. +* [MalShare Upload](https://misp.github.io/misp-modules/expansion/#malshare-upload) - Module to push malware samples to MalShare +* [Malware Bazaar Lookup](https://misp.github.io/misp-modules/expansion/#malware-bazaar-lookup) - Query Malware Bazaar to get additional information about the input hash. +* [McAfee MVISION Insights Lookup](https://misp.github.io/misp-modules/expansion/#mcafee-mvision-insights-lookup) - Lookup McAfee MVISION Insights Details +* [GeoIP Enrichment](https://misp.github.io/misp-modules/expansion/#geoip-enrichment) - A hover and expansion module to enrich an ip with geolocation and ASN information from an mmdb server instance, such as CIRCL's ip.circl.lu. +* [MWDB Submit](https://misp.github.io/misp-modules/expansion/#mwdb-submit) - Module to push malware samples to a MWDB instance +* [OCR Enrich](https://misp.github.io/misp-modules/expansion/#ocr-enrich) - Module to process some optical character recognition on pictures. +* [ODS Enrich](https://misp.github.io/misp-modules/expansion/#ods-enrich) - Module to extract freetext from a .ods document. +* [ODT Enrich](https://misp.github.io/misp-modules/expansion/#odt-enrich) - Module to extract freetext from a .odt document. +* [Onyphe Lookup](https://misp.github.io/misp-modules/expansion/#onyphe-lookup) - Module to process a query on Onyphe. +* [Onyphe Full Lookup](https://misp.github.io/misp-modules/expansion/#onyphe-full-lookup) - Module to process a full query on Onyphe. +* [AlienVault OTX Lookup](https://misp.github.io/misp-modules/expansion/#alienvault-otx-lookup) - Module to get information from AlienVault OTX. +* [Passive SSH Enrichment](https://misp.github.io/misp-modules/expansion/#passive-ssh-enrichment) - An expansion module to enrich, SSH key fingerprints and IP addresses with information collected by passive-ssh +* [PassiveTotal Lookup](https://misp.github.io/misp-modules/expansion/#passivetotal-lookup) - The PassiveTotal MISP expansion module brings the datasets derived from Internet scanning directly into your MISP instance. This module supports passive DNS, historic SSL, WHOIS, and host attributes. In order to use the module, you must have a valid PassiveTotal account username and API key. Registration is free and can be done by visiting https://www.passivetotal.org/register +* [PDF Enrich](https://misp.github.io/misp-modules/expansion/#pdf-enrich) - Module to extract freetext from a PDF document. +* [PPTX Enrich](https://misp.github.io/misp-modules/expansion/#pptx-enrich) - Module to extract freetext from a .pptx document. +* [Qintel QSentry Lookup](https://misp.github.io/misp-modules/expansion/#qintel-qsentry-lookup) - A hover and expansion module which queries Qintel QSentry for ip reputation data +* [QR Code Decode](https://misp.github.io/misp-modules/expansion/#qr-code-decode) - Module to decode QR codes. +* [RandomcoinDB Lookup](https://misp.github.io/misp-modules/expansion/#randomcoindb-lookup) - Module to access the ransomcoinDB (see https://ransomcoindb.concinnity-risks.com) +* [Real-time Blackhost Lists Lookup](https://misp.github.io/misp-modules/expansion/#real-time-blackhost-lists-lookup) - Module to check an IPv4 address against known RBLs. +* [Recorded Future Enrich](https://misp.github.io/misp-modules/expansion/#recorded-future-enrich) - Module to enrich attributes with threat intelligence from Recorded Future. +* [Reverse DNS](https://misp.github.io/misp-modules/expansion/#reverse-dns) - Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes. +* [SecurityTrails Lookup](https://misp.github.io/misp-modules/expansion/#securitytrails-lookup) - An expansion modules for SecurityTrails. +* [Shodan Lookup](https://misp.github.io/misp-modules/expansion/#shodan-lookup) - Module to query on Shodan. +* [Sigma Rule Converter](https://misp.github.io/misp-modules/expansion/#sigma-rule-converter) - An expansion hover module to display the result of sigma queries. +* [Sigma Syntax Validator](https://misp.github.io/misp-modules/expansion/#sigma-syntax-validator) - An expansion hover module to perform a syntax check on sigma rules. +* [SigMF Expansion](https://misp.github.io/misp-modules/expansion/#sigmf-expansion) - Expands a SigMF Recording object into a SigMF Expanded Recording object, extracts a SigMF archive into a SigMF Recording object. +* [Socialscan Lookup](https://misp.github.io/misp-modules/expansion/#socialscan-lookup) - A hover module to get information on the availability of an email address or username on some online platforms. +* [SophosLabs Intelix Lookup](https://misp.github.io/misp-modules/expansion/#sophoslabs-intelix-lookup) - An expansion module to query the Sophoslabs intelix API to get additional information about an ip address, url, domain or sha256 attribute. +* [URL Archiver](https://misp.github.io/misp-modules/expansion/#url-archiver) - Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page. +* [Stairwell Lookup](https://misp.github.io/misp-modules/expansion/#stairwell-lookup) - Module to query the Stairwell API to get additional information about the input hash attribute +* [STIX2 Pattern Syntax Validator](https://misp.github.io/misp-modules/expansion/#stix2-pattern-syntax-validator) - An expansion hover module to perform a syntax check on stix2 patterns. +* [ThreatCrowd Lookup](https://misp.github.io/misp-modules/expansion/#threatcrowd-lookup) - Module to get information from ThreatCrowd. +* [ThreadFox Lookup](https://misp.github.io/misp-modules/expansion/#threadfox-lookup) - Module to search for an IOC on ThreatFox by abuse.ch. +* [ThreatMiner Lookup](https://misp.github.io/misp-modules/expansion/#threatminer-lookup) - Module to get information from ThreatMiner. +* [Triage Submit](https://misp.github.io/misp-modules/expansion/#triage-submit) - Module to submit samples to tria.ge +* [TruSTAR Enrich](https://misp.github.io/misp-modules/expansion/#trustar-enrich) - Module to get enrich indicators with TruSTAR. +* [URLhaus Lookup](https://misp.github.io/misp-modules/expansion/#urlhaus-lookup) - Query of the URLhaus API to get additional information about the input attribute. +* [URLScan Lookup](https://misp.github.io/misp-modules/expansion/#urlscan-lookup) - An expansion module to query urlscan.io. +* [VARIoT db Lookup](https://misp.github.io/misp-modules/expansion/#variot-db-lookup) - An expansion module to query the VARIoT db API for more information about a vulnerability. +* [VirusTotal v3 Lookup](https://misp.github.io/misp-modules/expansion/#virustotal-v3-lookup) - Enrich observables with the VirusTotal v3 API +* [VirusTotal Public API Lookup](https://misp.github.io/misp-modules/expansion/#virustotal-public-api-lookup) - Enrich observables with the VirusTotal v3 public API +* [VirusTotal Upload](https://misp.github.io/misp-modules/expansion/#virustotal-upload) - Module to push malware samples to VirusTotal +* [VMRay Submit](https://misp.github.io/misp-modules/expansion/#vmray-submit) - Module to submit a sample to VMRay. +* [VMware NSX Defender Enrich](https://misp.github.io/misp-modules/expansion/#vmware-nsx-defender-enrich) - Module to enrich a file or URL with VMware NSX Defender. +* [VulnDB Lookup](https://misp.github.io/misp-modules/expansion/#vulndb-lookup) - Module to query VulnDB (RiskBasedSecurity.com). +* [Vulnerability Lookup](https://misp.github.io/misp-modules/expansion/#vulnerability-lookup) - An expansion module to query Vulnerability Lookup +* [Vulners Lookup](https://misp.github.io/misp-modules/expansion/#vulners-lookup) - An expansion hover module to expand information about CVE id using Vulners API. +* [Vysion Enrich](https://misp.github.io/misp-modules/expansion/#vysion-enrich) - Module to enrich the information by making use of the Vysion API. +* [Whois Lookup](https://misp.github.io/misp-modules/expansion/#whois-lookup) - Module to query a local instance of uwhois (https://github.com/rafiot/uwhoisd). +* [WhoisFreaks Lookup](https://misp.github.io/misp-modules/expansion/#whoisfreaks-lookup) - An expansion module for https://whoisfreaks.com/ that will provide an enriched analysis of the provided domain, including WHOIS and DNS information. +* [Wikidata Lookup](https://misp.github.io/misp-modules/expansion/#wikidata-lookup) - An expansion hover module to extract information from Wikidata to have additional information about particular term for analysis. +* [IBM X-Force Exchange Lookup](https://misp.github.io/misp-modules/expansion/#ibm-x-force-exchange-lookup) - An expansion module for IBM X-Force Exchange. +* [XLXS Enrich](https://misp.github.io/misp-modules/expansion/#xlxs-enrich) - Module to extract freetext from a .xlsx document. +* [YARA Rule Generator](https://misp.github.io/misp-modules/expansion/#yara-rule-generator) - jj +* [YARA Syntax Validator](https://misp.github.io/misp-modules/expansion/#yara-syntax-validator) - An expansion hover module to perform a syntax check on if yara rules are valid or not. +* [Yeti Lookup](https://misp.github.io/misp-modules/expansion/#yeti-lookup) - Module to process a query on Yeti. -* [Backscatter.io](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/backscatter_io.py) - a hover and expansion module to expand an IP address with mass-scanning observations. -* [BGP Ranking](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/bgpranking.py) - a hover and expansion module to expand an AS number with the ASN description, its history, and position in BGP Ranking. -* [BTC scam check](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_scam_check.py) - An expansion hover module to instantly check if a BTC address has been abused. -* [BTC transactions](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/btc_steroids.py) - An expansion hover module to get a blockchain balance and the transactions from a BTC address in MISP. -* [CIRCL Passive DNS](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivedns.py) - a hover and expansion module to expand hostname and IP addresses with passive DNS information. -* [CIRCL Passive SSL](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/circl_passivessl.py) - a hover and expansion module to expand IP addresses with the X.509 certificate seen. -* [countrycode](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/countrycode.py) - a hover module to tell you what country a URL belongs to. -* [CrowdStrike Falcon](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/crowdstrike_falcon.py) - an expansion module to expand using CrowdStrike Falcon Intel Indicator API. -* [CVE](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve.py) - a hover module to give more information about a vulnerability (CVE). -* [CVE advanced](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cve_advanced.py) - An expansion module to query the CIRCL CVE search API for more information about a vulnerability (CVE). -* [Cuckoo submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/cuckoo_submit.py) - A hover module to submit malware sample, url, attachment, domain to Cuckoo Sandbox. -* [DBL Spamhaus](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dbl_spamhaus.py) - a hover module to check Spamhaus DBL for a domain name. -* [DNS](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/dns.py) - a simple module to resolve MISP attributes like hostname and domain to expand IP addresses attributes. -* [docx-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/docx-enrich.py) - an enrichment module to get text out of Word document into MISP (using free-text parser). -* [DomainTools](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/domaintools.py) - a hover and expansion module to get information from [DomainTools](http://www.domaintools.com/) whois. -* [EUPI](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/eupi.py) - a hover and expansion module to get information about an URL from the [Phishing Initiative project](https://phishing-initiative.eu/?lang=en). -* [EQL](misp_modules/modules/expansion/eql.py) - an expansion module to generate event query language (EQL) from an attribute. [Event Query Language](https://eql.readthedocs.io/en/latest/) -* [Farsight DNSDB Passive DNS](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/farsight_passivedns.py) - a hover and expansion module to expand hostname and IP addresses with passive DNS information. -* [GeoIP](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/geoip_country.py) - a hover and expansion module to get GeoIP information from geolite/maxmind. -* [Greynoise](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/greynoise.py) - a hover to get information from greynoise. -* [hashdd](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashdd.py) - a hover module to check file hashes against [hashdd.com](http://www.hashdd.com) including NSLR dataset. -* [hibp](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hibp.py) - a hover module to lookup against Have I Been Pwned? -* [intel471](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intel471.py) - an expansion module to get info from [Intel471](https://intel471.com). -* [IPASN](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipasn.py) - a hover and expansion to get the BGP ASN of an IP address. -* [iprep](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/iprep.py) - an expansion module to get IP reputation from packetmail.net. -* [Joe Sandbox submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py) - Submit files and URLs to Joe Sandbox. -* [Joe Sandbox query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) - Query Joe Sandbox with the link of an analysis and get the parsed data. -* [macaddress.io](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macaddress_io.py) - a hover module to retrieve vendor details and other information regarding a given MAC address or an OUI from [MAC address Vendor Lookup](https://macaddress.io). See [integration tutorial here](https://macaddress.io/integrations/MISP-module). -* [macvendors](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/macvendors.py) - a hover module to retrieve mac vendor information. -* [ocr-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ocr-enrich.py) - an enrichment module to get OCRized data from images into MISP. -* [ods-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ods-enrich.py) - an enrichment module to get text out of OpenOffice spreadsheet document into MISP (using free-text parser). -* [odt-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/odt-enrich.py) - an enrichment module to get text out of OpenOffice document into MISP (using free-text parser). -* [onyphe](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe.py) - a modules to process queries on Onyphe. -* [onyphe_full](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/onyphe_full.py) - a modules to process full queries on Onyphe. -* [OTX](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/otx.py) - an expansion module for [OTX](https://otx.alienvault.com/). -* [passivetotal](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/passivetotal.py) - a [passivetotal](https://www.passivetotal.org/) module that queries a number of different PassiveTotal datasets. -* [pdf-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pdf-enrich.py) - an enrichment module to extract text from PDF into MISP (using free-text parser). -* [pptx-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/pptx-enrich.py) - an enrichment module to get text out of PowerPoint document into MISP (using free-text parser). -* [qrcode](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/qrcode.py) - a module decode QR code, barcode and similar codes from an image and enrich with the decoded values. -* [rbl](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/rbl.py) - a module to get RBL (Real-Time Blackhost List) values from an attribute. -* [reversedns](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/reversedns.py) - Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes. -* [securitytrails](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/securitytrails.py) - an expansion module for [securitytrails](https://securitytrails.com/). -* [shodan](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/shodan.py) - a minimal [shodan](https://www.shodan.io/) expansion module. -* [Sigma queries](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_queries.py) - Experimental expansion module querying a sigma rule to convert it into all the available SIEM signatures. -* [Sigma syntax validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sigma_syntax_validator.py) - Sigma syntax validator. -* [sourcecache](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/sourcecache.py) - a module to cache a specific link from a MISP instance. -* [STIX2 pattern syntax validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py) - a module to check a STIX2 pattern syntax. -* [ThreatCrowd](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatcrowd.py) - an expansion module for [ThreatCrowd](https://www.threatcrowd.org/). -* [threatminer](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/threatminer.py) - an expansion module to expand from [ThreatMiner](https://www.threatminer.org/). -* [urlhaus](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlhaus.py) - Query urlhaus to get additional data about a domain, hash, hostname, ip or url. -* [urlscan](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/urlscan.py) - an expansion module to query [urlscan.io](https://urlscan.io). -* [virustotal](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal.py) - an expansion module to query the [VirusTotal](https://www.virustotal.com/gui/home) API with a high request rate limit required. (More details about the API: [here](https://developers.virustotal.com/reference)) -* [virustotal_public](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal_public.py) - an expansion module to query the [VirusTotal](https://www.virustotal.com/gui/home) API with a public key and a low request rate limit. (More details about the API: [here](https://developers.virustotal.com/reference)) -* [VMray](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmray_submit.py) - a module to submit a sample to VMray. -* [VulnDB](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulndb.py) - a module to query [VulnDB](https://www.riskbasedsecurity.com/). -* [Vulners](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulners.py) - an expansion module to expand information about CVEs using Vulners API. -* [whois](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whois.py) - a module to query a local instance of [uwhois](https://github.com/rafiot/uwhoisd). -* [wikidata](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/wiki.py) - a [wikidata](https://www.wikidata.org) expansion module. -* [xforce](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xforceexchange.py) - an IBM X-Force Exchange expansion module. -* [xlsx-enrich](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xlsx-enrich.py) - an enrichment module to get text out of an Excel document into MISP (using free-text parser). -* [YARA query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_query.py) - a module to create YARA rules from single hash attributes. -* [YARA syntax validator](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/yara_syntax_validator.py) - YARA syntax validator. +### Export Modules +* [CEF Export](https://misp.github.io/misp-modules/export_mod/#cef-export) - Module to export a MISP event in CEF format. +* [Cisco fireSIGHT blockrule Export](https://misp.github.io/misp-modules/export_mod/#cisco-firesight-blockrule-export) - Module to export malicious network activity attributes to Cisco fireSIGHT manager block rules. +* [Microsoft Defender for Endpoint KQL Export](https://misp.github.io/misp-modules/export_mod/#microsoft-defender-for-endpoint-kql-export) - Defender for Endpoint KQL hunting query export module +* [GoAML Export](https://misp.github.io/misp-modules/export_mod/#goaml-export) - This module is used to export MISP events containing transaction objects into GoAML format. +* [Lite Export](https://misp.github.io/misp-modules/export_mod/#lite-export) - Lite export of a MISP event. +* [EQL Query Export](https://misp.github.io/misp-modules/export_mod/#eql-query-export) - Export MISP event in Event Query Language +* [Nexthink NXQL Export](https://misp.github.io/misp-modules/export_mod/#nexthink-nxql-export) - Nexthink NXQL query export module +* [OSQuery Export](https://misp.github.io/misp-modules/export_mod/#osquery-export) - OSQuery export of a MISP event. +* [Event to PDF Export](https://misp.github.io/misp-modules/export_mod/#event-to-pdf-export) - Simple export of a MISP event to PDF. +* [ThreatStream Export](https://misp.github.io/misp-modules/export_mod/#threatstream-export) - Module to export a structured CSV file for uploading to threatStream. +* [ThreadConnect Export](https://misp.github.io/misp-modules/export_mod/#threadconnect-export) - Module to export a structured CSV file for uploading to ThreatConnect. +* [VirusTotal Collections Export](https://misp.github.io/misp-modules/export_mod/#virustotal-collections-export) - Creates a VT Collection from an event iocs. +* [VirusTotal Graph Export](https://misp.github.io/misp-modules/export_mod/#virustotal-graph-export) - This module is used to create a VirusTotal Graph from a MISP event. +* [YARA Rule Export](https://misp.github.io/misp-modules/export_mod/#yara-rule-export) - This module is used to export MISP events to YARA. -### Export modules +### Import Modules +* [PDNS COF Importer](https://misp.github.io/misp-modules/import_mod/#pdns-cof-importer) - Passive DNS Common Output Format (COF) MISP importer +* [CSV Import](https://misp.github.io/misp-modules/import_mod/#csv-import) - Module to import MISP attributes from a csv file. +* [Cuckoo Sandbox Import](https://misp.github.io/misp-modules/import_mod/#cuckoo-sandbox-import) - Module to import Cuckoo JSON. +* [Email Import](https://misp.github.io/misp-modules/import_mod/#email-import) - Email import module for MISP +* [GoAML Import](https://misp.github.io/misp-modules/import_mod/#goaml-import) - Module to import MISP objects about financial transactions from GoAML files. +* [Import Blueprint](https://misp.github.io/misp-modules/import_mod/#import-blueprint) - Generic blueprint to be copy-pasted to quickly boostrap creation of import module. +* [Joe Sandbox Import](https://misp.github.io/misp-modules/import_mod/#joe-sandbox-import) - A module to import data from a Joe Sandbox analysis json report. +* [Lastline Import](https://misp.github.io/misp-modules/import_mod/#lastline-import) - Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module. Module to import and parse reports from Lastline analysis links. +* [MISP JSON Import](https://misp.github.io/misp-modules/import_mod/#misp-json-import) - Module to import MISP JSON format for merging MISP events. +* [OCR Import](https://misp.github.io/misp-modules/import_mod/#ocr-import) - Optical Character Recognition (OCR) module for MISP. +* [OpenIOC Import](https://misp.github.io/misp-modules/import_mod/#openioc-import) - Module to import OpenIOC packages. +* [TAXII 2.1 Import](https://misp.github.io/misp-modules/import_mod/#taxii-2.1-import) - Import content from a TAXII 2.1 server +* [ThreadAnalyzer Sandbox Import](https://misp.github.io/misp-modules/import_mod/#threadanalyzer-sandbox-import) - Module to import ThreatAnalyzer archive.zip / analysis.json files. +* [URL Import](https://misp.github.io/misp-modules/import_mod/#url-import) - Simple URL import tool with Faup +* [VMRay API Import](https://misp.github.io/misp-modules/import_mod/#vmray-api-import) - Module to import VMRay (VTI) results. +* [VMRay Summary JSON Import](https://misp.github.io/misp-modules/import_mod/#vmray-summary-json-import) - Import a VMRay Summary JSON report. -* [CEF](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cef_export.py) module to export Common Event Format (CEF). -* [Cisco FireSight Manager ACL rule](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py) module to export as rule for the Cisco FireSight manager ACL. -* [GoAML export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/goamlexport.py) module to export in [GoAML format](http://goaml.unodc.org/goaml/en/index.html). -* [Lite Export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/liteexport.py) module to export a lite event. -* [Mass EQL Export](misp_modules/modules/export_mod/mass_eql_export.py) module to export applicable attributes from an event to a mass EQL query. -* [PDF export](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/pdfexport.py) module to export an event in PDF. -* [Nexthink query format](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/nexthinkexport.py) module to export in Nexthink query format. -* [osquery](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/osqueryexport.py) module to export in [osquery](https://osquery.io/) query format. -* [ThreatConnect](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threat_connect_export.py) module to export in ThreatConnect CSV format. -* [ThreatStream](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/export_mod/threatStream_misp_export.py) module to export in ThreatStream format. - -### Import modules - -* [CSV import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/csvimport.py) Customizable CSV import module. -* [Cuckoo JSON](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/cuckooimport.py) Cuckoo JSON import. -* [Email Import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/email_import.py) Email import module for MISP to import basic metadata. -* [GoAML import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/goamlimport.py) Module to import [GoAML](http://goaml.unodc.org/goaml/en/index.html) XML format. -* [Joe Sandbox import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/joe_import.py) Parse data from a Joe Sandbox json report. -* [OCR](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/ocr.py) Optical Character Recognition (OCR) module for MISP to import attributes from images, scan or faxes. -* [OpenIOC](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/openiocimport.py) OpenIOC import based on PyMISP library. -* [ThreatAnalyzer](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/threatanalyzer_import.py) - An import module to process ThreatAnalyzer archive.zip/analysis.json sandbox exports. -* [VMRay](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/vmray_import.py) - An import module to process VMRay export. +### Action Modules +* [Mattermost](https://misp.github.io/misp-modules/action_mod/#mattermost) - Simplistic module to send message to a Mattermost channel. +* [Slack](https://misp.github.io/misp-modules/action_mod/#slack) - Simplistic module to send messages to a Slack channel. +* [Test action](https://misp.github.io/misp-modules/action_mod/#test-action) - This module is merely a test, always returning true. Triggers on event publishing. ## How to contribute your own module? @@ -115,6 +173,4 @@ For further information please see [Contribute](contribute/). ## Licenses -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%MISP%2Fmisp-modules.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FMISP%2Fmisp-modules?ref=badge_large) - For further Information see also the [license file](license/). diff --git a/documentation/mkdocs/install.md b/documentation/mkdocs/install.md index 3eed0f49..e38c0769 100644 --- a/documentation/mkdocs/install.md +++ b/documentation/mkdocs/install.md @@ -1,192 +1,177 @@ -## How to install and start MISP modules (in a Python virtualenv)? +## Install from pip + +It is strongly recommended to use a virtual environment (see here for instructions https://docs.python.org/3/tutorial/venv.html). + +Once the virtual environment is loaded just use the command: ~~~~bash -SUDO_WWW="sudo -u www-data" - -sudo apt-get install -y \ - git \ - libpq5 \ - libjpeg-dev \ - tesseract-ocr \ - libpoppler-cpp-dev \ - imagemagick virtualenv \ - libopencv-dev \ - zbar-tools \ - libzbar0 \ - libzbar-dev \ - libfuzzy-dev \ - libcaca-dev - -# BEGIN with virtualenv: -$SUDO_WWW virtualenv -p python3 /var/www/MISP/venv -# END with virtualenv - -cd /usr/local/src/ -# Ideally you add your user to the staff group and make /usr/local/src group writeable, below follows an example with user misp -sudo adduser misp staff -sudo chmod 2775 /usr/local/src -sudo chown root:staff /usr/local/src -git clone https://github.com/MISP/misp-modules.git -git clone git://github.com/stricaud/faup.git faup -git clone git://github.com/stricaud/gtcaca.git gtcaca - -# Install gtcaca/faup -cd gtcaca -mkdir -p build -cd build -cmake .. && make -sudo make install -cd ../../faup -mkdir -p build -cd build -cmake .. && make -sudo make install -sudo ldconfig - -cd ../../misp-modules - -# BEGIN with virtualenv: -$SUDO_WWW /var/www/MISP/venv/bin/pip install -I -r REQUIREMENTS -$SUDO_WWW /var/www/MISP/venv/bin/pip install . -# END with virtualenv - -# BEGIN without virtualenv: -sudo pip install -I -r REQUIREMENTS -sudo pip install . -# END without virtualenv - -# Start misp-modules as a service -sudo cp etc/systemd/system/misp-modules.service /etc/systemd/system/ -sudo systemctl daemon-reload -sudo systemctl enable --now misp-modules -/var/www/MISP/venv/bin/misp-modules -l 127.0.0.1 -s & #to start the modules +pip install misp-modules ~~~~ -## How to install and start MISP modules on RHEL-based distributions ? +Note that the dependencies will require a number of system packages installed. On Ubuntu these packages are `libpoppler-cpp-dev`, `libzbar0`, and `tesseract-ocr`. For an updated list, check the github action used to test the build inside `.github/workflows`. -As of this writing, the official RHEL repositories only contain Ruby 2.0.0 and Ruby 2.1 or higher is required. As such, this guide installs Ruby 2.2 from the SCL repository. +Because PyPI does not support git for direct dependencies, the following packages will not be installed by default `otdreader`, `google-search-api`, `trustar`, `pydnstrails`, `pyonyphe`. You can either install them manually or let the modules depending on them gracefully fail. ~~~~bash -SUDO_WWW="sudo -u apache" -sudo yum install \ - rh-ruby22 \ - openjpeg-devel \ - rubygem-rouge \ - rubygem-asciidoctor \ - zbar-devel \ - opencv-devel \ - gcc-c++ \ - pkgconfig \ - poppler-cpp-devel \ - python-devel \ - redhat-rpm-config -cd /usr/local/src/ -sudo git clone https://github.com/MISP/misp-modules.git -cd misp-modules -$SUDO_WWW /usr/bin/scl enable rh-python36 "virtualenv -p python3 /var/www/MISP/venv" -$SUDO_WWW /var/www/MISP/venv/bin/pip install -U -I -r REQUIREMENTS -$SUDO_WWW /var/www/MISP/venv/bin/pip install -U . +pip install \ + git+https://github.com/cartertemm/ODTReader.git \ + git+https://github.com/abenassi/Google-Search-API \ + git+https://github.com/SteveClement/trustar-python.git \ + git+https://github.com/sebdraven/pydnstrails.git \ + git+https://github.com/sebdraven/pyonyphe.git ~~~~ -Create the service file /etc/systemd/system/misp-modules.service : +You can now run `misp-modules` by invoking it (you might need to reload the virtual environment to update the search path used for executables). ~~~~bash -echo "[Unit] -Description=MISP's modules -After=misp-workers.service +misp-modules +~~~~ + + +## Install from cloned repository + +In this case the only requirement is to install `poetry`. Normally you just need to run `pip install poetry`, but see here for more alternatives https://python-poetry.org/docs/#installation. + +Once `poetry` is installed, you can clone the repository and install `misp-modules` as follows: + +~~~~bash +git clone https://github.com/MISP/misp-modules.git && cd misp-modules +git submodule update --init +poetry install --with unstable +~~~~ + +The switch `--with unstable` will also install dependencies available only on `git` repositories (which are manually installed when using pip). + +Note that the dependencies will require a number of system packages installed. On Ubuntu these packages are `libpoppler-cpp-dev`, `libzbar0`, and `tesseract-ocr`. For an updated list, check the github action used to test the build inside `.github/workflows`. + + +## Install the systemd unit + +To run `misp-modules` as a service on a distribution based on systemd, you need to create the unit as follows and store it in a file `/etc/systemd/system/misp-modules.service`: + +~~~~bash +[Unit] +Description=MISP modules [Service] Type=simple User=apache Group=apache -ExecStart=/usr/bin/scl enable rh-python36 rh-ruby22 '/var/www/MISP/venv/bin/misp-modules –l 127.0.0.1 –s' +ExecStart=/path/to/venv/bin/misp-modules -l 127.0.0.1 -s Restart=always RestartSec=10 [Install] -WantedBy=multi-user.target" | sudo tee /etc/systemd/system/misp-modules.service +WantedBy=multi-user.target ~~~~ -The After=misp-workers.service must be changed or removed if you have not created a misp-workers service. Then, enable the misp-modules service and start it: - +Then, enable the misp-modules service and start it: ~~~~bash systemctl daemon-reload systemctl enable --now misp-modules ~~~~ -## How to use an MISP modules Docker container -### Docker build +## Run the tests + +To run tests you need to install misp-modules from the cloned repository, run the server, and then run the tests. You can do all these step with `poetry`. ~~~~bash -docker build -t misp-modules \ - --build-arg BUILD_DATE=$(date -u +"%Y-%m-%d") \ - docker/ +poetry install --with unstable +poetry run misp-modules ~~~~ -### Docker run +And in another terminal: ~~~~bash -# Start Redis -docker run --rm -d --name=misp-redis redis:alpine -# Start MISP-modules -docker run \ - --rm -d --name=misp-modules \ - -e REDIS_BACKEND=misp-redis \ - -e REDIS_PORT="6379" \ - -e REDIS_PW="" \ - -e REDIS_DATABASE="245" \ - -e MISP_MODULES_DEBUG="false" \ - dcso/misp-dockerized-misp-modules +poetry run pytest ~~~~ -### Docker-compose -~~~~yml -services: - misp-modules: - # https://hub.docker.com/r/dcso/misp-dockerized-misp-modules - image: dcso/misp-dockerized-misp-modules:3 - - # Local image: - #image: misp-modules - #build: - # context: docker/ - - environment: - # Redis - REDIS_BACKEND: misp-redis - REDIS_PORT: "6379" - REDIS_DATABASE: "245" - # System PROXY (OPTIONAL) - http_proxy: - https_proxy: - no_proxy: 0.0.0.0 - # Timezone (OPTIONAL) - TZ: Europe/Berlin - # MISP-Modules (OPTIONAL) - MISP_MODULES_DEBUG: "false" - # Logging options (OPTIONAL) - LOG_SYSLOG_ENABLED: "no" - misp-redis: - # https://hub.docker.com/_/redis or alternative https://hub.docker.com/r/dcso/misp-dockerized-redis/ - image: redis:alpine +## Build the documentation + +To build the documentation you can use the provided `Makefile`. +Inside you will find three targets: + +- `generate_docs`: install the depdendency and generate the documentation. + +- `generate_docs`: build the documentation using `mkdocs`. + +- `deploy`: deploy the documentation using `mkdocs gh-deploy`. + +- `test-docs`: run a local server exposing the newly built documentation. + +Note: you can either run the targets using `poetry` (default), or using the Docker image `squidfunk/mkdocs-material` by setting the environment variable `USE_DOCKER=true`. + + +## Run MISP modules + +If you installed it using pip, you just need to execute the command `misp-modules` (source the virtual environment a second time to update the search paths). If you installed it from the cloned repository, just use poetry, i.e., `poetry run misp-modules`. + + +## Run MISP modules in Docker + +You can find an up-to-date container image and related documentation at the following repository: https://github.com/MISP/misp-docker . + + +## Install misp-module on an offline instance + +### If `misp-modules` is available on PyPI + +Once `misp-modules` is available on PyPI, you can just download all the necessary packages: + +~~~~bash +mkdir wheels +pip wheel misp-modules --no-cache-dir -w ./wheels ~~~~ -## Install misp-module on an offline instance. -First, you need to grab all necessary packages for example like this : +Move the `wheels` directory to the target system, and install them there: + +~~~~bash +pip install --no-cache-dir --use-deprecated=legacy-resolver /wheels/*.whl +~~~~ + +Once again, using a virtual environment is recommended. + +### If `misp-modules` is not available on PyPI + +You have two choices, the first approach uses `poetry export` to export the entire virtual environment so you can copy and run it on the target system; the second one uses `poetry bundle` to export a `requirements.txt` file. + +#### Using `poetry bundle` + +This is quite straightforward but it assumes your target system is relatively similar (same distribution, architecture, libaries). + +~~~~bash +poetry install --with unstable +poetry self add poetry-plugin-bundle +poetry bundle venv /destination/path/ +~~~~ + +#### Using `poetry export` + +This is a bit more convoluted and it is similar to how you would install `misp-modules` on an offline instance. + +Just follow those instructions but replace the package `misp-modules` with `-r requirements.txt`. + +Before doing so you need to generate the `requirements.txt` file. Due to the fact we are still supporting Python 3.8 and that Poetry still has some limitations (soon to be resolved) you need to need to replace the line `python = ">=3.8.*,<3.13"` inside `pyproject.toml` with your exact version (just run `python --version`). + +The following `sed` command does everything for you. + +~~~~bash +sed -i "s/^python = .*/python = \"$(python -c 'import platform; print(platform.python_version())')\"/" pyproject.toml +~~~~ + +Then, run the following commands to generate your very own `requirements.txt`. + +~~~~bash +poetry lock +poetry self add poetry-plugin-export +poetry export --with unstable --without-hashes -f requirements.txt -o requirements.txt +~~~~ + +Note that `misp-modules` will not be part of the `requirements.txt` file and you will need to create the wheel yourself: + +~~~~bash +poetry build --output ./wheels +~~~~ -Use pip wheel to create an archive -~~~ -mkdir misp-modules-offline -pip3 wheel -r REQUIREMENTS shodan --wheel-dir=./misp-modules-offline -tar -cjvf misp-module-bundeled.tar.bz2 ./misp-modules-offline/* -~~~ -On offline machine : -~~~ -mkdir misp-modules-bundle -tar xvf misp-module-bundeled.tar.bz2 -C misp-modules-bundle -cd misp-modules-bundle -ls -1|while read line; do sudo pip3 install --force-reinstall --ignore-installed --upgrade --no-index --no-deps ${line};done -~~~ -Next you can follow standard install procedure. diff --git a/documentation/website/expansion/apiosintds.json b/documentation/website/expansion/apiosintds.json deleted file mode 100644 index 8bdaf395..00000000 --- a/documentation/website/expansion/apiosintds.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "On demand query API for OSINT.digitalside.it project.", - "requirements": [ - "The apiosintDS python library to query the OSINT.digitalside.it API." - ], - "input": "A domain, ip, url or hash attribute.", - "output": "Hashes and urls resulting from the query to OSINT.digitalside.it", - "references": [ - "https://osint.digitalside.it/#About" - ], - "features": "The module simply queries the API of OSINT.digitalside.it with a domain, ip, url or hash attribute.\n\nThe result of the query is then parsed to extract additional hashes or urls. A module parameters also allows to parse the hashes related to the urls.\n\nFurthermore, it is possible to cache the urls and hashes collected over the last 7 days by OSINT.digitalside.it" -} \ No newline at end of file diff --git a/documentation/website/expansion/apivoid.json b/documentation/website/expansion/apivoid.json deleted file mode 100644 index 5962f578..00000000 --- a/documentation/website/expansion/apivoid.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to query APIVoid with some domain attributes.", - "logo": "apivoid.png", - "requirements": [ - "A valid APIVoid API key with enough credits to proceed 2 queries" - ], - "input": "A domain attribute.", - "output": "DNS records and SSL certificates related to the domain.", - "features": "This module takes a domain name and queries API Void to get the related DNS records and the SSL certificates. It returns then those pieces of data as MISP objects that can be added to the event.\n\nTo make it work, a valid API key and enough credits to proceed 2 queries (0.06 + 0.07 credits) are required.", - "references": [ - "https://www.apivoid.com/" - ] -} \ No newline at end of file diff --git a/documentation/website/expansion/assemblyline_query.json b/documentation/website/expansion/assemblyline_query.json deleted file mode 100644 index a0b38359..00000000 --- a/documentation/website/expansion/assemblyline_query.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "A module tu query the AssemblyLine API with a submission ID to get the submission report and parse it.", - "logo": "assemblyline.png", - "requirements": [ - "assemblyline_client: Python library to query the AssemblyLine rest API." - ], - "input": "Link of an AssemblyLine submission report.", - "output": "MISP attributes & objects parsed from the AssemblyLine submission.", - "references": [ - "https://www.cyber.gc.ca/en/assemblyline" - ], - "features": "The module requires the address of the AssemblyLine server you want to query as well as your credentials used for this instance. Credentials include the used-ID and an API key or the password associated to the user-ID.\n\nThe submission ID extracted from the submission link is then used to query AssemblyLine and get the full submission report. This report is parsed to extract file objects and the associated IPs, domains or URLs the files are connecting to.\n\nSome more data may be parsed in the future." -} diff --git a/documentation/website/expansion/assemblyline_submit.json b/documentation/website/expansion/assemblyline_submit.json deleted file mode 100644 index 8f147ca5..00000000 --- a/documentation/website/expansion/assemblyline_submit.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "A module to submit samples and URLs to AssemblyLine for advanced analysis, and return the link of the submission.", - "logo": "assemblyline.png", - "requirements": [ - "assemblyline_client: Python library to query the AssemblyLine rest API." - ], - "input": "Sample, or url to submit to AssemblyLine.", - "output": "Link of the report generated in AssemblyLine.", - "references": [ - "https://www.cyber.gc.ca/en/assemblyline" - ], - "features": "The module requires the address of the AssemblyLine server you want to query as well as your credentials used for this instance. Credentials include the user-ID and an API key or the password associated to the user-ID.\n\nIf the sample or url is correctly submitted, you get then the link of the submission." -} \ No newline at end of file diff --git a/documentation/website/expansion/backscatter_io.json b/documentation/website/expansion/backscatter_io.json deleted file mode 100644 index 146e41c2..00000000 --- a/documentation/website/expansion/backscatter_io.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Query backscatter.io (https://backscatter.io/).", - "requirements": [ - "backscatter python library" - ], - "features": "The module takes a source or destination IP address as input and displays the information known by backscatter.io.", - "logo": "backscatter_io.png", - "references": [ - "https://pypi.org/project/backscatter/" - ], - "input": "IP addresses.", - "output": "Text containing a history of the IP addresses especially on scanning based on backscatter.io information ." -} diff --git a/documentation/website/expansion/bgpranking.json b/documentation/website/expansion/bgpranking.json deleted file mode 100644 index 5b0383e5..00000000 --- a/documentation/website/expansion/bgpranking.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Query BGP Ranking (https://bgpranking-ng.circl.lu/).", - "requirements": [ - "pybgpranking python library" - ], - "features": "The module takes an AS number attribute as input and displays its description as well as its ranking position in BGP Ranking for a given day.", - "references": [ - "https://github.com/D4-project/BGP-Ranking/" - ], - "input": "Autonomous system number.", - "output": "An asn object with its related bgp-ranking object." -} diff --git a/documentation/website/expansion/btc_scam_check.json b/documentation/website/expansion/btc_scam_check.json deleted file mode 100644 index 01fe8ff4..00000000 --- a/documentation/website/expansion/btc_scam_check.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion hover module to query a special dns blacklist to check if a bitcoin address has been abused.", - "requirements": [ - "dnspython3: dns python library" - ], - "features": "The module queries a dns blacklist directly with the bitcoin address and get a response if the address has been abused.", - "logo": "bitcoin.png", - "input": "btc address attribute.", - "output": "Text to indicate if the BTC address has been abused.", - "references": [ - "https://btcblack.it/" - ] -} \ No newline at end of file diff --git a/documentation/website/expansion/btc_steroids.json b/documentation/website/expansion/btc_steroids.json deleted file mode 100644 index b365d44c..00000000 --- a/documentation/website/expansion/btc_steroids.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "description": "An expansion hover module to get a blockchain balance from a BTC address in MISP.", - "logo": "bitcoin.png", - "input": "btc address attribute.", - "output": "Text to describe the blockchain balance and the transactions related to the btc address in input." -} \ No newline at end of file diff --git a/documentation/website/expansion/censys_enrich.json b/documentation/website/expansion/censys_enrich.json deleted file mode 100644 index 9f3a6f0f..00000000 --- a/documentation/website/expansion/censys_enrich.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "An expansion module to enrich attributes in MISP by quering the censys.io API", - "requirements": [ - "API credentials to censys.io" - ], - "input": "IP, domain or certificate fingerprint (md5, sha1 or sha256)", - "output": "MISP objects retrieved from censys, including open ports, ASN, Location of the IP, x509 details", - "references": [ - "https://www.censys.io" - ], - "features": "This module takes an IP, hostname or a certificate fingerprint and attempts to enrich it by querying the Censys API." -} \ No newline at end of file diff --git a/documentation/website/expansion/circl_passivedns.json b/documentation/website/expansion/circl_passivedns.json deleted file mode 100644 index b50136b3..00000000 --- a/documentation/website/expansion/circl_passivedns.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "description": "Module to access CIRCL Passive DNS.", - "logo": "passivedns.png", - "requirements": [ - "pypdns: Passive DNS python library", - "A CIRCL passive DNS account with username & password" - ], - "input": "Hostname, domain, or ip-address attribute.", - "ouput": "Passive DNS objects related to the input attribute.", - "features": "This module takes a hostname, domain or ip-address (ip-src or ip-dst) attribute as input, and queries the CIRCL Passive DNS REST API to get the asssociated passive dns entries and return them as MISP objects.\n\nTo make it work a username and a password are thus required to authenticate to the CIRCL Passive DNS API.", - "references": [ - "https://www.circl.lu/services/passive-dns/", - "https://datatracker.ietf.org/doc/draft-dulaunoy-dnsop-passive-dns-cof/" - ] -} \ No newline at end of file diff --git a/documentation/website/expansion/circl_passivessl.json b/documentation/website/expansion/circl_passivessl.json deleted file mode 100644 index 4010297a..00000000 --- a/documentation/website/expansion/circl_passivessl.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Modules to access CIRCL Passive SSL.", - "logo": "passivessl.png", - "requirements": [ - "pypssl: Passive SSL python library", - "A CIRCL passive SSL account with username & password" - ], - "input": "IP address attribute.", - "output": "x509 certificate objects seen by the IP address(es).", - "features": "This module takes an ip-address (ip-src or ip-dst) attribute as input, and queries the CIRCL Passive SSL REST API to gather the related certificates and return the corresponding MISP objects.\n\nTo make it work a username and a password are required to authenticate to the CIRCL Passive SSL API.", - "references": [ - "https://www.circl.lu/services/passive-ssl/" - ] -} \ No newline at end of file diff --git a/documentation/website/expansion/cluster25_expand.json b/documentation/website/expansion/cluster25_expand.json deleted file mode 100644 index d41c2125..00000000 --- a/documentation/website/expansion/cluster25_expand.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Module to query Cluster25 CTI.", - "logo": "cluster25.png", - "requirements": [ - "A Cluster25 API access (API id & key)" - ], - "input": "An Indicator value of type included in the following list:\n- domain\n- email-src\n- email-dst\n- filename\n- md5\n- sha1\n- sha256\n- ip-src\n- ip-dst\n- url\n- vulnerability\n- btc\n- xmr\n ja3-fingerprint-md5", - "output": "A series of c25 MISP Objects with colletion of attributes mapped from Cluster25 CTI query result.", - "references": [ - "" - ], - "features": "This module takes a MISP attribute value as input to query the Cluster25CTI API. The result is then mapped into compatible MISP Objects and relative attributes.\n" -} - diff --git a/documentation/website/expansion/countrycode.json b/documentation/website/expansion/countrycode.json deleted file mode 100644 index 110bdf78..00000000 --- a/documentation/website/expansion/countrycode.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "description": "Module to expand country codes.", - "input": "Hostname or domain attribute.", - "output": "Text with the country code the input belongs to.", - "features": "The module takes a domain or a hostname as input, and returns the country it belongs to.\n\nFor non country domains, a list of the most common possible extensions is used." -} \ No newline at end of file diff --git a/documentation/website/expansion/cpe.json b/documentation/website/expansion/cpe.json deleted file mode 100644 index 0160d1c0..00000000 --- a/documentation/website/expansion/cpe.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "An expansion module to query the CVE search API with a cpe code to get its related vulnerabilities.", - "logo": "cve.png", - "input": "CPE attribute.", - "output": "The vulnerabilities related to the CPE.", - "references": [ - "https://cve.circl.lu/api/" - ], - "features": "The module takes a cpe attribute as input and queries the CVE search API to get its related vulnerabilities. \nThe list of vulnerabilities is then parsed and returned as vulnerability objects.\n\nUsers can use their own CVE search API url by defining a value to the custom_API_URL parameter. If no custom API url is given, the default cve.circl.lu api url is used.\n\nIn order to limit the amount of data returned by CVE serach, users can also the limit parameter. With the limit set, the API returns only the requested number of vulnerabilities, sorted from the highest cvss score to the lowest one." -} \ No newline at end of file diff --git a/documentation/website/expansion/crowdsec.json b/documentation/website/expansion/crowdsec.json deleted file mode 100644 index 750caae1..00000000 --- a/documentation/website/expansion/crowdsec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "description": "Hover module to lookup an IP in CrowdSec's CTI", - "logo": "crowdsec.png", - "requirements": [ - "A CrowdSec CTI API key. Get yours by following https://docs.crowdsec.net/docs/cti_api/getting_started/#getting-an-api-key" - ], - "input": "An IP address.", - "output": "IP Lookup information from CrowdSec CTI API", - "references": [ - "https://www.crowdsec.net/", - "https://docs.crowdsec.net/docs/cti_api/getting_started", - "https://app.crowdsec.net/" - ], - "features": "This module enables IP lookup from CrowdSec CTI API. It provides information about the IP, such as what kind of attacks it has been participant of as seen by CrowdSec's network. It also includes enrichment by CrowdSec like background noise score, aggressivity over time etc." -} \ No newline at end of file diff --git a/documentation/website/expansion/crowdstrike_falcon.json b/documentation/website/expansion/crowdstrike_falcon.json deleted file mode 100644 index a2408b91..00000000 --- a/documentation/website/expansion/crowdstrike_falcon.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to query Crowdstrike Falcon.", - "logo": "crowdstrike.png", - "requirements": [ - "A CrowdStrike API access (API id & key)" - ], - "input": "A MISP attribute included in the following list:\n- domain\n- email-attachment\n- email-dst\n- email-reply-to\n- email-src\n- email-subject\n- filename\n- hostname\n- ip-src\n- ip-dst\n- md5\n- mutex\n- regkey\n- sha1\n- sha256\n- uri\n- url\n- user-agent\n- whois-registrant-email\n- x509-fingerprint-md5", - "output": "MISP attributes mapped after the CrowdStrike API has been queried, included in the following list:\n- hostname\n- email-src\n- email-subject\n- filename\n- md5\n- sha1\n- sha256\n- ip-dst\n- ip-dst\n- mutex\n- regkey\n- url\n- user-agent\n- x509-fingerprint-md5", - "references": [ - "https://www.crowdstrike.com/products/crowdstrike-falcon-faq/" - ], - "features": "This module takes a MISP attribute as input to query a CrowdStrike Falcon API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes.\n\nPlease note that composite attributes composed by at least one of the input types mentionned below (domains, IPs, hostnames) are also supported." -} \ No newline at end of file diff --git a/documentation/website/expansion/cuckoo_submit.json b/documentation/website/expansion/cuckoo_submit.json deleted file mode 100644 index 5c232184..00000000 --- a/documentation/website/expansion/cuckoo_submit.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "An expansion module to submit files and URLs to Cuckoo Sandbox.", - "logo": "cuckoo.png", - "requirements": [ - "Access to a Cuckoo Sandbox API and an API key if the API requires it. (api_url and api_key)" - ], - "input": "A malware-sample or attachment for files. A url or domain for URLs.", - "output": "A text field containing 'Cuckoo task id: '", - "references": [ - "https://cuckoosandbox.org/", - "https://cuckoo.sh/docs/" - ], - "features": "The module takes a malware-sample, attachment, url or domain and submits it to Cuckoo Sandbox.\n The returned task id can be used to retrieve results when the analysis completed." -} \ No newline at end of file diff --git a/documentation/website/expansion/cve.json b/documentation/website/expansion/cve.json deleted file mode 100644 index 04f5733f..00000000 --- a/documentation/website/expansion/cve.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "An expansion hover module to expand information about CVE id.", - "logo": "cve.png", - "input": "Vulnerability attribute.", - "output": "Text giving information about the CVE related to the Vulnerability.", - "references": [ - "https://cve.circl.lu/", - "https://cve.mitre.org/" - ], - "features": "The module takes a vulnerability attribute as input and queries the CIRCL CVE search API to get information about the vulnerability as it is described in the list of CVEs." -} \ No newline at end of file diff --git a/documentation/website/expansion/cve_advanced.json b/documentation/website/expansion/cve_advanced.json deleted file mode 100644 index 364fb322..00000000 --- a/documentation/website/expansion/cve_advanced.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "An expansion module to query the CIRCL CVE search API for more information about a vulnerability (CVE).", - "logo": "cve.png", - "input": "Vulnerability attribute.", - "output": "Additional information about the vulnerability, such as its cvss score, some references, or the related weaknesses and attack patterns.", - "references": [ - "https://cve.circl.lu", - "https://cve/mitre.org/" - ], - "features": "The module takes a vulnerability attribute as input and queries the CIRCL CVE search API to gather additional information.\n\nThe result of the query is then parsed to return additional information about the vulnerability, like its cvss score or some references, as well as the potential related weaknesses and attack patterns.\n\nThe vulnerability additional data is returned in a vulnerability MISP object, and the related additional information are put into weakness and attack-pattern MISP objects." -} \ No newline at end of file diff --git a/documentation/website/expansion/cytomic_orion.json b/documentation/website/expansion/cytomic_orion.json deleted file mode 100644 index 8623670e..00000000 --- a/documentation/website/expansion/cytomic_orion.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "An expansion module to enrich attributes in MISP by quering the Cytomic Orion API", - "logo": "cytomic_orion.png", - "requirements": [ - "Access (license) to Cytomic Orion" - ], - "input": "MD5, hash of the sample / malware to search for.", - "output": "MISP objects with sightings of the hash in Cytomic Orion. Includes files and machines.", - "references": [ - "https://www.vanimpe.eu/2020/03/10/integrating-misp-and-cytomic-orion/", - "https://www.cytomicmodel.com/solutions/" - ], - "features": "This module takes an MD5 hash and searches for occurrences of this hash in the Cytomic Orion database. Returns observed files and machines." -} \ No newline at end of file diff --git a/documentation/website/expansion/dbl_spamhaus.json b/documentation/website/expansion/dbl_spamhaus.json deleted file mode 100644 index 6a33c8e8..00000000 --- a/documentation/website/expansion/dbl_spamhaus.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to check Spamhaus DBL for a domain name.", - "logo": "spamhaus.jpg", - "requirements": [ - "dnspython3: DNS python3 library" - ], - "input": "Domain or hostname attribute.", - "output": "Information about the nature of the input.", - "references": [ - "https://www.spamhaus.org/faq/section/Spamhaus%20DBL" - ], - "features": "This modules takes a domain or a hostname in input and queries the Domain Block List provided by Spamhaus to determine what kind of domain it is.\n\nDBL then returns a response code corresponding to a certain classification of the domain we display. If the queried domain is not in the list, it is also mentionned.\n\nPlease note that composite MISP attributes containing domain or hostname are supported as well." -} \ No newline at end of file diff --git a/documentation/website/expansion/dns.json b/documentation/website/expansion/dns.json deleted file mode 100644 index a0fb4ddb..00000000 --- a/documentation/website/expansion/dns.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "description": "A simple DNS expansion service to resolve IP address from domain MISP attributes.", - "requirements": [ - "dnspython3: DNS python3 library" - ], - "input": "Domain or hostname attribute.", - "output": "IP address resolving the input.", - "features": "The module takes a domain of hostname attribute as input, and tries to resolve it. If no error is encountered, the IP address that resolves the domain is returned, otherwise the origin of the error is displayed.\n\nThe address of the DNS resolver to use is also configurable, but if no configuration is set, we use the Google public DNS address (8.8.8.8).\n\nPlease note that composite MISP attributes containing domain or hostname are supported as well." -} \ No newline at end of file diff --git a/documentation/website/expansion/docx_enrich.json b/documentation/website/expansion/docx_enrich.json deleted file mode 100644 index 55bd9554..00000000 --- a/documentation/website/expansion/docx_enrich.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Module to extract freetext from a .docx document.", - "logo": "docx.png", - "requirements": [ - "docx python library" - ], - "input": "Attachment attribute containing a .docx document.", - "output": "Text and freetext parsed from the document.", - "references": [], - "features": "The module reads the text contained in a .docx document. The result is passed to the freetext import parser so IoCs can be extracted out of it." -} \ No newline at end of file diff --git a/documentation/website/expansion/domaintools.json b/documentation/website/expansion/domaintools.json deleted file mode 100644 index 99c916b6..00000000 --- a/documentation/website/expansion/domaintools.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "DomainTools MISP expansion module.", - "logo": "domaintools.png", - "requirements": [ - "Domaintools python library", - "A Domaintools API access (username & apikey)" - ], - "input": "A MISP attribute included in the following list:\n- domain\n- hostname\n- email-src\n- email-dst\n- target-email\n- whois-registrant-email\n- whois-registrant-name\n- whois-registrant-phone\n- ip-src\n- ip-dst", - "output": "MISP attributes mapped after the Domaintools API has been queried, included in the following list:\n- whois-registrant-email\n- whois-registrant-phone\n- whois-registrant-name\n- whois-registrar\n- whois-creation-date\n- text\n- domain", - "references": [ - "https://www.domaintools.com/" - ], - "features": "This module takes a MISP attribute as input to query the Domaintools API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes.\n\nPlease note that composite attributes composed by at least one of the input types mentionned below (domains, IPs, hostnames) are also supported." -} \ No newline at end of file diff --git a/documentation/website/expansion/eql.json b/documentation/website/expansion/eql.json deleted file mode 100644 index 4af9df41..00000000 --- a/documentation/website/expansion/eql.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "EQL query generation for a MISP attribute.", - "logo": "eql.png", - "requirements": [], - "input": "A filename or ip attribute.", - "output": "Attribute containing EQL for a network or file attribute.", - "references": [ - "https://eql.readthedocs.io/en/latest/" - ], - "features": "This module adds a new attribute to a MISP event containing an EQL query for a network or file attribute." -} \ No newline at end of file diff --git a/documentation/website/expansion/eupi.json b/documentation/website/expansion/eupi.json deleted file mode 100644 index 07eb59ea..00000000 --- a/documentation/website/expansion/eupi.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "A module to query the Phishing Initiative service (https://phishing-initiative.lu).", - "logo": "eupi.png", - "requirements": [ - "pyeupi: eupi python library", - "An access to the Phishing Initiative API (apikey & url)" - ], - "input": "A domain, hostname or url MISP attribute.", - "output": "Text containing information about the input, resulting from the query on Phishing Initiative.", - "references": [ - "https://phishing-initiative.eu/?lang=en" - ], - "features": "This module takes a domain, hostname or url MISP attribute as input to query the Phishing Initiative API. The API returns then the result of the query with some information about the value queried.\n\nPlease note that composite attributes containing domain or hostname are also supported." -} \ No newline at end of file diff --git a/documentation/website/expansion/farsight_passivedns.json b/documentation/website/expansion/farsight_passivedns.json deleted file mode 100644 index 93183ce2..00000000 --- a/documentation/website/expansion/farsight_passivedns.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Module to access Farsight DNSDB Passive DNS.", - "logo": "farsight.png", - "requirements": [ - "An access to the Farsight Passive DNS API (apikey)" - ], - "input": "A domain, hostname or IP address MISP attribute.", - "output": "Passive-dns objects, resulting from the query on the Farsight Passive DNS API.", - "references": [ - "https://www.farsightsecurity.com/", - "https://docs.dnsdb.info/dnsdb-api/" - ], - "features": "This module takes a domain, hostname or IP address MISP attribute as input to query the Farsight Passive DNS API.\n The results of rdata and rrset lookups are then returned and parsed into passive-dns objects.\n\nAn API key is required to submit queries to the API.\n It is also possible to define a custom server URL, and to set a limit of results to get.\n This limit is set for each lookup, which means we can have an up to the limit number of passive-dns objects resulting from an rdata query about an IP address, but an up to the limit number of passive-dns objects for each lookup queries about a domain or a hostname (== twice the limit)." -} diff --git a/documentation/website/expansion/geoip_asn.json b/documentation/website/expansion/geoip_asn.json deleted file mode 100644 index 9a7b1ddf..00000000 --- a/documentation/website/expansion/geoip_asn.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "descrption": "An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about its related AS number.", - "logo": "maxmind.png", - "requirements": [ - "A local copy of Maxmind's Geolite database" - ], - "input": "An IP address MISP attribute.", - "output": "Text containing information about the AS number of the IP address.", - "references": [ - "https://www.maxmind.com/en/home" - ], - "features": "The module takes an IP address attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the related AS number." -} \ No newline at end of file diff --git a/documentation/website/expansion/geoip_city.json b/documentation/website/expansion/geoip_city.json deleted file mode 100644 index 24d286b4..00000000 --- a/documentation/website/expansion/geoip_city.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about the city where it is located.", - "logo": "maxmind.png", - "requirements": [ - "A local copy of Maxmind's Geolite database" - ], - "input": "An IP address MISP attribute.", - "output": "Text containing information about the city where the IP address is located.", - "references": [ - "https://www.maxmind.com/en/home" - ], - "features": "The module takes an IP address attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the city where this IP address is located." -} \ No newline at end of file diff --git a/documentation/website/expansion/geoip_country.json b/documentation/website/expansion/geoip_country.json deleted file mode 100644 index ec842824..00000000 --- a/documentation/website/expansion/geoip_country.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to query a local copy of Maxmind's Geolite database.", - "logo": "maxmind.png", - "requirements": [ - "A local copy of Maxmind's Geolite database" - ], - "input": "An IP address MISP Attribute.", - "output": "Text containing information about the location of the IP address.", - "references": [ - "https://www.maxmind.com/en/home" - ], - "features": "This module takes an IP address MISP attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the location of this IP address.\n\nPlease note that composite attributes domain|ip are also supported." -} \ No newline at end of file diff --git a/documentation/website/expansion/google_search.json b/documentation/website/expansion/google_search.json deleted file mode 100644 index 8772d21a..00000000 --- a/documentation/website/expansion/google_search.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "descrption": "A hover module to get information about an url using a Google search.", - "logo": "google.png", - "requirements": [ - "The python Google Search API library" - ], - "input": "An url attribute.", - "output": "Text containing the result of a Google search on the input url.", - "references": [ - "https://github.com/abenassi/Google-Search-API" - ], - "features": "The module takes an url as input to query the Google search API. The result of the query is then return as raw text." -} \ No newline at end of file diff --git a/documentation/website/expansion/greynoise.json b/documentation/website/expansion/greynoise.json deleted file mode 100644 index 49885371..00000000 --- a/documentation/website/expansion/greynoise.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "description": "Module to query IP and CVE information from GreyNoise", - "logo": "greynoise.png", - "requirements": [ - "A Greynoise API key. Both Enterprise (Paid) and Community (Free) API keys are supported, however Community API users will only be able to perform IP lookups." - ], - "input": "An IP address or CVE ID", - "output": "IP Lookup information or CVE scanning profile for past 7 days", - "references": [ - "https://greynoise.io/", - "https://docs.greyniose.io/", - "https://www.greynoise.io/viz/account/" - ], - "features": "This module supports: 1) Query an IP from GreyNoise to see if it is internet background noise or a common business service 2) Query a CVE from GreyNoise to see the total number of internet scanners looking for the CVE in the last 7 days." -} \ No newline at end of file diff --git a/documentation/website/expansion/hashdd.json b/documentation/website/expansion/hashdd.json deleted file mode 100644 index 2edc1d17..00000000 --- a/documentation/website/expansion/hashdd.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "description": "A hover module to check hashes against hashdd.com including NSLR dataset.", - "input": "A hash MISP attribute (md5).", - "output": "Text describing the known level of the hash in the hashdd databases.", - "references": [ - "https://hashdd.com/" - ], - "features": "This module takes a hash attribute as input to check its known level, using the hashdd API. This information is then displayed." -} \ No newline at end of file diff --git a/documentation/website/expansion/hashlookup.json b/documentation/website/expansion/hashlookup.json deleted file mode 100644 index 713be839..00000000 --- a/documentation/website/expansion/hashlookup.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "An expansion module to query the CIRCL hashlookup services to find it if a hash is part of a known set such as NSRL.", - "logo": "circl.png", - "input": "File hashes (MD5, SHA1)", - "output": "Object with the filename associated hashes if the hash is part of a known set.", - "references": [ - "https://www.circl.lu/services/hashlookup/" - ], - "features": "The module takes file hashes as input such as a MD5 or SHA1.\n It queries the public CIRCL.lu hashlookup service and return all the hits if the hashes are known in an existing dataset. The module can be configured with a custom hashlookup url if required.\n The module can be used an hover module but also an expansion model to add related MISP objects.\n" -} diff --git a/documentation/website/expansion/hibp.json b/documentation/website/expansion/hibp.json deleted file mode 100644 index a2b7b09c..00000000 --- a/documentation/website/expansion/hibp.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Module to access haveibeenpwned.com API.", - "logo": "hibp.png", - "requirements": [], - "input": "An email address", - "output": "Additional information about the email address.", - "references": [ - "https://haveibeenpwned.com/" - ], - "features": "The module takes an email address as input and queries haveibeenpwned.com API to find additional information about it. This additional information actually tells if any account using the email address has already been compromised in a data breach." -} \ No newline at end of file diff --git a/documentation/website/expansion/html_to_markdown.json b/documentation/website/expansion/html_to_markdown.json deleted file mode 100644 index 08644317..00000000 --- a/documentation/website/expansion/html_to_markdown.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "description": "Expansion module to fetch the html content from an url and convert it into markdown.", - "input": "URL attribute.", - "output": "Markdown content converted from the HTML fetched from the url.", - "requirements": [ - "The markdownify python library" - ], - "features": "The module take an URL as input and the HTML content is fetched from it. This content is then converted into markdown that is returned as text." -} \ No newline at end of file diff --git a/documentation/website/expansion/hyasinsight.json b/documentation/website/expansion/hyasinsight.json deleted file mode 100644 index 2762a087..00000000 --- a/documentation/website/expansion/hyasinsight.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "HYAS Insight integration to MISP provides direct, high volume access to HYAS Insight data. It enables investigators and analysts to understand and defend against cyber adversaries and their infrastructure.", - "logo": "hyas.png", - "requirements": [ - "A HYAS Insight API Key." - ], - "input": "A MISP attribute of type IP Address(ip-src, ip-dst), Domain(hostname, domain), Email Address(email, email-src, email-dst, target-email, whois-registrant-email), Phone Number(phone-number, whois-registrant-phone), MDS(md5, x509-fingerprint-md5, ja3-fingerprint-md5, hassh-md5, hasshserver-md5), SHA1(sha1, x509-fingerprint-sha1), SHA256(sha256, x509-fingerprint-sha256), SHA512(sha512)", - "output": "Hyas Insight objects, resulting from the query on the HYAS Insight API.", - "references": [ - "https://www.hyas.com/hyas-insight/" - ], - "features": "This Module takes the IP Address, Domain, URL, Email, Phone Number, MD5, SHA1, Sha256, SHA512 MISP Attributes as input to query the HYAS Insight API.\n The results of the HYAS Insight API are than are then returned and parsed into Hyas Insight Objects. \n\nAn API key is required to submit queries to the HYAS Insight API.\n" -} diff --git a/documentation/website/expansion/intel471.json b/documentation/website/expansion/intel471.json deleted file mode 100644 index 89352767..00000000 --- a/documentation/website/expansion/intel471.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "descrption": "An expansion module to query Intel471 in order to get additional information about a domain, ip address, email address, url or hash.", - "logo": "intel471.png", - "requirements": [ - "The intel471 python library" - ], - "input": "A MISP attribute whose type is included in the following list:\n- hostname\n- domain\n- url\n- ip-src\n- ip-dst\n- email-src\n- email-dst\n- target-email\n- whois-registrant-email\n- whois-registrant-name\n- md5\n- sha1\n- sha256", - "output": "Freetext", - "references": [ - "https://public.intel471.com/" - ], - "features": "The module uses the Intel471 python library to query the Intel471 API with the value of the input attribute. The result of the query is then returned as freetext so the Freetext import parses it." -} \ No newline at end of file diff --git a/documentation/website/expansion/intelmq_eventdb.json b/documentation/website/expansion/intelmq_eventdb.json deleted file mode 100644 index ce2b12a5..00000000 --- a/documentation/website/expansion/intelmq_eventdb.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "description": "Module to access intelmqs eventdb.", - "logo": "intelmq.png", - "requirements": [ - "psycopg2: Python library to support PostgreSQL", - "An access to the IntelMQ database (username, password, hostname and database reference)" - ], - "input": "A hostname, domain, IP address or AS attribute.", - "output": "Text giving information about the input using IntelMQ database.", - "references": [ - "https://github.com/certtools/intelmq", - "https://intelmq.readthedocs.io/en/latest/Developers-Guide/" - ], - "features": "/!\\ EXPERIMENTAL MODULE, some features may not work /!\\\n\nThis module takes a domain, hostname, IP address or Autonomous system MISP attribute as input to query the IntelMQ database. The result of the query gives then additional information about the input." -} \ No newline at end of file diff --git a/documentation/website/expansion/ip2locationio.json b/documentation/website/expansion/ip2locationio.json deleted file mode 100644 index 71de5455..00000000 --- a/documentation/website/expansion/ip2locationio.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion module to query IP2Location.io to gather more information on a given IP address.", - "logo": "ip2locationio.png", - "requirements": [ - "An IP2Location.io token" - ], - "input": "IP address attribute.", - "output": "Additional information on the IP address, such as geolocation, proxy and so on. Refer to the Response Format section in https://www.ip2location.io/ip2location-documentation to find out the full format of the data returned.", - "references": [ - "https://www.ip2location.io/ip2location-documentation" - ], - "features": "The module takes an IP address attribute as input and queries the IP2Location.io API. \nFree plan user will get the basic geolocation informaiton, and different subsription plan will get more information on the IP address. \n Refer to [pricing page](https://www.ip2location.io/pricing) for more information on data available for each plan. \n\nMore information on the responses content is available in the [documentation](https://www.ip2location.io/ip2location-documentation)." -} diff --git a/documentation/website/expansion/ipasn.json b/documentation/website/expansion/ipasn.json deleted file mode 100644 index 5f30608a..00000000 --- a/documentation/website/expansion/ipasn.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Module to query an IP ASN history service (https://github.com/D4-project/IPASN-History).", - "requirements": [ - "pyipasnhistory: Python library to access IPASN-history instance" - ], - "input": "An IP address MISP attribute.", - "output": "Asn object(s) objects related to the IP address used as input.", - "references": [ - "https://github.com/D4-project/IPASN-History" - ], - "features": "This module takes an IP address attribute as input and queries the CIRCL IPASN service. The result of the query is the latest asn related to the IP address, that is returned as a MISP object." -} \ No newline at end of file diff --git a/documentation/website/expansion/ipinfo.json b/documentation/website/expansion/ipinfo.json deleted file mode 100644 index 070b7a8d..00000000 --- a/documentation/website/expansion/ipinfo.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion module to query ipinfo.io to gather more information on a given IP address.", - "logo": "ipinfo.png", - "requirements": [ - "An ipinfo.io token" - ], - "input": "IP address attribute.", - "output": "Additional information on the IP address, like its geolocation, the autonomous system it is included in, and the related domain(s).", - "references": [ - "https://ipinfo.io/developers" - ], - "features": "The module takes an IP address attribute as input and queries the ipinfo.io API. \nThe geolocation information on the IP address is always returned.\n\nDepending on the subscription plan, the API returns different pieces of information then:\n- With a basic plan (free) you get the AS number and the AS organisation name concatenated in the `org` field.\n- With a paid subscription, the AS information is returned in the `asn` field with additional AS information, and depending on which plan the user has, you can also get information on the privacy method used to protect the IP address, the related domains, or the point of contact related to the IP address in case of an abuse.\n\nMore information on the responses content is available in the [documentation](https://ipinfo.io/developers)." -} diff --git a/documentation/website/expansion/ipqs_fraud_and_risk_scoring.json b/documentation/website/expansion/ipqs_fraud_and_risk_scoring.json deleted file mode 100644 index d0d4665d..00000000 --- a/documentation/website/expansion/ipqs_fraud_and_risk_scoring.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "IPQualityScore MISP Expansion Module for IP reputation, Email Validation, Phone Number Validation, Malicious Domain and Malicious URL Scanner.", - "logo": "ipqualityscore.png", - "requirements": [ - "A IPQualityScore API Key." - ], - "input": "A MISP attribute of type IP Address(ip-src, ip-dst), Domain(hostname, domain), URL(url, uri), Email Address(email, email-src, email-dst, target-email, whois-registrant-email) and Phone Number(phone-number, whois-registrant-phone).", - "output": "IPQualityScore object, resulting from the query on the IPQualityScore API.", - "references": [ - "https://www.ipqualityscore.com/" - ], - "features": "This Module takes the IP Address, Domain, URL, Email and Phone Number MISP Attributes as input to query the IPQualityScore API.\n The results of the IPQualityScore API are than returned as IPQS Fraud and Risk Scoring Object. \n The object contains a copy of the enriched attribute with added tags presenting the verdict based on fraud score,risk score and other attributes from IPQualityScore." -} diff --git a/documentation/website/expansion/iprep.json b/documentation/website/expansion/iprep.json deleted file mode 100644 index 2e273044..00000000 --- a/documentation/website/expansion/iprep.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Module to query IPRep data for IP addresses.", - "requirements": [ - "An access to the packetmail API (apikey)" - ], - "input": "An IP address MISP attribute.", - "output": "Text describing additional information about the input after a query on the IPRep API.", - "references": [ - "https://github.com/mahesh557/packetmail" - ], - "features": "This module takes an IP address attribute as input and queries the database from packetmail.net to get some information about the reputation of the IP." -} \ No newline at end of file diff --git a/documentation/website/expansion/joesandbox_query.json b/documentation/website/expansion/joesandbox_query.json deleted file mode 100644 index 9fa08577..00000000 --- a/documentation/website/expansion/joesandbox_query.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Query Joe Sandbox API with a submission url to get the json report and extract its data that is parsed and converted into MISP attributes and objects.\n\nThis url can by the way come from the result of the [joesandbox_submit expansion module](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py).", - "logo": "joesandbox.png", - "requirements": [ - "jbxapi: Joe Sandbox API python3 library" - ], - "input": "Link of a Joe Sandbox sample or url submission.", - "output": "MISP attributes & objects parsed from the analysis report.", - "references": [ - "https://www.joesecurity.org", - "https://www.joesandbox.com/" - ], - "features": "Module using the new format of modules able to return attributes and objects.\n\nThe module returns the same results as the import module [joe_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/joe_import.py) taking directly the json report as input.\n\nEven if the introspection will allow all kinds of links to call this module, obviously only the ones presenting a sample or url submission in the Joe Sandbox API will return results.\n\nTo make it work you will need to fill the 'apikey' configuration with your Joe Sandbox API key and provide a valid link as input." -} \ No newline at end of file diff --git a/documentation/website/expansion/joesandbox_submit.json b/documentation/website/expansion/joesandbox_submit.json deleted file mode 100644 index 6da034a0..00000000 --- a/documentation/website/expansion/joesandbox_submit.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "A module to submit files or URLs to Joe Sandbox for an advanced analysis, and return the link of the submission.", - "logo": "joesandbox.png", - "requirements": [ - "jbxapi: Joe Sandbox API python3 library" - ], - "input": "Sample, url (or domain) to submit to Joe Sandbox for an advanced analysis.", - "output": "Link of the report generated in Joe Sandbox.", - "references": [ - "https://www.joesecurity.org", - "https://www.joesandbox.com/" - ], - "features": "The module requires a Joe Sandbox API key to submit files or URL, and returns the link of the submitted analysis.\n\nIt is then possible, when the analysis is completed, to query the Joe Sandbox API to get the data related to the analysis, using the [joesandbox_query module](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) directly on this submission link." -} \ No newline at end of file diff --git a/documentation/website/expansion/lastline_query.json b/documentation/website/expansion/lastline_query.json deleted file mode 100644 index 9e764bba..00000000 --- a/documentation/website/expansion/lastline_query.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module.\n\nQuery Lastline with an analysis link and parse the report into MISP attributes and objects.\nThe analysis link can also be retrieved from the output of the [lastline_submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_submit.py) expansion module.", - "logo": "lastline.png", - "requirements": [], - "input": "Link to a Lastline analysis.", - "output": "MISP attributes and objects parsed from the analysis report.", - "references": [ - "https://www.lastline.com" - ], - "features": "The module requires a Lastline Portal `username` and `password`.\nThe module uses the new format and it is able to return MISP attributes and objects.\nThe module returns the same results as the [lastline_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/lastline_import.py) import module." -} \ No newline at end of file diff --git a/documentation/website/expansion/lastline_submit.json b/documentation/website/expansion/lastline_submit.json deleted file mode 100644 index cc394e2a..00000000 --- a/documentation/website/expansion/lastline_submit.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module.\n\nModule to submit a file or URL to Lastline.", - "logo": "lastline.png", - "requirements": [], - "input": "File or URL to submit to Lastline.", - "output": "Link to the report generated by Lastline.", - "references": [ - "https://www.lastline.com" - ], - "features": "The module requires a Lastline Analysis `api_token` and `key`.\nWhen the analysis is completed, it is possible to import the generated report by feeding the analysis link to the [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) module." -} \ No newline at end of file diff --git a/documentation/website/expansion/macaddress_io.json b/documentation/website/expansion/macaddress_io.json deleted file mode 100644 index 013564a2..00000000 --- a/documentation/website/expansion/macaddress_io.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "description": "MISP hover module for macaddress.io", - "logo": "macaddress_io.png", - "requirements": [ - "maclookup: macaddress.io python library", - "An access to the macaddress.io API (apikey)" - ], - "input": "MAC address MISP attribute.", - "output": "Text containing information on the MAC address fetched from a query on macaddress.io.", - "references": [ - "https://macaddress.io/", - "https://github.com/CodeLineFi/maclookup-python" - ], - "features": "This module takes a MAC address attribute as input and queries macaddress.io for additional information.\n\nThis information contains data about:\n- MAC address details\n- Vendor details\n- Block details" -} \ No newline at end of file diff --git a/documentation/website/expansion/macvendors.json b/documentation/website/expansion/macvendors.json deleted file mode 100644 index 38c35887..00000000 --- a/documentation/website/expansion/macvendors.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Module to access Macvendors API.", - "logo": "macvendors.png", - "requirements": [], - "input": "A MAC address.", - "output": "Additional information about the MAC address.", - "references": [ - "https://macvendors.com/", - "https://macvendors.com/api" - ], - "features": "The module takes a MAC address as input and queries macvendors.com for some information about it. The API returns the name of the vendor related to the address." -} \ No newline at end of file diff --git a/documentation/website/expansion/malwarebazaar.json b/documentation/website/expansion/malwarebazaar.json deleted file mode 100644 index 8c8228c5..00000000 --- a/documentation/website/expansion/malwarebazaar.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "Query the MALWAREbazaar API to get additional information about the input hash attribute.", - "requirements": [], - "input": "A hash attribute (md5, sha1 or sha256).", - "output": "File object(s) related to the input attribute found on MALWAREbazaar databases.", - "references": [ - "https://bazaar.abuse.ch/" - ], - "features": "The module takes a hash attribute as input and queries MALWAREbazaar's API to fetch additional data about it. The result, if the payload is known on the databases, is at least one file object describing the file the input hash is related to.\n\nThe module is using the new format of modules able to return object since the result is one or multiple MISP object(s)." -} \ No newline at end of file diff --git a/documentation/website/expansion/mmdb_lookup.json b/documentation/website/expansion/mmdb_lookup.json deleted file mode 100644 index ebfbf491..00000000 --- a/documentation/website/expansion/mmdb_lookup.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "A hover and expansion module to enrich an ip with geolocation and ASN information from an mmdb server instance, such as CIRCL's ip.circl.lu.", - "logo": "circl.png", - "input": "An IP address attribute (for example ip-src or ip-src|port).", - "output": "Geolocation and asn objects.", - "references": [ - "https://data.public.lu/fr/datasets/geo-open-ip-address-geolocation-per-country-in-mmdb-format/", - "https://github.com/adulau/mmdb-server" - ], - "features": "The module takes an IP address related attribute as input.\n It queries the public CIRCL.lu mmdb-server instance, available at ip.circl.lu, by default. The module can be configured with a custom mmdb server url if required.\n It is also possible to filter results on 1 db_source by configuring db_source_filter." -} \ No newline at end of file diff --git a/documentation/website/expansion/mwdb.json b/documentation/website/expansion/mwdb.json deleted file mode 100644 index 456a160b..00000000 --- a/documentation/website/expansion/mwdb.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Module to push malware samples to a MWDB instance", - "requirements": [ - "* mwdblib installed (pip install mwdblib) ; * (optional) keys.py file to add tags of events/attributes to MWDB * (optional) MWDB attribute created for the link back to MISP (defined in mwdb_misp_attribute)" - ], - "input": "Attachment or malware sample", - "output": "Link attribute that points to the sample at the MWDB instane", - "references": [ - ], - "features": "An expansion module to push malware samples to a MWDB (https://github.com/CERT-Polska/mwdb-core) instance. This module does not push samples to a sandbox. This can be achieved via Karton (connected to the MWDB). Does: * Upload of attachment or malware sample to MWDB * Tags of events and/or attributes are added to MWDB. * Comment of the MISP attribute is added to MWDB. * A link back to the MISP event is added to MWDB via the MWDB attribute. * A link to the MWDB attribute is added as an enrichted attribute to the MISP event." -} \ No newline at end of file diff --git a/documentation/website/expansion/ocr_enrich.json b/documentation/website/expansion/ocr_enrich.json deleted file mode 100644 index 0e8f627e..00000000 --- a/documentation/website/expansion/ocr_enrich.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "Module to process some optical character recognition on pictures.", - "requirements": [ - "cv2: The OpenCV python library." - ], - "input": "A picture attachment.", - "output": "Text and freetext fetched from the input picture.", - "references": [], - "features": "The module takes an attachment attributes as input and process some optical character recognition on it. The text found is then passed to the Freetext importer to extract potential IoCs." -} \ No newline at end of file diff --git a/documentation/website/expansion/ods_enrich.json b/documentation/website/expansion/ods_enrich.json deleted file mode 100644 index ade41054..00000000 --- a/documentation/website/expansion/ods_enrich.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Module to extract freetext from a .ods document.", - "logo": "ods.png", - "requirements": [ - "ezodf: Python package to create/manipulate OpenDocumentFormat files.", - "pandas_ods_reader: Python library to read in ODS files." - ], - "input": "Attachment attribute containing a .ods document.", - "output": "Text and freetext parsed from the document.", - "references": [], - "features": "The module reads the text contained in a .ods document. The result is passed to the freetext import parser so IoCs can be extracted out of it." -} \ No newline at end of file diff --git a/documentation/website/expansion/odt_enrich.json b/documentation/website/expansion/odt_enrich.json deleted file mode 100644 index 8922a9b9..00000000 --- a/documentation/website/expansion/odt_enrich.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Module to extract freetext from a .odt document.", - "logo": "odt.png", - "requirements": [ - "ODT reader python library." - ], - "input": "Attachment attribute containing a .odt document.", - "output": "Text and freetext parsed from the document.", - "references": [], - "features": "The module reads the text contained in a .odt document. The result is passed to the freetext import parser so IoCs can be extracted out of it." -} \ No newline at end of file diff --git a/documentation/website/expansion/onyphe.json b/documentation/website/expansion/onyphe.json deleted file mode 100644 index f38ea25c..00000000 --- a/documentation/website/expansion/onyphe.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "description": "Module to process a query on Onyphe.", - "logo": "onyphe.jpg", - "requirements": [ - "onyphe python library", - "An access to the Onyphe API (apikey)" - ], - "input": "A domain, hostname or IP address MISP attribute.", - "output": "MISP attributes fetched from the Onyphe query.", - "references": [ - "https://www.onyphe.io/", - "https://github.com/sebdraven/pyonyphe" - ], - "features": "This module takes a domain, hostname, or IP address attribute as input in order to query the Onyphe API. Data fetched from the query is then parsed and MISP attributes are extracted." -} \ No newline at end of file diff --git a/documentation/website/expansion/onyphe_full.json b/documentation/website/expansion/onyphe_full.json deleted file mode 100644 index e1a040a5..00000000 --- a/documentation/website/expansion/onyphe_full.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "description": "Module to process a full query on Onyphe.", - "logo": "onyphe.jpg", - "requirements": [ - "onyphe python library", - "An access to the Onyphe API (apikey)" - ], - "input": "A domain, hostname or IP address MISP attribute.", - "output": "MISP attributes fetched from the Onyphe query.", - "references": [ - "https://www.onyphe.io/", - "https://github.com/sebdraven/pyonyphe" - ], - "features": "This module takes a domain, hostname, or IP address attribute as input in order to query the Onyphe API. Data fetched from the query is then parsed and MISP attributes are extracted.\n\nThe parsing is here more advanced than the one on onyphe module, and is returning more attributes, since more fields of the query result are watched and parsed." -} \ No newline at end of file diff --git a/documentation/website/expansion/otx.json b/documentation/website/expansion/otx.json deleted file mode 100644 index a17e2ff6..00000000 --- a/documentation/website/expansion/otx.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to get information from AlienVault OTX.", - "logo": "otx.png", - "requirements": [ - "An access to the OTX API (apikey)" - ], - "input": "A MISP attribute included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- md5\n- sha1\n- sha256\n- sha512", - "output": "MISP attributes mapped from the result of the query on OTX, included in the following list:\n- domain\n- ip-src\n- ip-dst\n- text\n- md5\n- sha1\n- sha256\n- sha512\n- email", - "references": [ - "https://www.alienvault.com/open-threat-exchange" - ], - "features": "This module takes a MISP attribute as input to query the OTX Alienvault API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes." -} \ No newline at end of file diff --git a/documentation/website/expansion/passivessh.json b/documentation/website/expansion/passivessh.json deleted file mode 100644 index 68f7eb74..00000000 --- a/documentation/website/expansion/passivessh.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "An expansion module to query the CIRCL Passive SSH.", - "logo": "passivessh.png", - "input": "IP addresses or SSH fingerprints", - "output": "SSH key materials, complementary IP addresses with similar SSH key materials", - "references": [ - "https://github.com/D4-project/passive-ssh" - ], - "features": "The module queries the Passive SSH service from CIRCL.\n \n The module can be used an hover module but also an expansion model to add related MISP objects.\n" -} diff --git a/documentation/website/expansion/passivetotal.json b/documentation/website/expansion/passivetotal.json deleted file mode 100644 index 26835d50..00000000 --- a/documentation/website/expansion/passivetotal.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "", - "logo": "passivetotal.png", - "requirements": [ - "Passivetotal python library", - "An access to the PassiveTotal API (apikey)" - ], - "input": "A MISP attribute included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- x509-fingerprint-sha1\n- email-src\n- email-dst\n- target-email\n- whois-registrant-email\n- whois-registrant-phone\n- text\n- whois-registrant-name\n- whois-registrar\n- whois-creation-date", - "output": "MISP attributes mapped from the result of the query on PassiveTotal, included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- x509-fingerprint-sha1\n- email-src\n- email-dst\n- target-email\n- whois-registrant-email\n- whois-registrant-phone\n- text\n- whois-registrant-name\n- whois-registrar\n- whois-creation-date\n- md5\n- sha1\n- sha256\n- link", - "references": [ - "https://www.passivetotal.org/register" - ], - "features": "The PassiveTotal MISP expansion module brings the datasets derived from Internet scanning directly into your MISP instance. This module supports passive DNS, historic SSL, WHOIS, and host attributes. In order to use the module, you must have a valid PassiveTotal account username and API key. Registration is free and can be done by visiting https://www.passivetotal.org/register" -} \ No newline at end of file diff --git a/documentation/website/expansion/pdf_enrich.json b/documentation/website/expansion/pdf_enrich.json deleted file mode 100644 index a17ef515..00000000 --- a/documentation/website/expansion/pdf_enrich.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Module to extract freetext from a PDF document.", - "logo": "pdf.jpg", - "requirements": [ - "pdftotext: Python library to extract text from PDF." - ], - "input": "Attachment attribute containing a PDF document.", - "output": "Text and freetext parsed from the document.", - "references": [], - "features": "The module reads the text contained in a PDF document. The result is passed to the freetext import parser so IoCs can be extracted out of it." -} \ No newline at end of file diff --git a/documentation/website/expansion/pptx_enrich.json b/documentation/website/expansion/pptx_enrich.json deleted file mode 100644 index 664c70ab..00000000 --- a/documentation/website/expansion/pptx_enrich.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Module to extract freetext from a .pptx document.", - "logo": "pptx.png", - "requirements": [ - "pptx: Python library to read PowerPoint files." - ], - "input": "Attachment attribute containing a .pptx document.", - "output": "Text and freetext parsed from the document.", - "references": [], - "features": "The module reads the text contained in a .pptx document. The result is passed to the freetext import parser so IoCs can be extracted out of it." -} \ No newline at end of file diff --git a/documentation/website/expansion/qintel_qsentry.json b/documentation/website/expansion/qintel_qsentry.json deleted file mode 100644 index 4994a62e..00000000 --- a/documentation/website/expansion/qintel_qsentry.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "A hover and expansion module which queries Qintel QSentry for ip reputation data", - "logo": "qintel.png", - "requirements": [ - "A Qintel API token" - ], - "input": "ip address attribute", - "ouput": "Objects containing the enriched IP, threat tags, last seen attributes and associated Autonomous System information", - "features": "This module takes an ip-address (ip-src or ip-dst) attribute as input, and queries the Qintel QSentry API to retrieve ip reputation data", - "references": [ - "https://www.qintel.com/products/qsentry/" - ] -} \ No newline at end of file diff --git a/documentation/website/expansion/qrcode.json b/documentation/website/expansion/qrcode.json deleted file mode 100644 index f5855116..00000000 --- a/documentation/website/expansion/qrcode.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Module to decode QR codes.", - "requirements": [ - "cv2: The OpenCV python library.", - "pyzbar: Python library to read QR codes." - ], - "input": "A QR code stored as attachment attribute.", - "output": "The URL or bitcoin address the QR code is pointing to.", - "references": [], - "features": "The module reads the QR code and returns the related address, which can be an URL or a bitcoin address." -} \ No newline at end of file diff --git a/documentation/website/expansion/ransomcoindb.json b/documentation/website/expansion/ransomcoindb.json deleted file mode 100644 index 26c3c556..00000000 --- a/documentation/website/expansion/ransomcoindb.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "descrption": "Module to access the ransomcoinDB with a hash or btc address attribute and get the associated btc address of hashes.", - "requirements": [ - "A ransomcoinDB API key." - ], - "input": "A hash (md5, sha1 or sha256) or btc attribute.", - "output": "Hashes associated to a btc address or btc addresses associated to a hash.", - "references": [ - "https://ransomcoindb.concinnity-risks.com" - ], - "features": "The module takes either a hash attribute or a btc attribute as input to query the ransomcoinDB API for some additional data.\n\nIf the input is a btc address, we will get the associated hashes returned in a file MISP object. If we query ransomcoinDB with a hash, the response contains the associated btc addresses returned as single MISP btc attributes." -} \ No newline at end of file diff --git a/documentation/website/expansion/rbl.json b/documentation/website/expansion/rbl.json deleted file mode 100644 index 942daa70..00000000 --- a/documentation/website/expansion/rbl.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Module to check an IPv4 address against known RBLs.", - "requirements": [ - "dnspython3: DNS python3 library" - ], - "input": "IP address attribute.", - "output": "Text with additional data from Real-time Blackhost Lists about the IP address.", - "references": [ - "[RBLs list](https://github.com/MISP/misp-modules/blob/8817de476572a10a9c9d03258ec81ca70f3d926d/misp_modules/modules/expansion/rbl.py#L20)" - ], - "features": "This module takes an IP address attribute as input and queries multiple know Real-time Blackhost Lists to check if they have already seen this IP address.\n\nWe display then all the information we get from those different sources." -} \ No newline at end of file diff --git a/documentation/website/expansion/recordedfuture.json b/documentation/website/expansion/recordedfuture.json deleted file mode 100644 index 91cf23eb..00000000 --- a/documentation/website/expansion/recordedfuture.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to enrich attributes with threat intelligence from Recorded Future.", - "logo": "recordedfuture.png", - "requirements": [ - "A Recorded Future API token." - ], - "input": "A MISP attribute of one of the following types: ip, ip-src, ip-dst, domain, hostname, md5, sha1, sha256, uri, url, vulnerability, weakness.", - "output": "A MISP object containing a copy of the enriched attribute with added tags from Recorded Future and a list of new attributes related to the enriched attribute.", - "references": [ - "https://www.recordedfuture.com/" - ], - "features": "Enrich an attribute to add a custom enrichment object to the event. The object contains a copy of the enriched attribute with added tags presenting risk score and triggered risk rules from Recorded Future. Malware and Threat Actors related to the enriched indicator in Recorded Future is matched against MISP's galaxy clusters and applied as galaxy tags. The custom enrichment object also includes a list of related indicators from Recorded Future (IP's, domains, hashes, URL's and vulnerabilities) added as additional attributes." -} \ No newline at end of file diff --git a/documentation/website/expansion/reversedns.json b/documentation/website/expansion/reversedns.json deleted file mode 100644 index cdd34192..00000000 --- a/documentation/website/expansion/reversedns.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "description": "Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes.", - "requirements": [ - "DNS python library" - ], - "input": "An IP address attribute.", - "output": "Hostname attribute the input is resolved into.", - "features": "The module takes an IP address as input and tries to find the hostname this IP address is resolved into.\n\nThe address of the DNS resolver to use is also configurable, but if no configuration is set, we use the Google public DNS address (8.8.8.8).\n\nPlease note that composite MISP attributes containing IP addresses are supported as well." -} \ No newline at end of file diff --git a/documentation/website/expansion/securitytrails.json b/documentation/website/expansion/securitytrails.json deleted file mode 100644 index 97f81b4c..00000000 --- a/documentation/website/expansion/securitytrails.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "An expansion modules for SecurityTrails.", - "logo": "securitytrails.png", - "requirements": [ - "dnstrails python library", - "An access to the SecurityTrails API (apikey)" - ], - "input": "A domain, hostname or IP address attribute.", - "output": "MISP attributes resulting from the query on SecurityTrails API, included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- dns-soa-email\n- whois-registrant-email\n- whois-registrant-phone\n- whois-registrant-name\n- whois-registrar\n- whois-creation-date\n- domain", - "references": [ - "https://securitytrails.com/" - ], - "features": "The module takes a domain, hostname or IP address attribute as input and queries the SecurityTrails API with it.\n\nMultiple parsing operations are then processed on the result of the query to extract a much information as possible.\n\nFrom this data extracted are then mapped MISP attributes." -} \ No newline at end of file diff --git a/documentation/website/expansion/shodan.json b/documentation/website/expansion/shodan.json deleted file mode 100644 index 703a0847..00000000 --- a/documentation/website/expansion/shodan.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Module to query on Shodan.", - "logo": "shodan.png", - "requirements": [ - "shodan python library", - "An access to the Shodan API (apikey)" - ], - "input": "An IP address MISP attribute.", - "output": "Text with additional data about the input, resulting from the query on Shodan.", - "references": [ - "https://www.shodan.io/" - ], - "features": "The module takes an IP address as input and queries the Shodan API to get some additional data about it." -} \ No newline at end of file diff --git a/documentation/website/expansion/sigma_queries.json b/documentation/website/expansion/sigma_queries.json deleted file mode 100644 index c9671125..00000000 --- a/documentation/website/expansion/sigma_queries.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion hover module to display the result of sigma queries.", - "logo": "sigma.png", - "requirements": [ - "Sigma python library" - ], - "input": "A Sigma attribute.", - "output": "Text displaying results of queries on the Sigma attribute.", - "references": [ - "https://github.com/Neo23x0/sigma/wiki" - ], - "features": "This module takes a Sigma rule attribute as input and tries all the different queries available to convert it into different formats recognized by SIEMs." -} \ No newline at end of file diff --git a/documentation/website/expansion/sigma_syntax_validator.json b/documentation/website/expansion/sigma_syntax_validator.json deleted file mode 100644 index b90c931d..00000000 --- a/documentation/website/expansion/sigma_syntax_validator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "An expansion hover module to perform a syntax check on sigma rules.", - "logo": "sigma.png", - "requirements": [ - "Sigma python library", - "Yaml python library" - ], - "input": "A Sigma attribute.", - "output": "Text describing the validity of the Sigma rule.", - "references": [ - "https://github.com/Neo23x0/sigma/wiki" - ], - "features": "This module takes a Sigma rule attribute as input and performs a syntax check on it.\n\nIt displays then that the rule is valid if it is the case, and the error related to the rule otherwise." -} \ No newline at end of file diff --git a/documentation/website/expansion/sigmf-expand.json b/documentation/website/expansion/sigmf-expand.json deleted file mode 100644 index 2a0fe024..00000000 --- a/documentation/website/expansion/sigmf-expand.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Enrichs a SigMF Recording or extracts a SigMF Archive into a SigMF Recording.", - "requirements": [ - "matplotlib: For plotting the waterfall plot of the recording.", - "numpy: For the waterfall plot of the recording.", - "sigmf: For validating SigMF files." - ], - "input": "Object of sigmf-archive or sigmf-recording template.", - "output": "Object of sigmf-expanded-recording or sigmf-recording template.", - "references": [ - "https://github.com/sigmf/SigMF" - ], - "features": "This module can be used to expand a SigMF Recording object into a SigMF Expanded Recording object with a waterfall plot or to extract a SigMF Archive object into a SigMF Recording objet." -} \ No newline at end of file diff --git a/documentation/website/expansion/socialscan.json b/documentation/website/expansion/socialscan.json deleted file mode 100644 index a1cf359b..00000000 --- a/documentation/website/expansion/socialscan.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "description": "A hover module to get information on the availability of an email address or username on some online platforms.", - "requirements": ["The socialscan python library"], - "input": "An email address or usename attribute.", - "output": "Text containing information about the availability of an email address or a username in some online platforms.", - "references": ["https://github.com/iojw/socialscan"], - "features": "The module takes an email address or username as input and check its availability on some online platforms. The results for each platform are then returned to see if the email address or the username is used, available or if there is an issue with it." -} diff --git a/documentation/website/expansion/sophoslabs_intelix.json b/documentation/website/expansion/sophoslabs_intelix.json deleted file mode 100644 index 88711924..00000000 --- a/documentation/website/expansion/sophoslabs_intelix.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion module to query the Sophoslabs intelix API to get additional information about an ip address, url, domain or sha256 attribute.", - "logo": "sophoslabs_intelix.svg", - "requirements": [ - "A client_id and client_secret pair to authenticate to the SophosLabs Intelix API" - ], - "input": "An ip address, url, domain or sha256 attribute.", - "output": "SophosLabs Intelix report and lookup objects", - "references": [ - "https://aws.amazon.com/marketplace/pp/B07SLZPMCS" - ], - "features": "The module takes an ip address, url, domain or sha256 attribute and queries the SophosLabs Intelix API with the attribute value. The result of this query is a SophosLabs Intelix hash report, or an ip or url lookup, that is then parsed and returned in a MISP object." -} \ No newline at end of file diff --git a/documentation/website/expansion/sourcecache.json b/documentation/website/expansion/sourcecache.json deleted file mode 100644 index 4340f2c4..00000000 --- a/documentation/website/expansion/sourcecache.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page.", - "requirements": [ - "urlarchiver: python library to fetch and archive URL on the file-system" - ], - "input": "A link or url attribute.", - "output": "A malware-sample attribute describing the cached page.", - "references": [ - "https://github.com/adulau/url_archiver" - ], - "features": "This module takes a link or url attribute as input and caches the related web page. It returns then a link of the cached page." -} \ No newline at end of file diff --git a/documentation/website/expansion/stairwell.json b/documentation/website/expansion/stairwell.json deleted file mode 100644 index 21159783..00000000 --- a/documentation/website/expansion/stairwell.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Module to query the Stairwell API to get additional information about the input hash attribute", - "logo": "stairwell.png", - "requirements": [ - "Access to Stairwell platform (apikey)" - ], - "input": "A hash attribute (md5, sha1, sha256).", - "output": "File object related to the input attribute found on Stairwell platform.", - "references": [ - "https://stairwell.com", - "https://docs.stairwell.com" - ], - "features": "The module takes a hash attribute as input and queries Stariwell's API to fetch additional data about it. The result, if the payload is observed in Stariwell, is a file object describing the file the input hash is related to." -} \ No newline at end of file diff --git a/documentation/website/expansion/stix2_pattern_syntax_validator.json b/documentation/website/expansion/stix2_pattern_syntax_validator.json deleted file mode 100644 index 0ac079dc..00000000 --- a/documentation/website/expansion/stix2_pattern_syntax_validator.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion hover module to perform a syntax check on stix2 patterns.", - "logo": "stix.png", - "requirements": [ - "stix2patterns python library" - ], - "input": "A STIX2 pattern attribute.", - "output": "Text describing the validity of the STIX2 pattern.", - "references": [ - "[STIX2.0 patterning specifications](http://docs.oasis-open.org/cti/stix/v2.0/cs01/part5-stix-patterning/stix-v2.0-cs01-part5-stix-patterning.html)" - ], - "features": "This module takes a STIX2 pattern attribute as input and performs a syntax check on it.\n\nIt displays then that the rule is valid if it is the case, and the error related to the rule otherwise." -} \ No newline at end of file diff --git a/documentation/website/expansion/threatcrowd.json b/documentation/website/expansion/threatcrowd.json deleted file mode 100644 index e279ece5..00000000 --- a/documentation/website/expansion/threatcrowd.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "Module to get information from ThreatCrowd.", - "logo": "threatcrowd.png", - "input": "A MISP attribute included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- md5\n- sha1\n- sha256\n- sha512\n- whois-registrant-email", - "output": "MISP attributes mapped from the result of the query on ThreatCrowd, included in the following list:\n- domain\n- ip-src\n- ip-dst\n- text\n- md5\n- sha1\n- sha256\n- sha512\n- hostname\n- whois-registrant-email", - "references": [ - "https://www.threatcrowd.org/" - ], - "features": "This module takes a MISP attribute as input and queries ThreatCrowd with it.\n\nThe result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute." -} \ No newline at end of file diff --git a/documentation/website/expansion/threatminer.json b/documentation/website/expansion/threatminer.json deleted file mode 100644 index 0b0d6416..00000000 --- a/documentation/website/expansion/threatminer.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "Module to get information from ThreatMiner.", - "logo": "threatminer.png", - "input": "A MISP attribute included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- md5\n- sha1\n- sha256\n- sha512", - "output": "MISP attributes mapped from the result of the query on ThreatMiner, included in the following list:\n- domain\n- ip-src\n- ip-dst\n- text\n- md5\n- sha1\n- sha256\n- sha512\n- ssdeep\n- authentihash\n- filename\n- whois-registrant-email\n- url\n- link", - "references": [ - "https://www.threatminer.org/" - ], - "features": "This module takes a MISP attribute as input and queries ThreatMiner with it.\n\nThe result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute." -} \ No newline at end of file diff --git a/documentation/website/expansion/trustar_enrich.json b/documentation/website/expansion/trustar_enrich.json deleted file mode 100644 index 415f52d2..00000000 --- a/documentation/website/expansion/trustar_enrich.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "Module to get enrich indicators with TruSTAR.", - "logo": "trustar.png", - "input": "Any of the following MISP attributes:\n- btc\n- domain\n- email-src\n- filename\n- hostname\n- ip-src\n- ip-dst\n- md5\n- sha1\n- sha256\n- url", - "output": "MISP attributes enriched with indicator summary data from the TruSTAR API. Data includes a severity level score and additional source and scoring info.", - "references": [ - "https://docs.trustar.co/api/v13/indicators/get_indicator_summaries.html" - ], - "features": "This module enriches MISP attributes with scoring and metadata from TruSTAR.\n\nThe TruSTAR indicator summary is appended to the attributes along with links to any associated reports." -} \ No newline at end of file diff --git a/documentation/website/expansion/urlhaus.json b/documentation/website/expansion/urlhaus.json deleted file mode 100644 index cd596610..00000000 --- a/documentation/website/expansion/urlhaus.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Query of the URLhaus API to get additional information about the input attribute.", - "logo": "urlhaus.png", - "requirements": [], - "input": "A domain, hostname, url, ip, md5 or sha256 attribute.", - "output": "MISP attributes & objects fetched from the result of the URLhaus API query.", - "references": [ - "https://urlhaus.abuse.ch/" - ], - "features": "Module using the new format of modules able to return attributes and objects.\n\nThe module takes one of the attribute type specified as input, and query the URLhaus API with it. If any result is returned by the API, attributes and objects are created accordingly." -} \ No newline at end of file diff --git a/documentation/website/expansion/urlscan.json b/documentation/website/expansion/urlscan.json deleted file mode 100644 index 3aab2ab5..00000000 --- a/documentation/website/expansion/urlscan.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion module to query urlscan.io.", - "logo": "urlscan.jpg", - "requirements": [ - "An access to the urlscan.io API" - ], - "input": "A domain, hostname or url attribute.", - "output": "MISP attributes mapped from the result of the query on urlscan.io.", - "references": [ - "https://urlscan.io/" - ], - "features": "This module takes a MISP attribute as input and queries urlscan.io with it.\n\nThe result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute." -} \ No newline at end of file diff --git a/documentation/website/expansion/variotdbs.json b/documentation/website/expansion/variotdbs.json deleted file mode 100644 index f5618661..00000000 --- a/documentation/website/expansion/variotdbs.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion module to query the VARIoT db API for more information about a vulnerability.", - "logo": "variot.png", - "requirements": [ - "A VARIoT db API key (if you do not want to be limited to 100 queries / day)" - ], - "input": "Vulnerability attribute.", - "output": "Additional information about the vulnerability, as it is stored on the VARIoT db, about the vulnerability itself, and the potential related exploits.", - "references": [ - "https://www.variotdbs.pl/" - ], - "features": "The module takes a vulnerability attribute as input and queries que VARIoT db API to gather additional information.\n\nThe `vuln` endpoint is queried first to look for additional information about the vulnerability itself.\n\nThe `exploits` endpoint is also queried then to look for the information of the potential related exploits, which are parsed and added to the results using the `exploit` object template." -} diff --git a/documentation/website/expansion/virustotal.json b/documentation/website/expansion/virustotal.json deleted file mode 100644 index 80378a08..00000000 --- a/documentation/website/expansion/virustotal.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Module to get advanced information from virustotal.", - "logo": "virustotal.png", - "requirements": [ - "An access to the VirusTotal API (apikey), with a high request rate limit." - ], - "input": "A domain, hash (md5, sha1, sha256 or sha512), hostname or IP address attribute.", - "output": "MISP attributes and objects resulting from the parsing of the VirusTotal report concerning the input attribute.", - "references": [ - "https://www.virustotal.com/", - "https://developers.virustotal.com/reference" - ], - "features": "New format of modules able to return attributes and objects.\n\nA module to take a MISP attribute as input and query the VirusTotal API to get additional data about it.\n\nCompared to the [standard VirusTotal expansion module](https://github.com/MISP/misp-modules/blob/main/misp_modules/modules/expansion/virustotal_public.py), this module is made for advanced parsing of VirusTotal report, with a recursive analysis of the elements found after the first request.\n\nThus, it requires a higher request rate limit to avoid the API to return a 204 error (Request rate limit exceeded), and the data parsed from the different requests are returned as MISP attributes and objects, with the corresponding relations between each one of them." -} \ No newline at end of file diff --git a/documentation/website/expansion/virustotal_public.json b/documentation/website/expansion/virustotal_public.json deleted file mode 100644 index 591dfbfa..00000000 --- a/documentation/website/expansion/virustotal_public.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Module to get information from VirusTotal.", - "logo": "virustotal.png", - "requirements": [ - "An access to the VirusTotal API (apikey)" - ], - "input": "A domain, hostname, ip, url or hash (md5, sha1, sha256 or sha512) attribute.", - "output": "MISP attributes and objects resulting from the parsing of the VirusTotal report concerning the input attribute.", - "references": [ - "https://www.virustotal.com", - "https://developers.virustotal.com/reference" - ], - "features": "New format of modules able to return attributes and objects.\n\nA module to take a MISP attribute as input and query the VirusTotal API to get additional data about it.\n\nCompared to the [more advanced VirusTotal expansion module](https://github.com/MISP/misp-modules/blob/main/misp_modules/modules/expansion/virustotal.py), this module is made for VirusTotal users who have a low request rate limit.\n\nThus, it only queries the API once and returns the results that is parsed into MISP attributes and objects." -} \ No newline at end of file diff --git a/documentation/website/expansion/vmray_submit.json b/documentation/website/expansion/vmray_submit.json deleted file mode 100644 index 2b387923..00000000 --- a/documentation/website/expansion/vmray_submit.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to submit a sample to VMRay.", - "logo": "vmray.png", - "requirements": [ - "An access to the VMRay API (apikey & url)" - ], - "input": "An attachment or malware-sample attribute.", - "output": "MISP attributes mapped from the result of the query on VMRay API, included in the following list:\n- text\n- sha1\n- sha256\n- md5\n- link", - "references": [ - "https://www.vmray.com/" - ], - "features": "This module takes an attachment or malware-sample attribute as input to query the VMRay API.\n\nThe sample contained within the attribute in then enriched with data from VMRay mapped into MISP attributes." -} \ No newline at end of file diff --git a/documentation/website/expansion/vmware_nsx.json b/documentation/website/expansion/vmware_nsx.json deleted file mode 100644 index c7e5b024..00000000 --- a/documentation/website/expansion/vmware_nsx.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Module to enrich a file or URL with VMware NSX Defender.", - "logo": "vmware_nsx.png", - "requirements": [ - "The module requires a VMware NSX Defender Analysis `api_token` and `key`." - ], - "input": "File hash, attachment or URL to be enriched with VMware NSX Defender.", - "output": "Objects and tags generated by VMware NSX Defender.", - "references": [ - "https://www.vmware.com" - ], - "features": "This module takes an IoC such as file hash, file attachment, malware-sample or url as input to query VMware NSX Defender.\n\nThe IoC is then enriched with data from VMware NSX Defender." -} - diff --git a/documentation/website/expansion/vulndb.json b/documentation/website/expansion/vulndb.json deleted file mode 100644 index e1dd869c..00000000 --- a/documentation/website/expansion/vulndb.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to query VulnDB (RiskBasedSecurity.com).", - "logo": "vulndb.png", - "requirements": [ - "An access to the VulnDB API (apikey, apisecret)" - ], - "input": "A vulnerability attribute.", - "output": "Additional data enriching the CVE input, fetched from VulnDB.", - "references": [ - "https://vulndb.cyberriskanalytics.com/" - ], - "features": "This module takes a vulnerability attribute as input and queries VulnDB in order to get some additional data about it.\n\nThe API gives the result of the query which can be displayed in the screen, and/or mapped into MISP attributes to add in the event." -} \ No newline at end of file diff --git a/documentation/website/expansion/vulners.json b/documentation/website/expansion/vulners.json deleted file mode 100644 index ab5a7786..00000000 --- a/documentation/website/expansion/vulners.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "An expansion hover module to expand information about CVE id using Vulners API.", - "logo": "vulners.png", - "requirements": [ - "Vulners python library", - "An access to the Vulners API" - ], - "input": "A vulnerability attribute.", - "output": "Text giving additional information about the CVE in input.", - "references": [ - "https://vulners.com/" - ], - "features": "This module takes a vulnerability attribute as input and queries the Vulners API in order to get some additional data about it.\n\nThe API then returns details about the vulnerability." -} \ No newline at end of file diff --git a/documentation/website/expansion/vysion.json b/documentation/website/expansion/vysion.json deleted file mode 100644 index 9f51ddf7..00000000 --- a/documentation/website/expansion/vysion.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "description": "Module to enrich the information by making use of the Vysion API.", - "logo": "vysion.png", - "requirements": [ - "Vysion python library", - "Vysion API Key" - ], - "input": "MISP Attribute which include: company(target-org), country, info.", - "output": "MISP objects containing title, link to our webapp and TOR, i2p or clearnet URLs.", - "references": [ - "https://vysion.ai/", - "https://developers.vysion.ai/", - "https://github.com/ByronLabs/vysion-cti/tree/main" - ], - "features": "This module gets correlated information from our dark web intelligence database. With this you will get several objects containing information related to, for example, an organization victim of a ransomware attack." -} \ No newline at end of file diff --git a/documentation/website/expansion/whois.json b/documentation/website/expansion/whois.json deleted file mode 100644 index bba08280..00000000 --- a/documentation/website/expansion/whois.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Module to query a local instance of uwhois (https://github.com/rafiot/uwhoisd).", - "requirements": [ - "uwhois: A whois python library" - ], - "input": "A domain or IP address attribute.", - "output": "Text describing the result of a whois request for the input value.", - "references": [ - "https://github.com/rafiot/uwhoisd" - ], - "features": "This module takes a domain or IP address attribute as input and queries a 'Univseral Whois proxy server' to get the correct details of the Whois query on the input value (check the references for more details about this whois server)." -} \ No newline at end of file diff --git a/documentation/website/expansion/whoisfreaks.json b/documentation/website/expansion/whoisfreaks.json deleted file mode 100644 index 0e55373d..00000000 --- a/documentation/website/expansion/whoisfreaks.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion module for https://whoisfreaks.com/ that will provide an enriched analysis of the provided domain, including WHOIS and DNS information.\nOur Whois service, DNS Lookup API, and SSL analysis, equips organizations with comprehensive threat intelligence and attack surface analysis capabilities for enhanced security. \nExplore our website's product section at https://whoisfreaks.com/ for a wide range of additional services catering to threat intelligence and attack surface analysis needs.", - "logo": "whoisfreaks.png", - "requirements": [ - "An access to the Whoisfreaks API_KEY" - ], - "input": "A domain whose Data is required", - "output": "MISP attributes resulting from the query on Whoisfreaks API, included in the following list:\n- domain\n- dns-soa-email\n- whois-registrant-email\n- whois-registrant-phone\n- whois-registrant-name\n- whois-registrar\n- whois-creation-date\n- domain", - "references": [ - "https://whoisfreaks.com/" - ], - "features": "The module takes a domain as input and queries the Whoisfreaks API with it.\n\nSome parsing operations are then processed on the result of the query to extract as much information as possible.\n\nAfter this we map the extracted data to MISP attributes." -} \ No newline at end of file diff --git a/documentation/website/expansion/wiki.json b/documentation/website/expansion/wiki.json deleted file mode 100644 index 36bb0099..00000000 --- a/documentation/website/expansion/wiki.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion hover module to extract information from Wikidata to have additional information about particular term for analysis.", - "logo": "wikidata.png", - "requirements": [ - "SPARQLWrapper python library" - ], - "input": "Text attribute.", - "output": "Text attribute.", - "references": [ - "https://www.wikidata.org" - ], - "features": "This module takes a text attribute as input and queries the Wikidata API. If the text attribute is clear enough to define a specific term, the API returns a wikidata link in response." -} \ No newline at end of file diff --git a/documentation/website/expansion/xforceexchange.json b/documentation/website/expansion/xforceexchange.json deleted file mode 100644 index fe6fcbb8..00000000 --- a/documentation/website/expansion/xforceexchange.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion module for IBM X-Force Exchange.", - "logo": "xforce.png", - "requirements": [ - "An access to the X-Force API (apikey)" - ], - "input": "A MISP attribute included in the following list:\n- ip-src\n- ip-dst\n- vulnerability\n- md5\n- sha1\n- sha256", - "output": "MISP attributes mapped from the result of the query on X-Force Exchange.", - "references": [ - "https://exchange.xforce.ibmcloud.com/" - ], - "features": "This module takes a MISP attribute as input to query the X-Force API. The API returns then additional information known in their threats data, that is mapped into MISP attributes." -} \ No newline at end of file diff --git a/documentation/website/expansion/xlsx_enrich.json b/documentation/website/expansion/xlsx_enrich.json deleted file mode 100644 index dff623da..00000000 --- a/documentation/website/expansion/xlsx_enrich.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Module to extract freetext from a .xlsx document.", - "logo": "xlsx.png", - "requirements": [ - "pandas: Python library to perform data analysis, time series and statistics." - ], - "input": "Attachment attribute containing a .xlsx document.", - "output": "Text and freetext parsed from the document.", - "references": [], - "features": "The module reads the text contained in a .xlsx document. The result is passed to the freetext import parser so IoCs can be extracted out of it." -} \ No newline at end of file diff --git a/documentation/website/expansion/yara_query.json b/documentation/website/expansion/yara_query.json deleted file mode 100644 index 453e5993..00000000 --- a/documentation/website/expansion/yara_query.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "An expansion & hover module to translate any hash attribute into a yara rule.", - "logo": "yara.png", - "requirements": [ - "yara-python python library" - ], - "features": "The module takes a hash attribute (md5, sha1, sha256, imphash) as input, and is returning a YARA rule from it. This YARA rule is also validated using the same method as in 'yara_syntax_validator' module.\nBoth hover and expansion functionalities are supported with this module, where the hover part is displaying the resulting YARA rule and the expansion part allows you to add the rule as a new attribute, as usual with expansion modules.", - "input": "MISP Hash attribute (md5, sha1, sha256, imphash, or any of the composite attribute with filename and one of the previous hash type).", - "output": "YARA rule.", - "references": [ - "https://virustotal.github.io/yara/", - "https://github.com/virustotal/yara-python" - ] -} \ No newline at end of file diff --git a/documentation/website/expansion/yara_syntax_validator.json b/documentation/website/expansion/yara_syntax_validator.json deleted file mode 100644 index 72550b2b..00000000 --- a/documentation/website/expansion/yara_syntax_validator.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "An expansion hover module to perform a syntax check on if yara rules are valid or not.", - "logo": "yara.png", - "requirements": [ - "yara_python python library" - ], - "input": "YARA rule attribute.", - "output": "Text to inform users if their rule is valid.", - "references": [ - "http://virustotal.github.io/yara/" - ], - "features": "This modules simply takes a YARA rule as input, and checks its syntax. It returns then a confirmation if the syntax is valid, otherwise the syntax error is displayed." -} \ No newline at end of file diff --git a/documentation/website/expansion/yeti.json b/documentation/website/expansion/yeti.json deleted file mode 100644 index 93341dc5..00000000 --- a/documentation/website/expansion/yeti.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "description": "Module to process a query on Yeti.", - "logo": "yeti.png", - "requirements": ["pyeti", "API key "], - "input": "A domain, hostname,IP, sha256,sha1, md5, url of MISP attribute.", - "output": "MISP attributes and objects fetched from the Yeti instances.", - "references": ["https://github.com/yeti-platform/yeti", "https://github.com/sebdraven/pyeti"], - "features": "This module add context and links between observables using yeti" -} diff --git a/documentation/website/export_mod/cef_export.json b/documentation/website/export_mod/cef_export.json deleted file mode 100644 index cd247a72..00000000 --- a/documentation/website/export_mod/cef_export.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "Module to export a MISP event in CEF format.", - "requirements": [], - "features": "The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in Common Event Format.\nThus, there is no particular feature concerning MISP Events since any event can be exported. However, 4 configuration parameters recognized by CEF format are required and should be provided by users before exporting data: the device vendor, product and version, as well as the default severity of data.", - "references": [ - "https://community.softwaregrp.com/t5/ArcSight-Connectors/ArcSight-Common-Event-Format-CEF-Guide/ta-p/1589306?attachment-id=65537" - ], - "input": "MISP Event attributes", - "output": "Common Event Format file" -} \ No newline at end of file diff --git a/documentation/website/export_mod/cisco_firesight_manager_ACL_rule_export.json b/documentation/website/export_mod/cisco_firesight_manager_ACL_rule_export.json deleted file mode 100644 index b9c72f93..00000000 --- a/documentation/website/export_mod/cisco_firesight_manager_ACL_rule_export.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Module to export malicious network activity attributes to Cisco fireSIGHT manager block rules.", - "logo": "cisco.png", - "requirements": [ - "Firesight manager console credentials" - ], - "input": "Network activity attributes (IPs, URLs).", - "output": "Cisco fireSIGHT manager block rules.", - "references": [], - "features": "The module goes through the attributes to find all the network activity ones in order to create block rules for the Cisco fireSIGHT manager." -} \ No newline at end of file diff --git a/documentation/website/export_mod/defender_endpoint_export.json b/documentation/website/export_mod/defender_endpoint_export.json deleted file mode 100644 index ee45766e..00000000 --- a/documentation/website/export_mod/defender_endpoint_export.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Defender for Endpoint KQL hunting query export module", - "requirements": [], - "features": "This module export an event as Defender for Endpoint KQL queries that can then be used in your own python3 or Powershell tool. If you are using Microsoft Sentinel, you can directly connect your MISP instance to Sentinel and then create queries using the `ThreatIntelligenceIndicator` table to match events against imported IOC.", - "references": [ - "https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/advanced-hunting-schema-reference" - ], - "input": "MISP Event attributes", - "output": "Defender for Endpoint KQL queries", - "logo": "defender_endpoint.png" -} \ No newline at end of file diff --git a/documentation/website/export_mod/goamlexport.json b/documentation/website/export_mod/goamlexport.json deleted file mode 100644 index aaab295b..00000000 --- a/documentation/website/export_mod/goamlexport.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "This module is used to export MISP events containing transaction objects into GoAML format.", - "logo": "goAML.jpg", - "requirements": [ - "PyMISP", - "MISP objects" - ], - "features": "The module works as long as there is at least one transaction object in the Event.\n\nThen in order to have a valid GoAML document, please follow these guidelines:\n- For each transaction object, use either a bank-account, person, or legal-entity object to describe the origin of the transaction, and again one of them to describe the target of the transaction.\n- Create an object reference for both origin and target objects of the transaction.\n- A bank-account object needs a signatory, which is a person object, put as object reference of the bank-account.\n- A person can have an address, which is a geolocation object, put as object reference of the person.\n\nSupported relation types for object references that are recommended for each object are the folowing:\n- transaction:\n\t- 'from', 'from_my_client': Origin of the transaction - at least one of them is required.\n\t- 'to', 'to_my_client': Target of the transaction - at least one of them is required.\n\t- 'address': Location of the transaction - optional.\n- bank-account:\n\t- 'signatory': Signatory of a bank-account - the reference from bank-account to a signatory is required, but the relation-type is optional at the moment since this reference will always describe a signatory.\n\t- 'entity': Entity owning the bank account - optional.\n- person:\n\t- 'address': Address of a person - optional.", - "references": [ - "http://goaml.unodc.org/" - ], - "input": "MISP objects (transaction, bank-account, person, legal-entity, geolocation), with references, describing financial transactions and their origin and target.", - "output": "GoAML format file, describing financial transactions, with their origin and target (bank accounts, persons or entities)." -} \ No newline at end of file diff --git a/documentation/website/export_mod/liteexport.json b/documentation/website/export_mod/liteexport.json deleted file mode 100644 index 1f910399..00000000 --- a/documentation/website/export_mod/liteexport.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "description": "Lite export of a MISP event.", - "requirements": [], - "features": "This module is simply producing a json MISP event format file, but exporting only Attributes from the Event. Thus, MISP Events exported with this module should have attributes that are not internal references, otherwise the resulting event would be empty.", - "references": [], - "input": "MISP Event attributes", - "output": "Lite MISP Event" -} \ No newline at end of file diff --git a/documentation/website/export_mod/mass_eql_export.json b/documentation/website/export_mod/mass_eql_export.json deleted file mode 100644 index 30b12a9b..00000000 --- a/documentation/website/export_mod/mass_eql_export.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Mass EQL query export for a MISP event.", - "logo": "eql.png", - "requirements": [], - "features": "This module produces EQL queries for all relevant attributes in a MISP event.", - "references": [ - "https://eql.readthedocs.io/en/latest/" - ], - "input": "MISP Event attributes", - "output": "Text file containing one or more EQL queries" -} \ No newline at end of file diff --git a/documentation/website/export_mod/nexthinkexport.json b/documentation/website/export_mod/nexthinkexport.json deleted file mode 100644 index 0c06f9eb..00000000 --- a/documentation/website/export_mod/nexthinkexport.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Nexthink NXQL query export module", - "requirements": [], - "features": "This module export an event as Nexthink NXQL queries that can then be used in your own python3 tool or from wget/powershell", - "references": [ - "https://doc.nexthink.com/Documentation/Nexthink/latest/APIAndIntegrations/IntroducingtheWebAPIV2" - ], - "input": "MISP Event attributes", - "output": "Nexthink NXQL queries", - "logo": "nexthink.svg" -} \ No newline at end of file diff --git a/documentation/website/export_mod/osqueryexport.json b/documentation/website/export_mod/osqueryexport.json deleted file mode 100644 index 5b563c00..00000000 --- a/documentation/website/export_mod/osqueryexport.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "description": "OSQuery export of a MISP event.", - "requirements": [], - "features": "This module export an event as osquery queries that can be used in packs or in fleet management solution like Kolide.", - "references": [], - "input": "MISP Event attributes", - "output": "osquery SQL queries", - "logo": "osquery.png" -} \ No newline at end of file diff --git a/documentation/website/export_mod/pdfexport.json b/documentation/website/export_mod/pdfexport.json deleted file mode 100644 index b23c6815..00000000 --- a/documentation/website/export_mod/pdfexport.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Simple export of a MISP event to PDF.", - "requirements": [ - "PyMISP", - "reportlab" - ], - "features": "The module takes care of the PDF file building, and work with any MISP Event. Except the requirement of reportlab, used to create the file, there is no special feature concerning the Event. Some parameters can be given through the config dict. 'MISP_base_url_for_dynamic_link' is your MISP URL, to attach an hyperlink to your event on your MISP instance from the PDF. Keep it clear to avoid hyperlinks in the generated pdf.\n 'MISP_name_for_metadata' is your CERT or MISP instance name. Used as text in the PDF' metadata\n 'Activate_textual_description' is a boolean (True or void) to activate the textual description/header abstract of an event\n 'Activate_galaxy_description' is a boolean (True or void) to activate the description of event related galaxies.\n 'Activate_related_events' is a boolean (True or void) to activate the description of related event. Be aware this might leak information on confidential events linked to the current event !\n 'Activate_internationalization_fonts' is a boolean (True or void) to activate Noto fonts instead of default fonts (Helvetica). This allows the support of CJK alphabet. Be sure to have followed the procedure to download Noto fonts (~70Mo) in the right place (/tools/pdf_fonts/Noto_TTF), to allow PyMisp to find and use them during PDF generation.\n 'Custom_fonts_path' is a text (path or void) to the TTF file of your choice, to create the PDF with it. Be aware the PDF won't support bold/italic/special style anymore with this option ", - "references": [ - "https://acrobat.adobe.com/us/en/acrobat/about-adobe-pdf.html" - ], - "input": "MISP Event", - "output": "MISP Event in a PDF file." -} \ No newline at end of file diff --git a/documentation/website/export_mod/testexport.json b/documentation/website/export_mod/testexport.json deleted file mode 100644 index 884ccbe0..00000000 --- a/documentation/website/export_mod/testexport.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "Skeleton export module." -} \ No newline at end of file diff --git a/documentation/website/export_mod/threatStream_misp_export.json b/documentation/website/export_mod/threatStream_misp_export.json deleted file mode 100644 index b096f411..00000000 --- a/documentation/website/export_mod/threatStream_misp_export.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Module to export a structured CSV file for uploading to threatStream.", - "logo": "threatstream.png", - "requirements": [ - "csv" - ], - "features": "The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in a CSV format recognized by ThreatStream.", - "references": [ - "https://www.anomali.com/platform/threatstream", - "https://github.com/threatstream" - ], - "input": "MISP Event attributes", - "output": "ThreatStream CSV format file" -} \ No newline at end of file diff --git a/documentation/website/export_mod/threat_connect_export.json b/documentation/website/export_mod/threat_connect_export.json deleted file mode 100644 index 23708ddb..00000000 --- a/documentation/website/export_mod/threat_connect_export.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to export a structured CSV file for uploading to ThreatConnect.", - "logo": "threatconnect.png", - "requirements": [ - "csv" - ], - "features": "The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in a CSV format recognized by ThreatConnect.\nUsers should then provide, as module configuration, the source of data they export, because it is required by the output format.", - "references": [ - "https://www.threatconnect.com" - ], - "input": "MISP Event attributes", - "output": "ThreatConnect CSV format file" -} \ No newline at end of file diff --git a/documentation/website/export_mod/virustotal_collections.json b/documentation/website/export_mod/virustotal_collections.json deleted file mode 100644 index 1ecdbe92..00000000 --- a/documentation/website/export_mod/virustotal_collections.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "description": "Creates a VT Collection from an event iocs.", - "logo": "virustotal.png", - "requirements": [ - "An access to the VirusTotal API (apikey)." - ], - "input": "A domain, hash (md5, sha1, sha256 or sha512), hostname, url or IP address attribute.", - "output": "A VirusTotal collection in VT.", - "references": [ - "https://www.virustotal.com/", - "https://blog.virustotal.com/2021/11/introducing-virustotal-collections.html" - ], - "features": "This export module which takes advantage of a new endpoint in VT APIv3 to create VT Collections from IOCs contained in a MISP event. With this module users will be able to create a collection just using the Download as... button." -} diff --git a/documentation/website/export_mod/vt_graph.json b/documentation/website/export_mod/vt_graph.json deleted file mode 100644 index 993c7917..00000000 --- a/documentation/website/export_mod/vt_graph.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "This module is used to create a VirusTotal Graph from a MISP event.", - "logo": "virustotal.png", - "requirements": [ - "vt_graph_api, the python library to query the VirusTotal graph API" - ], - "features": "The module takes the MISP event as input and queries the VirusTotal Graph API to create a new graph out of the event.\n\nOnce the graph is ready, we get the url of it, which is returned so we can view it on VirusTotal.", - "references": [ - "https://www.virustotal.com/gui/graph-overview" - ], - "input": "A MISP event.", - "output": "Link of the VirusTotal Graph created for the event." -} \ No newline at end of file diff --git a/documentation/website/import_mod/cof2misp.json b/documentation/website/import_mod/cof2misp.json deleted file mode 100644 index cbbb0ccf..00000000 --- a/documentation/website/import_mod/cof2misp.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Passive DNS Common Output Format (COF) MISP importer", - "requirements": [ - "PyMISP" - ], - "features": "Takes as input a valid COF file or the output of the dnsdbflex utility and creates MISP objects for the input.", - "references": [ - "https://tools.ietf.org/id/draft-dulaunoy-dnsop-passive-dns-cof-08.html" - ], - "input": "Passive DNS output in Common Output Format (COF)", - "output": "MISP objects" -} diff --git a/documentation/website/import_mod/csvimport.json b/documentation/website/import_mod/csvimport.json deleted file mode 100644 index 61bc6ccd..00000000 --- a/documentation/website/import_mod/csvimport.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to import MISP attributes from a csv file.", - "requirements": [ - "PyMISP" - ], - "features": "In order to parse data from a csv file, a header is required to let the module know which column is matching with known attribute fields / MISP types.\n\nThis header either comes from the csv file itself or is part of the configuration of the module and should be filled out in MISP plugin settings, each field separated by COMMAS. Fields that do not match with any type known in MISP or are not MISP attribute fields should be ignored in import, using a space or simply nothing between two separators (example: 'ip-src, , comment, ').\n\nIf the csv file already contains a header that does not start by a '#', you should tick the checkbox 'has_header' to avoid importing it and have potential issues. You can also redefine the header even if it is already contained in the file, by following the rules for headers explained earlier. One reason why you would redefine a header is for instance when you want to skip some fields, or some fields are not valid types.", - "references": [ - "https://tools.ietf.org/html/rfc4180", - "https://tools.ietf.org/html/rfc7111" - ], - "input": "CSV format file.", - "output": "MISP Event attributes" -} \ No newline at end of file diff --git a/documentation/website/import_mod/cuckooimport.json b/documentation/website/import_mod/cuckooimport.json deleted file mode 100644 index 2e51ea8e..00000000 --- a/documentation/website/import_mod/cuckooimport.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Module to import Cuckoo JSON.", - "logo": "cuckoo.png", - "requirements": [], - "features": "The module simply imports MISP Attributes from a Cuckoo JSON format file. There is thus no special feature to make it work.", - "references": [ - "https://cuckoosandbox.org/", - "https://github.com/cuckoosandbox/cuckoo" - ], - "input": "Cuckoo JSON file", - "output": "MISP Event attributes" -} \ No newline at end of file diff --git a/documentation/website/import_mod/email_import.json b/documentation/website/import_mod/email_import.json deleted file mode 100644 index 95ec3c78..00000000 --- a/documentation/website/import_mod/email_import.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "description": "Module to import emails in MISP.", - "requirements": [], - "features": "This module can be used to import e-mail text as well as attachments and urls.\n3 configuration parameters are then used to unzip attachments, guess zip attachment passwords, and extract urls: set each one of them to True or False to process or not the respective corresponding actions.", - "references": [], - "input": "E-mail file", - "output": "MISP Event attributes" -} \ No newline at end of file diff --git a/documentation/website/import_mod/goamlimport.json b/documentation/website/import_mod/goamlimport.json deleted file mode 100644 index e8f12cfc..00000000 --- a/documentation/website/import_mod/goamlimport.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Module to import MISP objects about financial transactions from GoAML files.", - "logo": "goAML.jpg", - "requirements": [ - "PyMISP" - ], - "features": "Unlike the GoAML export module, there is here no special feature to import data from GoAML external files, since the module will import MISP Objects with their References on its own, as it is required for the export module to rebuild a valid GoAML document.", - "references": "http://goaml.unodc.org/", - "input": "GoAML format file, describing financial transactions, with their origin and target (bank accounts, persons or entities).", - "output": "MISP objects (transaction, bank-account, person, legal-entity, geolocation), with references, describing financial transactions and their origin and target." -} \ No newline at end of file diff --git a/documentation/website/import_mod/joe_import.json b/documentation/website/import_mod/joe_import.json deleted file mode 100644 index 234259f5..00000000 --- a/documentation/website/import_mod/joe_import.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "A module to import data from a Joe Sandbox analysis json report.", - "logo": "joesandbox.png", - "requirements": [], - "input": "Json report of a Joe Sandbox analysis.", - "output": "MISP attributes & objects parsed from the analysis report.", - "references": [ - "https://www.joesecurity.org", - "https://www.joesandbox.com/" - ], - "features": "Module using the new format of modules able to return attributes and objects.\n\nThe module returns the same results as the expansion module [joesandbox_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) using the submission link of the analysis to get the json report." -} diff --git a/documentation/website/import_mod/lastline_import.json b/documentation/website/import_mod/lastline_import.json deleted file mode 100644 index 17b899ad..00000000 --- a/documentation/website/import_mod/lastline_import.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description": "Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module.\n\nModule to import and parse reports from Lastline analysis links.", - "logo": "lastline.png", - "requirements": [], - "input": "Link to a Lastline analysis.", - "output": "MISP attributes and objects parsed from the analysis report.", - "references": [ - "https://www.lastline.com" - ], - "features": "The module requires a Lastline Portal `username` and `password`.\nThe module uses the new format and it is able to return MISP attributes and objects.\nThe module returns the same results as the [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) expansion module." -} \ No newline at end of file diff --git a/documentation/website/import_mod/mispjson.json b/documentation/website/import_mod/mispjson.json deleted file mode 100644 index 7ba47bd7..00000000 --- a/documentation/website/import_mod/mispjson.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "description": "Module to import MISP JSON format for merging MISP events.", - "requirements": [], - "features": "The module simply imports MISP Attributes from an other MISP Event in order to merge events together. There is thus no special feature to make it work.", - "references": [], - "input": "MISP Event", - "output": "MISP Event attributes" -} \ No newline at end of file diff --git a/documentation/website/import_mod/ocr.json b/documentation/website/import_mod/ocr.json deleted file mode 100644 index a33c7e24..00000000 --- a/documentation/website/import_mod/ocr.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "description": "Optical Character Recognition (OCR) module for MISP.", - "requirements": [], - "features": "The module tries to recognize some text from an image and import the result as a freetext attribute, there is then no special feature asked to users to make it work.", - "references": [], - "input": "Image", - "output": "freetext MISP attribute" -} \ No newline at end of file diff --git a/documentation/website/import_mod/openiocimport.json b/documentation/website/import_mod/openiocimport.json deleted file mode 100644 index 3e00baf5..00000000 --- a/documentation/website/import_mod/openiocimport.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Module to import OpenIOC packages.", - "requirements": [ - "PyMISP" - ], - "features": "The module imports MISP Attributes from OpenIOC packages, there is then no special feature for users to make it work.", - "references": [ - "https://www.fireeye.com/blog/threat-research/2013/10/openioc-basics.html" - ], - "input": "OpenIOC packages", - "output": "MISP Event attributes" -} \ No newline at end of file diff --git a/documentation/website/import_mod/threatanalyzer_import.json b/documentation/website/import_mod/threatanalyzer_import.json deleted file mode 100644 index 5866e090..00000000 --- a/documentation/website/import_mod/threatanalyzer_import.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "Module to import ThreatAnalyzer archive.zip / analysis.json files.", - "requirements": [], - "features": "The module imports MISP Attributes from a ThreatAnalyzer format file. This file can be either ZIP, or JSON format.\nThere is by the way no special feature for users to make the module work.", - "references": [ - "https://www.threattrack.com/malware-analysis.aspx" - ], - "input": "ThreatAnalyzer format file", - "output": "MISP Event attributes" -} \ No newline at end of file diff --git a/documentation/website/import_mod/vmray_import.json b/documentation/website/import_mod/vmray_import.json deleted file mode 100644 index c80b2375..00000000 --- a/documentation/website/import_mod/vmray_import.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "Module to import VMRay (VTI) results.", - "logo": "vmray.png", - "requirements": [ - "vmray_rest_api" - ], - "features": "The module imports MISP Attributes from VMRay format, using the VMRay api.\nUsers should then provide as the module configuration the API Key as well as the server url in order to fetch their data to import.", - "references": [ - "https://www.vmray.com/" - ], - "input": "VMRay format", - "output": "MISP Event attributes" -} \ No newline at end of file diff --git a/etc/systemd/system/misp-modules.service b/etc/systemd/system/misp-modules.service deleted file mode 100644 index 078ebecf..00000000 --- a/etc/systemd/system/misp-modules.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=System-wide instance of the MISP Modules -After=network.target - -[Service] -User=www-data -Group=www-data -WorkingDirectory=/usr/local/src/misp-modules -Environment="PATH=/var/www/MISP/venv/bin" -ExecStart=/var/www/MISP/venv/bin/misp-modules -l 127.0.0.1 - -[Install] -WantedBy=multi-user.target - diff --git a/misp_modules/__init__.py b/misp_modules/__init__.py index 290cbfbf..f8fbf86e 100644 --- a/misp_modules/__init__.py +++ b/misp_modules/__init__.py @@ -28,6 +28,9 @@ import argparse import re import datetime import psutil +import pkgutil +import platform +import typing try: import orjson as json @@ -41,6 +44,52 @@ from tornado.concurrent import run_on_executor from concurrent.futures import ThreadPoolExecutor from pymisp import pymisp_json_default + +import warnings +warnings.filterwarnings("ignore", category=SyntaxWarning) + + +LIBFAUP_PATHS = [ + "/usr/local/lib/", + "/usr/lib/", + "/opt/local/lib/", +] + +ARCH_TO_EXTENSION = { + "linux": "so", + "darwin": "dylib", +} + + +def _get_libfaup_path(lib_path: str) -> str: + extension = ARCH_TO_EXTENSION.get(platform.system().lower(), "lib") + return f"{lib_path.rstrip('/')}/libfaupl.{extension}" + + +def _replace_libfaup_path(module_path: str, libfaup_path: str) -> None: + with open(module_path, "r") as f: + file_data = f.read() + file_data = re.sub(r"cdll.LoadLibrary\(.*\)", f"cdll.LoadLibrary(\"{libfaup_path}\")", file_data) + with open(module_path, "w") as f: + f.write(file_data) + + +def _try_pyfaup_import(lib_path: typing.Optional[str]) -> None: + package = pkgutil.get_loader("pyfaup") + if not package: + return + if lib_path: + _replace_libfaup_path(package.path, _get_libfaup_path(lib_path)) + importlib.import_module("pyfaup") + + +for lib_path in [None, *LIBFAUP_PATHS]: + try: + _try_pyfaup_import(lib_path) + break + except OSError: + continue + try: from .modules import * # noqa HAS_PACKAGE_MODULES = True diff --git a/misp_modules/helpers/cache.py b/misp_modules/helpers/cache.py index f833b8e1..7b982132 100644 --- a/misp_modules/helpers/cache.py +++ b/misp_modules/helpers/cache.py @@ -27,12 +27,13 @@ import hashlib port = int(os.getenv("REDIS_PORT")) if os.getenv("REDIS_PORT") else 6379 hostname = os.getenv("REDIS_BACKEND") or '127.0.0.1' db = int(os.getenv("REDIS_DATABASE")) if os.getenv("REDIS_DATABASE") else 0 +password = os.getenv("REDIS_PW") or None def selftest(enable=True): if not enable: return False - r = redis.Redis(host=hostname, port=port, db=db) + r = redis.Redis(host=hostname, password=password, port=port, db=db) try: r.ping() except Exception: @@ -42,7 +43,7 @@ def selftest(enable=True): def get(modulename=None, query=None, value=None, debug=False): if (modulename is None or query is None): return False - r = redis.Redis(host=hostname, port=port, db=db, decode_responses=True) + r = redis.Redis(host=hostname, password=password, port=port, db=db, decode_responses=True) h = hashlib.sha1() h.update(query.encode('UTF-8')) hv = h.hexdigest() @@ -60,7 +61,7 @@ def get(modulename=None, query=None, value=None, debug=False): def flush(): - r = redis.StrictRedis(host=hostname, port=port, db=db, decode_responses=True) + r = redis.StrictRedis(host=hostname, password=password, port=port, db=db, decode_responses=True) returncode = r.flushdb() return returncode diff --git a/misp_modules/lib/vt_graph_parser/helpers/rules.py b/misp_modules/lib/vt_graph_parser/helpers/rules.py index e3ed7f83..92ad5d24 100644 --- a/misp_modules/lib/vt_graph_parser/helpers/rules.py +++ b/misp_modules/lib/vt_graph_parser/helpers/rules.py @@ -4,10 +4,10 @@ This module provides rules that helps MISP importers to connect MISP attributes between them using VirusTotal relationship. Check all available relationship here: -- File: https://developers.virustotal.com/v3/reference/#files-relationships -- URL: https://developers.virustotal.com/v3/reference/#urls-relationships -- Domain: https://developers.virustotal.com/v3/reference/#domains-relationships -- IP: https://developers.virustotal.com/v3/reference/#ip-relationships +- File: https://docs.virustotal.com/reference/files#relationships +- URL: https://docs.virustotal.com/reference/url-object#relationships +- Domain: https://docs.virustotal.com/reference/domains-object#relationships +- IP: https://docs.virustotal.com/reference/ip-object#relationships """ diff --git a/misp_modules/modules/action_mod/mattermost.py b/misp_modules/modules/action_mod/mattermost.py index 241a2dc9..49c8ab9a 100644 --- a/misp_modules/modules/action_mod/mattermost.py +++ b/misp_modules/modules/action_mod/mattermost.py @@ -42,12 +42,23 @@ moduleconfig = { # For blocking modules the actual boolean value determines whether we break execution returns = 'boolean' -moduleinfo = {'version': '0.1', 'author': 'Sami Mokaddem', - 'description': 'Simplistic module to send message to a Mattermost channel.', - 'module-type': ['action']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sami Mokaddem', + 'description': 'Simplistic module to send message to a Mattermost channel.', + 'module-type': ['action'], + 'name': 'Mattermost', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '' +} f = Faup() + def createPost(request): params = request['params'] f.decode(params['mattermost_hostname']) diff --git a/misp_modules/modules/action_mod/slack.py b/misp_modules/modules/action_mod/slack.py index cdfff74c..f0bda6b0 100644 --- a/misp_modules/modules/action_mod/slack.py +++ b/misp_modules/modules/action_mod/slack.py @@ -36,9 +36,19 @@ moduleconfig = { # For blocking modules, the actual boolean value determines whether we break execution returns = 'boolean' -moduleinfo = {'version': '0.1', 'author': 'goodlandsecurity', - 'description': 'Simplistic module to send messages to a Slack channel.', - 'module-type': ['action']} +moduleinfo = { + 'version': '0.1', + 'author': 'goodlandsecurity', + 'description': 'Simplistic module to send messages to a Slack channel.', + 'module-type': ['action'], + 'name': 'Slack', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '' +} def create_post(request): diff --git a/misp_modules/modules/action_mod/testaction.py b/misp_modules/modules/action_mod/testaction.py index d773c4ea..e85a9f17 100644 --- a/misp_modules/modules/action_mod/testaction.py +++ b/misp_modules/modules/action_mod/testaction.py @@ -1,5 +1,4 @@ import json -from ._utils import utils misperrors = {'error': 'Error'} @@ -31,9 +30,19 @@ moduleconfig = { # For blocking modules the actual boolean value determines whether we break execution returns = 'boolean' -moduleinfo = {'version': '0.1', 'author': 'Andras Iklody', - 'description': 'This module is merely a test, always returning true. Triggers on event publishing.', - 'module-type': ['action']} +moduleinfo = { + 'version': '0.1', + 'author': 'Andras Iklody', + 'description': 'This module is merely a test, always returning true. Triggers on event publishing.', + 'module-type': ['action'], + 'name': 'Test action', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '' +} def handler(q=False): diff --git a/misp_modules/modules/expansion/__init__.py b/misp_modules/modules/expansion/__init__.py index 8cb745af..7248af7c 100644 --- a/misp_modules/modules/expansion/__init__.py +++ b/misp_modules/modules/expansion/__init__.py @@ -3,10 +3,10 @@ import sys sys.path.append('{}/lib'.format('/'.join((os.path.realpath(__file__)).split('/')[:-3]))) -__all__ = ['cuckoo_submit', 'vmray_submit', 'bgpranking', 'circl_passivedns', 'circl_passivessl', +__all__ = ['cuckoo_submit', 'vmray_submit', 'circl_passivedns', 'circl_passivessl', 'cluster25_expand', 'countrycode', 'cve', 'cve_advanced', 'cpe', 'dns', 'btc_steroids', 'domaintools', 'eupi', 'eql', 'farsight_passivedns', 'ipasn', 'passivetotal', 'sourcecache', 'virustotal', - 'whois', 'shodan', 'reversedns', 'geoip_asn', 'geoip_city', 'geoip_country', 'wiki', 'iprep', + 'shodan', 'reversedns', 'geoip_asn', 'geoip_city', 'geoip_country', 'wiki', 'iprep', 'threatminer', 'otx', 'threatcrowd', 'vulndb', 'crowdstrike_falcon', 'yara_syntax_validator', 'hashdd', 'onyphe', 'onyphe_full', 'rbl', 'xforceexchange', 'sigma_syntax_validator', 'stix2_pattern_syntax_validator', @@ -17,10 +17,13 @@ __all__ = ['cuckoo_submit', 'vmray_submit', 'bgpranking', 'circl_passivedns', 'c 'virustotal_public', 'apiosintds', 'urlscan', 'securitytrails', 'apivoid', 'assemblyline_submit', 'assemblyline_query', 'ransomcoindb', 'malwarebazaar', 'lastline_query', 'lastline_submit', 'sophoslabs_intelix', 'cytomic_orion', 'censys_enrich', - 'trustar_enrich', 'recordedfuture', 'html_to_markdown', 'socialscan', 'passive-ssh', + 'trustar_enrich', 'recordedfuture', 'html_to_markdown', 'socialscan', 'passive_ssh', 'qintel_qsentry', 'mwdb', 'hashlookup', 'mmdb_lookup', 'ipqs_fraud_and_risk_scoring', - 'clamav', 'jinja_template_rendering','hyasinsight', 'variotdbs', 'crowdsec', - 'extract_url_components', 'ipinfo', 'whoisfreaks', 'ip2locationio', 'vysion', 'stairwell'] + 'clamav', 'jinja_template_rendering', 'hyasinsight', 'variotdbs', 'crowdsec', + 'extract_url_components', 'ipinfo', 'whoisfreaks', 'ip2locationio', 'stairwell', + 'google_threat_intelligence', 'vulnerability_lookup', 'vysion', 'mcafee_insights_enrich', + 'threatfox', 'yeti', 'abuseipdb', 'vmware_nsx', 'sigmf_expand', 'google_safe_browsing', + 'google_search', 'whois', 'triage_submit', 'virustotal_upload', 'malshare_upload' ] minimum_required_fields = ('type', 'uuid', 'value') diff --git a/var/.gitkeep b/misp_modules/modules/expansion/_vulnerability_parser/__init__.py similarity index 100% rename from var/.gitkeep rename to misp_modules/modules/expansion/_vulnerability_parser/__init__.py diff --git a/misp_modules/modules/expansion/_vulnerability_parser/vulnerability_parser.py b/misp_modules/modules/expansion/_vulnerability_parser/vulnerability_parser.py new file mode 100644 index 00000000..5f4d69cf --- /dev/null +++ b/misp_modules/modules/expansion/_vulnerability_parser/vulnerability_parser.py @@ -0,0 +1,118 @@ +import json +from pymisp import MISPAttribute, MISPEvent, MISPObject + + +class VulnerabilityMapping: + __variot_data_mapping = { + 'credits': 'credit', + 'description': 'description', + 'title': 'summary' + } + __variot_flat_mapping = { + 'cve': 'id', 'id': 'id' + } + + @classmethod + def exploit_mapping(cls) -> dict: + return cls.__exploit_mapping + + @classmethod + def exploit_multiple_mapping(cls) -> dict: + return cls.__exploit_multiple_mapping + + @classmethod + def variot_data_mapping(cls) -> dict: + return cls.__variot_data_mapping + + @classmethod + def variot_flat_mapping(cls) -> dict: + return cls.__variot_flat_mapping + + +class VulnerabilityParser: + def __init__(self, attribute: dict): + misp_attribute = MISPAttribute() + misp_attribute.from_dict(**attribute) + misp_event = MISPEvent() + misp_event.add_attribute(**misp_attribute) + self.__misp_attribute = misp_attribute + self.__misp_event = misp_event + + @property + def misp_attribute(self): + return self.__misp_attribute + + @property + def misp_event(self): + return self.__misp_event + + def get_results(self) -> dict: + event = json.loads(self.misp_event.to_json()) + return { + 'results': { + key: value for key, value in event.items() + if key in ('Attribute', 'Object') + } + } + + def _parse_variot_description(self, query_results): + vulnerability_object = MISPObject('vulnerability') + for field, relation in self.mapping.variot_flat_mapping().items(): + if query_results.get(field): + vulnerability_object.add_attribute( + relation, query_results[field] + ) + for field, relation in self.mapping.variot_data_mapping().items(): + if query_results.get(field, {}).get('data'): + vulnerability_object.add_attribute( + relation, query_results[field]['data'] + ) + if query_results.get('configurations', {}).get('data'): + for configuration in query_results['configurations']['data']: + for node in configuration['nodes']: + for cpe_match in node['cpe_match']: + if cpe_match['vulnerable']: + vulnerability_object.add_attribute( + 'vulnerable-configuration', + cpe_match['cpe23Uri'] + ) + if query_results.get('cvss', {}).get('data'): + cvss = {} + for cvss_data in query_results['cvss']['data']: + for cvss_v3 in cvss_data['cvssV3']: + cvss[float(cvss_v3['trust'])] = cvss_v3 + if cvss: + cvss = cvss[max(cvss)] + vulnerability_object.add_attribute( + 'cvss-score', cvss['baseScore'] + ) + vulnerability_object.add_attribute( + 'cvss-string', cvss['vectorString'] + ) + if query_results.get('references', {}).get('data'): + for reference in query_results['references']['data']: + vulnerability_object.add_attribute( + 'references', reference['url'] + ) + if query_results.get('sources_release_date', {}).get('data'): + for release_date in query_results['sources_release_date']['data']: + if release_date['db'] != 'NVD': + continue + if release_date['id'] == self.misp_attribute.value: + vulnerability_object.add_attribute( + 'published', release_date['date'] + ) + break + if query_results.get('sources_update_date', {}).get('data'): + for update_date in query_results['sources_update_date']['data']: + if update_date['db'] != 'NVD': + continue + if update_date['id'] == self.misp_attribute.value: + vulnerability_object.add_attribute( + 'modified', update_date['date'] + ) + break + vulnerability_object.add_reference( + self.misp_attribute.uuid, 'related-to' + ) + self.misp_event.add_object(vulnerability_object) diff --git a/misp_modules/modules/expansion/abuseipdb.py b/misp_modules/modules/expansion/abuseipdb.py index afab5c96..ba09a4c1 100644 --- a/misp_modules/modules/expansion/abuseipdb.py +++ b/misp_modules/modules/expansion/abuseipdb.py @@ -6,9 +6,19 @@ import dns.resolver misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-dst', 'hostname', 'domain', 'domain|ip'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.1', 'author': 'Stephanie S', - 'description': 'AbuseIPDB MISP expansion module', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Stephanie S', + 'description': 'AbuseIPDB MISP expansion module', + 'module-type': ['expansion', 'hover'], + 'name': 'Abuse IPDB', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} moduleconfig = ['api_key', 'max_age_in_days', 'abuse_threshold'] @@ -52,8 +62,8 @@ def handler(q=False): else: ip = request["attribute"]["value"] - - api_key = request["config"]["api_key"] + + api_key = request["config"]["api_key"] max_age_in_days = request["config"]["max_age_in_days"] api_endpoint = 'https://api.abuseipdb.com/api/v2/check' querystring = { @@ -64,13 +74,13 @@ def handler(q=False): 'Accept': 'application/json', 'key': api_key } - r = {"results": []} + r = {"results": []} response = requests.request(method='GET', url=api_endpoint, headers=headers, params=querystring) if (response.status_code == 200): response_json = json.loads(response.text) - is_whitelisted = response_json['data']['isWhitelisted'] + is_whitelisted = response_json['data']['isWhitelisted'] is_tor = response_json['data']['isTor'] is_public = response_json['data']['isPublic'] abuse_confidence_score = response_json['data']['abuseConfidenceScore'] @@ -112,7 +122,7 @@ def handler(q=False): obj.add_attribute('abuse-confidence-score', **{'type': 'counter', 'value': abuse_confidence_score}) obj.add_reference(request['attribute']['uuid'], "describes") event.add_object(obj) - + # Avoid serialization issue event = json.loads(event.to_json()) @@ -120,7 +130,7 @@ def handler(q=False): return r else: - try: + try: response_json = json.loads(response.text) if (response_json['errors']): return {"error": "API not reachable, status code: " + str(response.status_code) + " " + str(response_json['errors'][0]['detail'])} diff --git a/misp_modules/modules/expansion/apiosintds.py b/misp_modules/modules/expansion/apiosintds.py index 4dddf0d7..51448ba5 100644 --- a/misp_modules/modules/expansion/apiosintds.py +++ b/misp_modules/modules/expansion/apiosintds.py @@ -19,9 +19,19 @@ mispattributes = {'input': ["domain", "domain|ip", "hostname", "ip-dst", "ip-src 'output': ["domain", "ip-dst", "url", "comment", "md5", "sha1", "sha256", "link", "text"] } -moduleinfo = {'version': '0.2', 'author': 'Davide Baglieri aka davidonzo', - 'description': 'On demand query API for OSINT.digitalside.it project.', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.2', + 'author': 'Davide Baglieri aka davidonzo', + 'description': 'On demand query API for OSINT.digitalside.it project.', + 'module-type': ['expansion', 'hover'], + 'name': 'OSINT DigitalSide', + 'logo': '', + 'requirements': ['The apiosintDS python library to query the OSINT.digitalside.it API.'], + 'features': 'The module simply queries the API of OSINT.digitalside.it with a domain, ip, url or hash attribute.\n\nThe result of the query is then parsed to extract additional hashes or urls. A module parameters also allows to parse the hashes related to the urls.\n\nFurthermore, it is possible to cache the urls and hashes collected over the last 7 days by OSINT.digitalside.it', + 'references': ['https://osint.digitalside.it/#About'], + 'input': 'A domain, ip, url or hash attribute.', + 'output': 'Hashes and urls resulting from the query to OSINT.digitalside.it', +} moduleconfig = ['STIX2_details', 'import_related', 'cache', 'cache_directory', 'cache_timeout_h', 'local_directory'] @@ -62,7 +72,7 @@ def handler(q=False): tosubmit.append(request['filename|sha256'].split('|')[1]) else: return False - + persistent = 0 if request.get('persistent'): persistent = request["persistent"] @@ -77,19 +87,19 @@ def handler(q=False): r = {"results": []} if request.get('config'): - + if request['config'].get('cache') and request['config']['cache'].lower() == "yes": submitcache = True - + if request['config'].get('import_related') and request['config']['import_related'].lower() == "yes": import_related = True - + if request['config'].get('STIX2_details') and request['config']['STIX2_details'].lower() == "yes": submit_stix = True - + if request['config'].get('cache_timeout_h') and len(request['config']['cache_timeout_h']) > 0: submitcache_timeout = int(request['config'].get('cache_timeout_h')) - + localdirectory = request['config'].get('local_directory') if localdirectory and len(localdirectory) > 0: if os.access(localdirectory, os.R_OK): @@ -149,33 +159,33 @@ def apiosintParserHover(ispersistent, response, import_related, stix): commentH = "IoC '"+item["item"] + "' found in OSINT.DigitaiSide.it repository." CommentHDate = "List file: "+response[key]["list"]["file"]+". Date list: " + response[key]["list"]["date"] ret.append({"types": ["text"], "values": [comment]}) - + retHover.append({"types": ["text"], "values": [commentH]}) retHover.append({"types": ["text"], "values": [CommentHDate]}) retHover.append({"types": ["text"], "values": [line]}) - + if key in ["url", "hash"]: if "hashes" in item: headhash = "Hashes set" retHover.append({"types": ["text"], "values": [headhash]}) if "md5" in item["hashes"].keys(): ret.append({"types": ["md5"], "values": [item["hashes"]["md5"]], "comment": "Related to: " + item["item"]}) - + strmd5 = "MD5: "+item["hashes"]["md5"] retHover.append({"types": ["text"], "values": [strmd5]}) - + if "sha1" in item["hashes"].keys(): ret.append({"types": ["sha1"], "values": [item["hashes"]["sha1"]], "comment": "Related to: " + item["item"]}) - + strsha1 = "SHA1: "+item["hashes"]["sha1"] retHover.append({"types": ["text"], "values": [strsha1]}) - + if "sha256" in item["hashes"].keys(): ret.append({"types": ["sha256"], "values": [item["hashes"]["sha256"]], "comment": "Related to: " + item["item"]}) - + strsha256 = "SHA256: "+item["hashes"]["sha256"] retHover.append({"types": ["text"], "values": [strsha256]}) - + if "online_reports" in item: headReports = "Online Reports (availability depends on retention)" retHover.append({"types": ["text"], "values": [linedot]}) @@ -185,17 +195,17 @@ def apiosintParserHover(ispersistent, response, import_related, stix): ret.append({"category": "External analysis", "types": ["link"], "values": [onlierepor["MISP_CSV"]], "comment": "MISP CSV related to: " + item["item"]}) ret.append({"category": "External analysis", "types": ["link"], "values": [onlierepor["OSINTDS_REPORT"]], "comment": "DigitalSide report related to: " + item["item"]}) ret.append({"category": "External analysis", "types": ["link"], "values": [onlierepor["STIX"]], "comment": "STIX2 report related to: " + item["item"]}) - + MISPEVENT = "MISP Event => "+onlierepor["MISP_EVENT"] MISPCSV = "MISP CSV => "+onlierepor["MISP_CSV"] OSINTDS = "DigitalSide report => "+onlierepor["OSINTDS_REPORT"] STIX = "STIX report => "+onlierepor["STIX"] - + retHover.append({"types": ["text"], "values": [MISPEVENT]}) retHover.append({"types": ["text"], "values": [MISPCSV]}) retHover.append({"types": ["text"], "values": [OSINTDS]}) retHover.append({"types": ["text"], "values": [STIX]}) - + if stix and onlierepor: if "STIXDETAILS" in onlierepor: retHover.append({"types": ["text"], "values": [linedot]}) @@ -205,31 +215,31 @@ def apiosintParserHover(ispersistent, response, import_related, stix): ret.append({"types": ["comment"], "values": [stxdet], "comment": "STIX2 details for: " + item["item"]}) retHover.append({"types": ["text"], "values": [headStix]}) retHover.append({"types": ["text"], "values": [stxdet]}) - - + + if stixobj["observed_time_frame"] != False: obstf = "Observation time frame: "+str(stixobj["observed_time_frame"]) ret.append({"types": ["comment"], "values": [obstf], "comment": "STIX2 details for: " + item["item"]}) retHover.append({"types": ["text"], "values": [obstf]}) - + filename = stixobj["filename"] ret.append({"category": "Payload delivery", "types": ["filename"], "values": [filename], "comment": "STIX2 details for: " + item["item"]}) - + Hovefilename = "Filename: "+filename retHover.append({"types": ["text"], "values": [Hovefilename]}) - + filesize = stixobj["filesize"] ret.append({"types": ["size-in-bytes"], "values": [filesize], "comment": "STIX2 details for: " + item["item"]}) - + Hovefilesize = "Filesize in bytes: "+str(filesize) retHover.append({"types": ["text"], "values": [Hovefilesize]}) - + filetype = stixobj["mime_type"] ret.append({"category": "Payload delivery", "types": ["mime-type"], "values": [filetype], "comment": "STIX2 details for: " + item["item"]}) - + Hovemime = "Filetype: "+filetype retHover.append({"types": ["text"], "values": [Hovemime]}) - + if "virus_total" in stixobj: if stixobj["virus_total"] != False: VTratio = "VirusTotal Ratio: "+str(stixobj["virus_total"]["vt_detection_ratio"]) @@ -247,31 +257,31 @@ def apiosintParserHover(ispersistent, response, import_related, stix): if isinstance(urls, dict): itemToInclude = urls["url"] ret.append({"types": ["url"], "values": [itemToInclude], "comment": "Download URL for "+urls["hashes"]["md5"]+". Related to: " + item["item"]}) - + retHover.append({"types": ["text"], "values": [linedot]}) relatedURL = "Related URL "+itemToInclude retHover.append({"types": ["text"], "values": [relatedURL]}) - + if "hashes" in urls.keys(): if "md5" in urls["hashes"].keys(): ret.append({"types": ["md5"], "values": [urls["hashes"]["md5"]], "comment": "Related to: " + itemToInclude}) - + strmd5 = "MD5: "+urls["hashes"]["md5"] retHover.append({"types": ["text"], "values": [strmd5]}) - + if "sha1" in urls["hashes"].keys(): ret.append({"types": ["sha1"], "values": [urls["hashes"]["sha1"]], "comment": "Related to: " + itemToInclude}) - + strsha1 = "SHA1: "+urls["hashes"]["sha1"] retHover.append({"types": ["text"], "values": [strsha1]}) - + if "sha256" in urls["hashes"].keys(): ret.append({"types": ["sha256"], "values": [urls["hashes"]["sha256"]], "comment": "Related to: " + itemToInclude}) - + strsha256 = "SHA256: "+urls["hashes"]["sha256"] retHover.append({"types": ["text"], "values": [strsha256]}) - + headReports = "Online Reports (availability depends on retention)" retHover.append({"types": ["text"], "values": [linedotty]}) retHover.append({"types": ["text"], "values": [headReports]}) @@ -300,42 +310,42 @@ def apiosintParserHover(ispersistent, response, import_related, stix): ret.append({"types": ["comment"], "values": [stxdet], "comment": "STIX2 details for: " + item["item"]}) retHover.append({"types": ["text"], "values": [headStix]}) retHover.append({"types": ["text"], "values": [stxdet]}) - + if stixobj["observed_time_frame"] != False: obstf = "Observation time frame: "+str(stixobj["observed_time_frame"]) ret.append({"types": ["comment"], "values": [obstf], "comment": "STIX2 details for: " + item["item"]}) retHover.append({"types": ["text"], "values": [obstf]}) - + filename = stixobj["filename"] ret.append({"category": "Payload delivery", "types": ["filename"], "values": [filename], "comment": "STIX2 details for: " + item["item"]}) - + Hovefilename = "Filename: "+filename retHover.append({"types": ["text"], "values": [Hovefilename]}) - + filesize = stixobj["filesize"] ret.append({"types": ["size-in-bytes"], "values": [filesize], "comment": "STIX2 details for: " + item["item"]}) - + Hovefilesize = "Filesize in bytes: "+str(filesize) retHover.append({"types": ["text"], "values": [Hovefilesize]}) - + filetype = stixobj["mime_type"] ret.append({"category": "Payload delivery", "types": ["mime-type"], "values": [filetype], "comment": "STIX2 details for: " + item["item"]}) - + Hovemime = "Filetype: "+filetype retHover.append({"types": ["text"], "values": [Hovemime]}) - + if "virus_total" in stixobj: if stixobj["virus_total"] != False: VTratio = "VirusTotal Ratio: "+stixobj["virus_total"]["vt_detection_ratio"] ret.append({"types": ["comment"], "values": [VTratio], "comment": "STIX2 details for: " + item["item"]}) retHover.append({"types": ["text"], "values": [VTratio]}) - + VTReport = stixobj["virus_total"]["vt_report"] ret.append({"category": "External analysis", "types": ["link"], "values": [VTReport], "comment": "VirusTotal Report for: " + item["item"]}) - else: + else: ret.append({"types": ["url"], "values": [urls], "comment": "Download URL for: " + item["item"]}) urlHover = "URL => "+urls - retHover.append({"types": ["text"], "values": [urlHover]}) + retHover.append({"types": ["text"], "values": [urlHover]}) else: notfound = item["item"] + " IS NOT listed by OSINT.digitalside.it. Date list: " + response[key]["list"]["date"] ret.append({"types": ["comment"], "values": [notfound]}) diff --git a/misp_modules/modules/expansion/apivoid.py b/misp_modules/modules/expansion/apivoid.py index fc0d43ec..3410617b 100755 --- a/misp_modules/modules/expansion/apivoid.py +++ b/misp_modules/modules/expansion/apivoid.py @@ -5,9 +5,19 @@ from pymisp import MISPAttribute, MISPEvent, MISPObject misperrors = {'error': 'Error'} mispattributes = {'input': ['domain', 'hostname', 'email', 'email-src', 'email-dst', 'email-reply-to', 'dns-soa-email', 'target-email', 'whois-registrant-email'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.2', 'author': 'Christian Studer', - 'description': 'On demand query API for APIVoid.', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.2', + 'author': 'Christian Studer', + 'description': 'Module to query APIVoid with some domain attributes.', + 'module-type': ['expansion', 'hover'], + 'name': 'APIVoid', + 'logo': 'apivoid.png', + 'requirements': ['A valid APIVoid API key with enough credits to proceed 2 queries'], + 'features': 'This module takes a domain name and queries API Void to get the related DNS records and the SSL certificates. It returns then those pieces of data as MISP objects that can be added to the event.\n\nTo make it work, a valid API key and enough credits to proceed 2 queries (0.06 + 0.07 credits) are required.', + 'references': ['https://www.apivoid.com/'], + 'input': 'A domain attribute.', + 'output': 'DNS records and SSL certificates related to the domain.', +} moduleconfig = ['apikey'] diff --git a/misp_modules/modules/expansion/assemblyline_query.py b/misp_modules/modules/expansion/assemblyline_query.py index 90bdd3c1..3c5867c3 100644 --- a/misp_modules/modules/expansion/assemblyline_query.py +++ b/misp_modules/modules/expansion/assemblyline_query.py @@ -8,9 +8,19 @@ from pymisp import MISPAttribute, MISPEvent, MISPObject misperrors = {'error': 'Error'} mispattributes = {'input': ['link'], 'format': 'misp_standard'} -moduleinfo = {'version': '1', 'author': 'Christian Studer', - 'description': 'Query AssemblyLine with a report URL to get the parsed data.', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '1', + 'author': 'Christian Studer', + 'description': 'A module tu query the AssemblyLine API with a submission ID to get the submission report and parse it.', + 'module-type': ['expansion'], + 'name': 'AssemblyLine Query', + 'logo': 'assemblyline.png', + 'requirements': ['assemblyline_client: Python library to query the AssemblyLine rest API.'], + 'features': 'The module requires the address of the AssemblyLine server you want to query as well as your credentials used for this instance. Credentials include the used-ID and an API key or the password associated to the user-ID.\n\nThe submission ID extracted from the submission link is then used to query AssemblyLine and get the full submission report. This report is parsed to extract file objects and the associated IPs, domains or URLs the files are connecting to.\n\nSome more data may be parsed in the future.', + 'references': ['https://www.cyber.gc.ca/en/assemblyline'], + 'input': 'Link of an AssemblyLine submission report.', + 'output': 'MISP attributes & objects parsed from the AssemblyLine submission.', +} moduleconfig = ["apiurl", "user_id", "apikey", "password", "verifyssl"] diff --git a/misp_modules/modules/expansion/assemblyline_submit.py b/misp_modules/modules/expansion/assemblyline_submit.py index 9e019ffe..9d3681c5 100644 --- a/misp_modules/modules/expansion/assemblyline_submit.py +++ b/misp_modules/modules/expansion/assemblyline_submit.py @@ -5,8 +5,19 @@ from assemblyline_client import Client, ClientError from urllib.parse import urljoin -moduleinfo = {"version": 1, "author": "Christian Studer", "module-type": ["expansion"], - "description": "Submit files or URLs to AssemblyLine"} +moduleinfo = { + 'version': 1, + 'author': 'Christian Studer', + 'module-type': ['expansion'], + 'name': 'AssemblyLine Submit', + 'description': 'A module to submit samples and URLs to AssemblyLine for advanced analysis, and return the link of the submission.', + 'logo': 'assemblyline.png', + 'requirements': ['assemblyline_client: Python library to query the AssemblyLine rest API.'], + 'features': 'The module requires the address of the AssemblyLine server you want to query as well as your credentials used for this instance. Credentials include the user-ID and an API key or the password associated to the user-ID.\n\nIf the sample or url is correctly submitted, you get then the link of the submission.', + 'references': ['https://www.cyber.gc.ca/en/assemblyline'], + 'input': 'Sample, or url to submit to AssemblyLine.', + 'output': 'Link of the report generated in AssemblyLine.', +} moduleconfig = ["apiurl", "user_id", "apikey", "password", "verifyssl"] mispattributes = {"input": ["attachment", "malware-sample", "url"], "output": ["link"]} diff --git a/misp_modules/modules/expansion/backscatter_io.py b/misp_modules/modules/expansion/backscatter_io.py index 07969176..d226f503 100644 --- a/misp_modules/modules/expansion/backscatter_io.py +++ b/misp_modules/modules/expansion/backscatter_io.py @@ -8,9 +8,19 @@ except ImportError: misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-dst'], 'output': ['freetext']} -moduleinfo = {'version': '1', 'author': 'brandon@backscatter.io', - 'description': 'Backscatter.io module to bring mass-scanning observations into MISP.', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '1', + 'author': 'brandon@backscatter.io', + 'description': 'Backscatter.io module to bring mass-scanning observations into MISP.', + 'module-type': ['expansion', 'hover'], + 'name': 'Backscatter.io', + 'logo': 'backscatter_io.png', + 'requirements': ['backscatter python library'], + 'features': 'The module takes a source or destination IP address as input and displays the information known by backscatter.io.', + 'references': ['https://pypi.org/project/backscatter/'], + 'input': 'IP addresses.', + 'output': 'Text containing a history of the IP addresses especially on scanning based on backscatter.io information .', +} moduleconfig = ['api_key'] query_playbook = [ {'inputs': ['ip-src', 'ip-dst'], diff --git a/misp_modules/modules/expansion/bgpranking.py b/misp_modules/modules/expansion/bgpranking.py deleted file mode 100755 index c021d62e..00000000 --- a/misp_modules/modules/expansion/bgpranking.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- coding: utf-8 -*- - -import json -from . import check_input_attribute, standard_error_message -from datetime import date, datetime, timedelta -from pybgpranking import BGPRanking -from pymisp import MISPAttribute, MISPEvent, MISPObject - -misperrors = {'error': 'Error'} -mispattributes = {'input': ['AS'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.1', 'author': 'Raphaël Vinot', - 'description': 'Query BGP Ranking to get the ranking of an Autonomous System number.', - 'module-type': ['expansion', 'hover']} - - -def handler(q=False): - if q is False: - return False - request = json.loads(q) - if not request.get('attribute') or not check_input_attribute(request['attribute']): - return {'error': f'{standard_error_message}, which should contain at least a type, a value and an uuid.'} - toquery = request['attribute'] - if toquery['type'] not in mispattributes['input']: - return {'error': 'Unsupported attribute type.'} - - bgpranking = BGPRanking() - value_toquery = int(toquery['value'][2:]) if toquery['value'].startswith('AS') else int(toquery['value']) - values = bgpranking.query(value_toquery, date=(date.today() - timedelta(1)).isoformat()) - - if not values['response'] or not values['response']['asn_description']: - misperrors['error'] = 'There is no result about this ASN in BGP Ranking' - return misperrors - - event = MISPEvent() - attribute = MISPAttribute() - attribute.from_dict(**toquery) - event.add_attribute(**attribute) - - asn_object = MISPObject('asn') - asn_object.add_attribute(**{ - 'type': 'AS', - 'object_relation': 'asn', - 'value': values['meta']['asn'] - }) - description, country = values['response']['asn_description'].split(', ') - for relation, value in zip(('description', 'country'), (description, country)): - asn_object.add_attribute(**{ - 'type': 'text', - 'object_relation': relation, - 'value': value - }) - - mapping = { - 'address_family': {'type': 'text', 'object_relation': 'address-family'}, - 'date': {'type': 'datetime', 'object_relation': 'date'}, - 'position': {'type': 'float', 'object_relation': 'position'}, - 'rank': {'type': 'float', 'object_relation': 'ranking'} - } - bgp_object = MISPObject('bgp-ranking') - for feature in ('rank', 'position'): - bgp_attribute = {'value': values['response']['ranking'][feature]} - bgp_attribute.update(mapping[feature]) - bgp_object.add_attribute(**bgp_attribute) - date_attribute = {'value': datetime.strptime(values['meta']['date'], '%Y-%m-%d')} - date_attribute.update(mapping['date']) - bgp_object.add_attribute(**date_attribute) - address_attribute = {'value': values['meta']['address_family']} - address_attribute.update(mapping['address_family']) - bgp_object.add_attribute(**address_attribute) - - asn_object.add_reference(attribute.uuid, 'describes') - asn_object.add_reference(bgp_object.uuid, 'ranked-with') - event.add_object(asn_object) - event.add_object(bgp_object) - - event = json.loads(event.to_json()) - results = {key: event[key] for key in ('Attribute', 'Object')} - return {'results': results} - - -def introspection(): - return mispattributes - - -def version(): - return moduleinfo diff --git a/misp_modules/modules/expansion/btc_scam_check.py b/misp_modules/modules/expansion/btc_scam_check.py index 44fa7326..8b577da4 100644 --- a/misp_modules/modules/expansion/btc_scam_check.py +++ b/misp_modules/modules/expansion/btc_scam_check.py @@ -12,9 +12,19 @@ except ImportError: misperrors = {'error': 'Error'} mispattributes = {'input': ['btc'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Christian Studer', - 'description': 'Checks if a BTC address has been abused.', - 'module-type': ['hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Christian Studer', + 'description': 'An expansion hover module to query a special dns blacklist to check if a bitcoin address has been abused.', + 'module-type': ['hover'], + 'name': 'BTC Scam Check', + 'logo': 'bitcoin.png', + 'requirements': ['dnspython3: dns python library'], + 'features': 'The module queries a dns blacklist directly with the bitcoin address and get a response if the address has been abused.', + 'references': ['https://btcblack.it/'], + 'input': 'btc address attribute.', + 'output': 'Text to indicate if the BTC address has been abused.', +} moduleconfig = [] url = 'bl.btcblack.it' diff --git a/misp_modules/modules/expansion/btc_steroids.py b/misp_modules/modules/expansion/btc_steroids.py index 04b71383..899c64b0 100755 --- a/misp_modules/modules/expansion/btc_steroids.py +++ b/misp_modules/modules/expansion/btc_steroids.py @@ -4,10 +4,19 @@ import time misperrors = {'error': 'Error'} mispattributes = {'input': ['btc'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Sascha Rommelfangen', - 'description': 'BTC expansion service to \ - get quick information from MISP attributes', - 'module-type': ['hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sascha Rommelfangen', + 'description': 'An expansion hover module to get a blockchain balance from a BTC address in MISP.', + 'module-type': ['hover'], + 'name': 'BTC Steroids', + 'logo': 'bitcoin.png', + 'requirements': [], + 'features': '', + 'references': [], + 'input': 'btc address attribute.', + 'output': 'Text to describe the blockchain balance and the transactions related to the btc address in input.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/censys_enrich.py b/misp_modules/modules/expansion/censys_enrich.py index f423712d..8531a606 100644 --- a/misp_modules/modules/expansion/censys_enrich.py +++ b/misp_modules/modules/expansion/censys_enrich.py @@ -28,8 +28,19 @@ misperrors = {'error': 'Error'} moduleconfig = ['api_id', 'api_secret'] mispattributes = {'input': ['ip-src', 'ip-dst', 'domain', 'hostname', 'hostname|port', 'domain|ip', 'ip-dst|port', 'ip-src|port', 'x509-fingerprint-md5', 'x509-fingerprint-sha1', 'x509-fingerprint-sha256'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.1', 'author': 'Loïc Fortemps', - 'description': 'Censys.io expansion module', 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Loïc Fortemps', + 'description': 'An expansion module to enrich attributes in MISP by quering the censys.io API', + 'module-type': ['expansion', 'hover'], + 'name': 'Censys Enrich', + 'logo': '', + 'requirements': ['API credentials to censys.io'], + 'features': 'This module takes an IP, hostname or a certificate fingerprint and attempts to enrich it by querying the Censys API.', + 'references': ['https://www.censys.io'], + 'input': 'IP, domain or certificate fingerprint (md5, sha1 or sha256)', + 'output': 'MISP objects retrieved from censys, including open ports, ASN, Location of the IP, x509 details', +} api_id = None api_secret = None diff --git a/misp_modules/modules/expansion/circl_passivedns.py b/misp_modules/modules/expansion/circl_passivedns.py index eca78c8b..c02d4b9d 100755 --- a/misp_modules/modules/expansion/circl_passivedns.py +++ b/misp_modules/modules/expansion/circl_passivedns.py @@ -3,9 +3,20 @@ from . import check_input_attribute, standard_error_message from pymisp import MISPAttribute, MISPEvent, MISPObject mispattributes = {'input': ['hostname', 'domain', 'ip-src', 'ip-dst', 'ip-src|port', 'ip-dst|port'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.2', 'author': 'Alexandre Dulaunoy', - 'description': 'Module to access CIRCL Passive DNS', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.2', + 'author': 'Alexandre Dulaunoy', + 'description': 'Module to access CIRCL Passive DNS.', + 'module-type': ['expansion', 'hover'], + 'name': 'CIRCL Passive DNS', + 'logo': 'passivedns.png', + 'requirements': ['pypdns: Passive DNS python library', 'A CIRCL passive DNS account with username & password'], + 'features': 'This module takes a hostname, domain or ip-address (ip-src or ip-dst) attribute as input, and queries the CIRCL Passive DNS REST API to get the asssociated passive dns entries and return them as MISP objects.\n\nTo make it work a username and a password are thus required to authenticate to the CIRCL Passive DNS API.', + 'references': ['https://www.circl.lu/services/passive-dns/', 'https://datatracker.ietf.org/doc/draft-dulaunoy-dnsop-passive-dns-cof/'], + 'input': 'Hostname, domain, or ip-address attribute.', + 'output': '', + 'ouput': 'Passive DNS objects related to the input attribute.', +} moduleconfig = ['username', 'password'] diff --git a/misp_modules/modules/expansion/circl_passivessl.py b/misp_modules/modules/expansion/circl_passivessl.py index 65783d76..e04adcf1 100755 --- a/misp_modules/modules/expansion/circl_passivessl.py +++ b/misp_modules/modules/expansion/circl_passivessl.py @@ -4,9 +4,19 @@ from . import check_input_attribute, standard_error_message from pymisp import MISPAttribute, MISPEvent, MISPObject mispattributes = {'input': ['ip-src', 'ip-dst', 'ip-src|port', 'ip-dst|port'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.2', 'author': 'Raphaël Vinot', - 'description': 'Module to access CIRCL Passive SSL', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.2', + 'author': 'Raphaël Vinot', + 'description': 'Modules to access CIRCL Passive SSL.', + 'module-type': ['expansion', 'hover'], + 'name': 'CIRCL Passive SSL', + 'logo': 'passivessl.png', + 'requirements': ['pypssl: Passive SSL python library', 'A CIRCL passive SSL account with username & password'], + 'features': 'This module takes an ip-address (ip-src or ip-dst) attribute as input, and queries the CIRCL Passive SSL REST API to gather the related certificates and return the corresponding MISP objects.\n\nTo make it work a username and a password are required to authenticate to the CIRCL Passive SSL API.', + 'references': ['https://www.circl.lu/services/passive-ssl/'], + 'input': 'IP address attribute.', + 'output': 'x509 certificate objects seen by the IP address(es).', +} moduleconfig = ['username', 'password'] diff --git a/misp_modules/modules/expansion/clamav.py b/misp_modules/modules/expansion/clamav.py index bdff3b51..61d848df 100644 --- a/misp_modules/modules/expansion/clamav.py +++ b/misp_modules/modules/expansion/clamav.py @@ -19,10 +19,17 @@ sh.setFormatter(fmt) log.addHandler(sh) moduleinfo = { - "version": "0.1", - "author": "Jakub Onderka", - "description": "Submit file to ClamAV", - "module-type": ["expansion"] + 'version': '0.1', + 'author': 'Jakub Onderka', + 'description': 'Submit file to ClamAV', + 'module-type': ['expansion'], + 'name': 'ClaamAV', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', } moduleconfig = ["connection"] mispattributes = { diff --git a/misp_modules/modules/expansion/cluster25_expand.py b/misp_modules/modules/expansion/cluster25_expand.py index 5da8c476..31eb6361 100755 --- a/misp_modules/modules/expansion/cluster25_expand.py +++ b/misp_modules/modules/expansion/cluster25_expand.py @@ -4,10 +4,19 @@ import uuid from . import check_input_attribute, standard_error_message from pymisp import MISPAttribute, MISPEvent, MISPObject -moduleinfo = {'version': '0.1', - 'author': 'Milo Volpicelli', - 'description': 'Module to query Cluster25CTI', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Milo Volpicelli', + 'description': 'Module to query Cluster25 CTI.', + 'module-type': ['expansion', 'hover'], + 'name': 'Cluster25 Expand', + 'logo': 'cluster25.png', + 'requirements': ['A Cluster25 API access (API id & key)'], + 'features': 'This module takes a MISP attribute value as input to query the Cluster25CTI API. The result is then mapped into compatible MISP Objects and relative attributes.\n', + 'references': [''], + 'input': 'An Indicator value of type included in the following list:\n- domain\n- email-src\n- email-dst\n- filename\n- md5\n- sha1\n- sha256\n- ip-src\n- ip-dst\n- url\n- vulnerability\n- btc\n- xmr\n ja3-fingerprint-md5', + 'output': 'A series of c25 MISP Objects with colletion of attributes mapped from Cluster25 CTI query result.', +} moduleconfig = ['api_id', 'apikey', 'base_url'] misperrors = {'error': 'Error'} misp_type_in = ['domain', 'email-src', 'email-dst', 'filename', 'md5', 'sha1', 'sha256', 'ip-src', 'ip-dst', 'url', diff --git a/misp_modules/modules/expansion/countrycode.py b/misp_modules/modules/expansion/countrycode.py index 1de56e0f..0bf74088 100755 --- a/misp_modules/modules/expansion/countrycode.py +++ b/misp_modules/modules/expansion/countrycode.py @@ -5,9 +5,19 @@ misperrors = {'error': 'Error'} mispattributes = {'input': ['hostname', 'domain']} # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '1', 'author': 'Hannah Ward', - 'description': 'Expand Country Codes', - 'module-type': ['hover']} +moduleinfo = { + 'version': '1', + 'author': 'Hannah Ward', + 'description': 'Module to expand country codes.', + 'module-type': ['hover'], + 'name': 'Country Code', + 'logo': '', + 'requirements': [], + 'features': 'The module takes a domain or a hostname as input, and returns the country it belongs to.\n\nFor non country domains, a list of the most common possible extensions is used.', + 'references': [], + 'input': 'Hostname or domain attribute.', + 'output': 'Text with the country code the input belongs to.', +} # config fields that your code expects from the site admin moduleconfig = [] diff --git a/misp_modules/modules/expansion/cpe.py b/misp_modules/modules/expansion/cpe.py index 600ff37e..bd721fdc 100644 --- a/misp_modules/modules/expansion/cpe.py +++ b/misp_modules/modules/expansion/cpe.py @@ -8,8 +8,15 @@ mispattributes = {'input': ['cpe'], 'format': 'misp_standard'} moduleinfo = { 'version': '2', 'author': 'Christian Studer', - 'description': 'An expansion module to enrich a CPE attribute with its related vulnerabilities.', - 'module-type': ['expansion', 'hover'] + 'description': 'An expansion module to query the CVE search API with a cpe code to get its related vulnerabilities.', + 'module-type': ['expansion', 'hover'], + 'name': 'CPE Lookup', + 'logo': 'cve.png', + 'requirements': [], + 'features': 'The module takes a cpe attribute as input and queries the CVE search API to get its related vulnerabilities. \nThe list of vulnerabilities is then parsed and returned as vulnerability objects.\n\nUsers can use their own CVE search API url by defining a value to the custom_API_URL parameter. If no custom API url is given, the default vulnerability.circl.lu api url is used.\n\nIn order to limit the amount of data returned by CVE serach, users can also the limit parameter. With the limit set, the API returns only the requested number of vulnerabilities, sorted from the highest cvss score to the lowest one.', + 'references': ['https://vulnerability.circl.lu/api/'], + 'input': 'CPE attribute.', + 'output': 'The vulnerabilities related to the CPE.', } moduleconfig = ["custom_API_URL", "limit"] cveapi_url = 'https://cvepremium.circl.lu/api/query' diff --git a/misp_modules/modules/expansion/crowdsec.py b/misp_modules/modules/expansion/crowdsec.py index 5b250ce8..983ac88b 100644 --- a/misp_modules/modules/expansion/crowdsec.py +++ b/misp_modules/modules/expansion/crowdsec.py @@ -1,17 +1,40 @@ +import ipaddress import json + import pycountry import requests -from . import check_input_attribute, standard_error_message from pymisp import MISPEvent, MISPObject +from . import check_input_attribute, standard_error_message + mispattributes = {"input": ["ip-dst", "ip-src"], "format": "misp_standard"} moduleinfo = { - "version": "2.0", + "version": "2.1", "author": "Shivam Sandbhor ", "description": "Module to access CrowdSec CTI API.", "module-type": ["hover", "expansion"], + "name": "CrowdSec CTI", + "logo": "crowdsec.png", + "requirements": [ + "A CrowdSec CTI API key. Get yours by following https://docs.crowdsec.net/docs/cti_api/getting_started/#getting-an-api-key" + ], + "features": "This module enables IP lookup from CrowdSec CTI API. It provides information about the IP, such as what kind of attacks it has been participant of as seen by CrowdSec's network. It also includes enrichment by CrowdSec like background noise score, aggressivity over time etc.", + "references": [ + "https://www.crowdsec.net/", + "https://docs.crowdsec.net/docs/cti_api/getting_started", + "https://app.crowdsec.net/", + ], + "input": "An IP address.", + "output": "IP Lookup information from CrowdSec CTI API", } -moduleconfig = ["api_key"] +moduleconfig = [ + "api_key", + "add_reputation_tag", + "add_behavior_tag", + "add_classification_tag", + "add_mitre_technique_tag", + "add_cve_tag", +] def handler(q=False): @@ -25,106 +48,182 @@ def handler(q=False): if not request["config"].get("api_key"): return {"error": "Missing CrowdSec API key"} - if not request.get('attribute') or not check_input_attribute(request['attribute']): - return {'error': f'{standard_error_message}, which shoul contain at least a type, a value and an uuid.'} + if not request.get("attribute") or not check_input_attribute(request["attribute"]): + return { + "error": f"{standard_error_message}, which should contain at least a type, a value and an uuid." + } - if request['attribute'].get('type') not in mispattributes['input']: - return {'error': f"Wrong input type. Please choose on of the following: {', '.join(mispattributes['input'])}"} + if request["attribute"].get("type") not in mispattributes["input"]: + return { + "error": f"Wrong input type. Please choose on of the following: {', '.join(mispattributes['input'])}" + } return _handler_v2(request) +def _get_boolean_config(request_data, config: str, default_config: bool): + if request_data["config"].get(config) is None: + return default_config + raw_config = request_data["config"].get(config).lower() + # falsy values, return False + if raw_config in ["false", "0", "no", "off"]: + return False + # truthy values, return True + if raw_config in ["true", "1", "yes", "on"]: + return True + return default_config + + def _handler_v2(request_data): - attribute = request_data['attribute'] - ip = attribute['value'] + attribute = request_data["attribute"] + ip = attribute["value"] + # Validate IP + try: + ipaddress.ip_address(ip) + except ValueError: + return { + "error": f"IP ({ip}) is not valid for calling CrowdSec CTI. Please provide a valid IP address." + } crowdsec_cti = requests.get( f"https://cti.api.crowdsec.net/v2/smoke/{ip}", headers={ "x-api-key": request_data["config"]["api_key"], - "User-Agent": "crowdsec-misp/v1.0.0", - } + "User-Agent": "crowdsec-misp/v2.1.1", + }, ) crowdsec_cti.raise_for_status() crowdsec_cti = crowdsec_cti.json() + add_reputation_tag = _get_boolean_config(request_data, "add_reputation_tag", True) + add_behavior_tag = _get_boolean_config(request_data, "add_behavior_tag", True) + add_classification_tag = _get_boolean_config( + request_data, "add_classification_tag", True + ) + add_mitre_technique_tag = _get_boolean_config( + request_data, "add_mitre_technique_tag", True + ) + add_cve_tag = _get_boolean_config(request_data, "add_cve_tag", True) + misp_event = MISPEvent() misp_attribute = misp_event.add_attribute(**attribute) crowdsec_context_object = MISPObject("crowdsec-ip-context") crowdsec_context_object.from_dict( first_seen=crowdsec_cti["history"]["first_seen"], - last_seen=crowdsec_cti["history"]["last_seen"] + last_seen=crowdsec_cti["history"]["last_seen"], ) ip_attribute = crowdsec_context_object.add_attribute("ip", crowdsec_cti["ip"]) + reputation = crowdsec_cti["reputation"] or "unknown" + crowdsec_context_object.add_attribute("reputation", reputation) + if add_reputation_tag: + tag = f'crowdsec:reputation="{reputation}"' + ip_attribute.add_tag(tag) crowdsec_context_object.add_attribute("ip-range", crowdsec_cti["ip_range"]) - crowdsec_context_object.add_attribute("ip-range-score", crowdsec_cti["ip_range_score"]) + crowdsec_context_object.add_attribute( + "ip-range-score", crowdsec_cti["ip_range_score"] + ) crowdsec_context_object.add_attribute( "country", get_country_name_from_alpha_2(crowdsec_cti["location"]["country"]) ) - crowdsec_context_object.add_attribute("country-code", crowdsec_cti["location"]["country"]) + crowdsec_context_object.add_attribute( + "country-code", crowdsec_cti["location"]["country"] + ) if crowdsec_cti["location"].get("city"): - crowdsec_context_object.add_attribute( - "city", crowdsec_cti["location"]["city"] - ) - crowdsec_context_object.add_attribute("latitude", crowdsec_cti["location"]["latitude"]) - crowdsec_context_object.add_attribute("longitude", crowdsec_cti["location"]["longitude"]) + crowdsec_context_object.add_attribute("city", crowdsec_cti["location"]["city"]) + crowdsec_context_object.add_attribute( + "latitude", crowdsec_cti["location"]["latitude"] + ) + crowdsec_context_object.add_attribute( + "longitude", crowdsec_cti["location"]["longitude"] + ) crowdsec_context_object.add_attribute("as-name", crowdsec_cti["as_name"]) crowdsec_context_object.add_attribute("as-num", crowdsec_cti["as_num"]) - if crowdsec_cti.get('reverse_dns') is not None: - crowdsec_context_object.add_attribute("reverse-dns", crowdsec_cti["reverse_dns"]) - crowdsec_context_object.add_attribute('background-noise', crowdsec_cti['background_noise_score']) + if crowdsec_cti.get("reverse_dns") is not None: + crowdsec_context_object.add_attribute( + "reverse-dns", crowdsec_cti["reverse_dns"] + ) + crowdsec_context_object.add_attribute( + "background-noise", crowdsec_cti["background_noise_score"] + ) for behavior in crowdsec_cti["behaviors"]: crowdsec_context_object.add_attribute( - "behaviors", behavior["label"], - comment=behavior['description'] + "behaviors", behavior["label"], comment=behavior["description"] ) - tag = f'crowdsec:behavior="{behavior["name"]}"' - ip_attribute.add_tag(tag) - for feature, values in crowdsec_cti['classifications'].items(): + if add_behavior_tag: + tag = f'crowdsec:behavior="{behavior["name"]}"' + ip_attribute.add_tag(tag) + for technique in crowdsec_cti["mitre_techniques"]: + technique_name = technique["name"] + mitre_url = ( + f"https://attack.mitre.org/tactics/{technique_name}" + if technique_name.startswith("TA") + else f"https://attack.mitre.org/techniques/{technique_name}" + ) + crowdsec_context_object.add_attribute( + "mitre-techniques", + technique["label"], + comment=f'{technique["description"]} ({mitre_url})', + ) + if add_mitre_technique_tag: + tag = f'crowdsec:mitre-technique="{technique_name}"' + ip_attribute.add_tag(tag) + + for cve in crowdsec_cti["cves"]: + cve_url = f"https://nvd.nist.gov/vuln/detail/{cve}" + crowdsec_context_object.add_attribute("cves", cve, comment=cve_url) + if add_cve_tag: + tag = f'crowdsec:cve="{cve}"' + ip_attribute.add_tag(tag) + + for feature, values in crowdsec_cti["classifications"].items(): field = feature[:-1] for value in values: crowdsec_context_object.add_attribute( - feature, value['label'], comment=value['description'] + feature, value["label"], comment=value["description"] ) - tag = f'crowdsec:{field}="{value["name"]}"' - ip_attribute.add_tag(tag) + if add_classification_tag: + tag = f'crowdsec:{field}="{value["name"]}"' + ip_attribute.add_tag(tag) crowdsec_context_object.add_attribute( "attack-details", ", ".join( f"{scenario['name']} - {scenario['label']} ({scenario['description']})" for scenario in crowdsec_cti["attack_details"] - ) + ), ) crowdsec_context_object.add_attribute( "target-countries", ", ".join( - map( - get_country_name_from_alpha_2, - crowdsec_cti["target_countries"].keys() - ) - ) + map(get_country_name_from_alpha_2, crowdsec_cti["target_countries"].keys()) + ), + ) + crowdsec_context_object.add_attribute( + "trust", crowdsec_cti["scores"]["overall"]["trust"] ) - crowdsec_context_object.add_attribute("trust", crowdsec_cti["scores"]["overall"]["trust"]) scores = [] for time_period, indicators in crowdsec_cti["scores"].items(): - tp = ' '.join(map(str.capitalize, time_period.split('_'))) + tp = " ".join(map(str.capitalize, time_period.split("_"))) indicator = ( - f'{indicator_type.capitalize()}: {indicator_value}' + f"{indicator_type.capitalize()}: {indicator_value}" for indicator_type, indicator_value in indicators.items() ) scores.append(f"{tp}: {' - '.join(indicator)}") - crowdsec_context_object.add_attribute('scores', ', '.join(scores)) - crowdsec_context_object.add_reference(misp_attribute.uuid, 'related-to') + crowdsec_context_object.add_attribute("scores", ", ".join(scores)) + crowdsec_context_object.add_reference(misp_attribute.uuid, "related-to") misp_event.add_object(crowdsec_context_object) event = json.loads(misp_event.to_json()) - results = {key: event[key] for key in ("Attribute", "Object") if (key in event and event[key])} + results = { + key: event[key] + for key in ("Attribute", "Object") + if (key in event and event[key]) + } return {"results": results} def get_country_name_from_alpha_2(alpha_2): country_info = pycountry.countries.get(alpha_2=alpha_2) - return country_info.name + return country_info.name if country_info else None def introspection(): diff --git a/misp_modules/modules/expansion/crowdstrike_falcon.py b/misp_modules/modules/expansion/crowdstrike_falcon.py index c26d59fb..43467d3e 100755 --- a/misp_modules/modules/expansion/crowdstrike_falcon.py +++ b/misp_modules/modules/expansion/crowdstrike_falcon.py @@ -3,10 +3,19 @@ from . import check_input_attribute, standard_error_message from falconpy import Intel from pymisp import MISPAttribute, MISPEvent -moduleinfo = {'version': '0.2', - 'author': 'Christophe Vandeplas', - 'description': 'Module to query CrowdStrike Falcon.', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.2', + 'author': 'Christophe Vandeplas', + 'description': 'Module to query CrowdStrike Falcon.', + 'module-type': ['expansion', 'hover'], + 'name': 'CrowdStrike Falcon', + 'logo': 'crowdstrike.png', + 'requirements': ['A CrowdStrike API access (API id & key)'], + 'features': 'This module takes a MISP attribute as input to query a CrowdStrike Falcon API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes.\n\nPlease note that composite attributes composed by at least one of the input types mentionned below (domains, IPs, hostnames) are also supported.', + 'references': ['https://www.crowdstrike.com/products/crowdstrike-falcon-faq/'], + 'input': 'A MISP attribute included in the following list:\n- domain\n- email-attachment\n- email-dst\n- email-reply-to\n- email-src\n- email-subject\n- filename\n- hostname\n- ip-src\n- ip-dst\n- md5\n- mutex\n- regkey\n- sha1\n- sha256\n- uri\n- url\n- user-agent\n- whois-registrant-email\n- x509-fingerprint-md5', + 'output': 'MISP attributes mapped after the CrowdStrike API has been queried, included in the following list:\n- hostname\n- email-src\n- email-subject\n- filename\n- md5\n- sha1\n- sha256\n- ip-dst\n- ip-dst\n- mutex\n- regkey\n- url\n- user-agent\n- x509-fingerprint-md5', +} moduleconfig = ['api_id', 'apikey'] misperrors = {'error': 'Error'} misp_type_in = ['domain', 'email-attachment', 'email-dst', 'email-reply-to', 'email-src', 'email-subject', diff --git a/misp_modules/modules/expansion/cuckoo_submit.py b/misp_modules/modules/expansion/cuckoo_submit.py index c1ded90c..91269744 100644 --- a/misp_modules/modules/expansion/cuckoo_submit.py +++ b/misp_modules/modules/expansion/cuckoo_submit.py @@ -20,9 +20,17 @@ sh.setFormatter(fmt) log.addHandler(sh) moduleinfo = { - "version": "0.1", "author": "Evert Kors", - "description": "Submit files and URLs to Cuckoo Sandbox", - "module-type": ["expansion", "hover"] + 'version': '0.1', + 'author': 'Evert Kors', + 'description': 'Submit files and URLs to Cuckoo Sandbox', + 'module-type': ['expansion', 'hover'], + 'name': 'Cuckoo Submit', + 'logo': 'cuckoo.png', + 'requirements': ['Access to a Cuckoo Sandbox API and an API key if the API requires it. (api_url and api_key)'], + 'features': 'The module takes a malware-sample, attachment, url or domain and submits it to Cuckoo Sandbox.\n The returned task id can be used to retrieve results when the analysis completed.', + 'references': ['https://cuckoosandbox.org/', 'https://cuckoo.sh/docs/'], + 'input': 'A malware-sample or attachment for files. A url or domain for URLs.', + 'output': "A text field containing 'Cuckoo task id: '", } misperrors = {"error": "Error"} moduleconfig = ["api_url", "api_key"] diff --git a/misp_modules/modules/expansion/cve.py b/misp_modules/modules/expansion/cve.py index 90c46bfd..e92466de 100755 --- a/misp_modules/modules/expansion/cve.py +++ b/misp_modules/modules/expansion/cve.py @@ -3,9 +3,21 @@ import requests misperrors = {'error': 'Error'} mispattributes = {'input': ['vulnerability'], 'output': ['text']} -moduleinfo = {'version': '0.3', 'author': 'Alexandre Dulaunoy', 'description': 'An expansion hover module to expand information about CVE id.', 'module-type': ['hover']} +moduleinfo = { + 'version': '0.4', + 'author': 'Alexandre Dulaunoy', + 'description': 'An expansion hover module to expand information about CVE id.', + 'module-type': ['hover'], + 'name': 'CVE Lookup', + 'logo': 'cve.png', + 'requirements': [], + 'features': 'The module takes a vulnerability attribute as input and queries the CIRCL CVE search API to get information about the vulnerability as it is described in the list of CVEs.', + 'references': ['https://vulnerability.circl.lu/', 'https://cve.mitre.org/'], + 'input': 'Vulnerability attribute.', + 'output': 'Text giving information about the CVE related to the Vulnerability.', +} moduleconfig = ["custom_API"] -cveapi_url = 'https://cve.circl.lu/api/cve/' +cveapi_url = 'https://vulnerability.circl.lu/api/cve/' def check_url(url): @@ -24,10 +36,9 @@ def handler(q=False): r = requests.get("{}{}".format(api_url, request.get('vulnerability'))) if r.status_code == 200: vulnerability = json.loads(r.text) - if vulnerability: - if vulnerability.get('summary'): - summary = vulnerability['summary'] - else: + try: + summary = vulnerability['containers']['cna']['descriptions'][0]['value'] + except Exception: summary = 'Non existing CVE' else: misperrors['error'] = 'API not accessible' diff --git a/misp_modules/modules/expansion/cve_advanced.py b/misp_modules/modules/expansion/cve_advanced.py index 32f86d10..b1e4c841 100644 --- a/misp_modules/modules/expansion/cve_advanced.py +++ b/misp_modules/modules/expansion/cve_advanced.py @@ -6,9 +6,19 @@ from pymisp import MISPAttribute, MISPEvent, MISPObject misperrors = {'error': 'Error'} mispattributes = {'input': ['vulnerability'], 'format': 'misp_standard'} -moduleinfo = {'version': '2', 'author': 'Christian Studer', - 'description': 'An expansion module to enrich a CVE attribute with the vulnerability information.', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '2', + 'author': 'Christian Studer', + 'description': 'An expansion module to query the CIRCL CVE search API for more information about a vulnerability (CVE).', + 'module-type': ['expansion', 'hover'], + 'name': 'CVE Advanced Lookup', + 'logo': 'cve.png', + 'requirements': [], + 'features': 'The module takes a vulnerability attribute as input and queries the CIRCL CVE search API to gather additional information.\n\nThe result of the query is then parsed to return additional information about the vulnerability, like its cvss score or some references, as well as the potential related weaknesses and attack patterns.\n\nThe vulnerability additional data is returned in a vulnerability MISP object, and the related additional information are put into weakness and attack-pattern MISP objects.', + 'references': ['https://vulnerability.circl.lu', 'https://cve/mitre.org/'], + 'input': 'Vulnerability attribute.', + 'output': 'Additional information about the vulnerability, such as its cvss score, some references, or the related weaknesses and attack patterns.', +} moduleconfig = ["custom_API"] cveapi_url = 'https://cvepremium.circl.lu/api/' diff --git a/misp_modules/modules/expansion/cytomic_orion.py b/misp_modules/modules/expansion/cytomic_orion.py index c13b2540..41750bd9 100755 --- a/misp_modules/modules/expansion/cytomic_orion.py +++ b/misp_modules/modules/expansion/cytomic_orion.py @@ -15,9 +15,19 @@ import sys misperrors = {'error': 'Error'} mispattributes = {'input': ['md5'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.3', 'author': 'Koen Van Impe', - 'description': 'an expansion module to enrich attributes in MISP and share indicators of compromise with Cytomic Orion', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.3', + 'author': 'Koen Van Impe', + 'description': 'An expansion module to enrich attributes in MISP by quering the Cytomic Orion API', + 'module-type': ['expansion'], + 'name': 'Cytomic Orion Lookup', + 'logo': 'cytomic_orion.png', + 'requirements': ['Access (license) to Cytomic Orion'], + 'features': 'This module takes an MD5 hash and searches for occurrences of this hash in the Cytomic Orion database. Returns observed files and machines.', + 'references': ['https://www.vanimpe.eu/2020/03/10/integrating-misp-and-cytomic-orion/', 'https://www.cytomicmodel.com/solutions/'], + 'input': 'MD5, hash of the sample / malware to search for.', + 'output': 'MISP objects with sightings of the hash in Cytomic Orion. Includes files and machines.', +} moduleconfig = ['api_url', 'token_url', 'clientid', 'clientsecret', 'clientsecret', 'username', 'password', 'upload_timeframe', 'upload_tag', 'delete_tag', 'upload_ttlDays', 'upload_threat_level_id', 'limit_upload_events', 'limit_upload_attributes'] # There are more config settings in this module than used by the enrichment # There is also a PyMISP module which reuses the module config, and requires additional configuration, for example used for pushing indicators to the API diff --git a/misp_modules/modules/expansion/dbl_spamhaus.py b/misp_modules/modules/expansion/dbl_spamhaus.py index 2bccd008..f27a3ff8 100644 --- a/misp_modules/modules/expansion/dbl_spamhaus.py +++ b/misp_modules/modules/expansion/dbl_spamhaus.py @@ -15,9 +15,19 @@ except ImportError: misperrors = {'error': 'Error'} mispattributes = {'input': ['domain', 'domain|ip', 'hostname', 'hostname|port'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Christian Studer', - 'description': 'Checks Spamhaus DBL for a domain name.', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Christian Studer', + 'description': 'Checks Spamhaus DBL for a domain name.', + 'module-type': ['expansion', 'hover'], + 'name': 'DBL Spamhaus Lookup', + 'logo': 'spamhaus.jpg', + 'requirements': ['dnspython3: DNS python3 library'], + 'features': 'This modules takes a domain or a hostname in input and queries the Domain Block List provided by Spamhaus to determine what kind of domain it is.\n\nDBL then returns a response code corresponding to a certain classification of the domain we display. If the queried domain is not in the list, it is also mentionned.\n\nPlease note that composite MISP attributes containing domain or hostname are supported as well.', + 'references': ['https://www.spamhaus.org/faq/section/Spamhaus%20DBL'], + 'input': 'Domain or hostname attribute.', + 'output': 'Information about the nature of the input.', +} moduleconfig = [] dbl = 'dbl.spamhaus.org' diff --git a/misp_modules/modules/expansion/dns.py b/misp_modules/modules/expansion/dns.py index 4ab238c0..657f7d98 100755 --- a/misp_modules/modules/expansion/dns.py +++ b/misp_modules/modules/expansion/dns.py @@ -4,9 +4,19 @@ import dns.resolver misperrors = {'error': 'Error'} mispattributes = {'input': ['hostname', 'domain', 'domain|ip'], 'output': ['ip-src', 'ip-dst']} -moduleinfo = {'version': '0.3', 'author': 'Alexandre Dulaunoy', - 'description': 'Simple DNS expansion service to resolve IP address from MISP attributes', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.3', + 'author': 'Alexandre Dulaunoy', + 'description': 'jj', + 'module-type': ['expansion', 'hover'], + 'name': 'DNS Resolver', + 'logo': '', + 'requirements': ['dnspython3: DNS python3 library'], + 'features': 'The module takes a domain of hostname attribute as input, and tries to resolve it. If no error is encountered, the IP address that resolves the domain is returned, otherwise the origin of the error is displayed.\n\nThe address of the DNS resolver to use is also configurable, but if no configuration is set, we use the Google public DNS address (8.8.8.8).\n\nPlease note that composite MISP attributes containing domain or hostname are supported as well.', + 'references': [], + 'input': 'Domain or hostname attribute.', + 'output': 'IP address resolving the input.', +} moduleconfig = ['nameserver'] diff --git a/misp_modules/modules/expansion/docx_enrich.py b/misp_modules/modules/expansion/docx_enrich.py index d5da3f86..aaf269df 100644 --- a/misp_modules/modules/expansion/docx_enrich.py +++ b/misp_modules/modules/expansion/docx_enrich.py @@ -7,9 +7,19 @@ import io misperrors = {'error': 'Error'} mispattributes = {'input': ['attachment'], 'output': ['freetext', 'text']} -moduleinfo = {'version': '0.1', 'author': 'Sascha Rommelfangen', - 'description': '.docx to freetext-import IOC extractor', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sascha Rommelfangen', + 'description': 'Module to extract freetext from a .docx document.', + 'module-type': ['expansion'], + 'name': 'DOCX Enrich', + 'logo': 'docx.png', + 'requirements': ['docx python library'], + 'features': 'The module reads the text contained in a .docx document. The result is passed to the freetext import parser so IoCs can be extracted out of it.', + 'references': [], + 'input': 'Attachment attribute containing a .docx document.', + 'output': 'Text and freetext parsed from the document.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/domaintools.py b/misp_modules/modules/expansion/domaintools.py index 353b4566..c70b7f7e 100755 --- a/misp_modules/modules/expansion/domaintools.py +++ b/misp_modules/modules/expansion/domaintools.py @@ -29,7 +29,14 @@ moduleinfo = { 'version': '0.1', 'author': 'Raphaël Vinot', 'description': 'DomainTools MISP expansion module.', - 'module-type': ['expansion', 'hover'] + 'module-type': ['expansion', 'hover'], + 'name': 'DomainTools Lookup', + 'logo': 'domaintools.png', + 'requirements': ['Domaintools python library', 'A Domaintools API access (username & apikey)'], + 'features': 'This module takes a MISP attribute as input to query the Domaintools API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes.\n\nPlease note that composite attributes composed by at least one of the input types mentionned below (domains, IPs, hostnames) are also supported.', + 'references': ['https://www.domaintools.com/'], + 'input': 'A MISP attribute included in the following list:\n- domain\n- hostname\n- email-src\n- email-dst\n- target-email\n- whois-registrant-email\n- whois-registrant-name\n- whois-registrant-phone\n- ip-src\n- ip-dst', + 'output': 'MISP attributes mapped after the Domaintools API has been queried, included in the following list:\n- whois-registrant-email\n- whois-registrant-phone\n- whois-registrant-name\n- whois-registrar\n- whois-creation-date\n- text\n- domain', } moduleconfig = ['username', 'api_key'] diff --git a/misp_modules/modules/expansion/eql.py b/misp_modules/modules/expansion/eql.py index 46cc05e3..e2b51bd7 100644 --- a/misp_modules/modules/expansion/eql.py +++ b/misp_modules/modules/expansion/eql.py @@ -7,10 +7,17 @@ import logging misperrors = {"error": "Error"} moduleinfo = { - "version": "0.1", - "author": "92 COS DOM", - "description": "Generates EQL queries from events", - "module-type": ["expansion"] + 'version': '0.1', + 'author': '92 COS DOM', + 'description': 'EQL query generation for a MISP attribute.', + 'module-type': ['expansion'], + 'name': 'EQL Query Generator', + 'logo': 'eql.png', + 'requirements': [], + 'features': 'This module adds a new attribute to a MISP event containing an EQL query for a network or file attribute.', + 'references': ['https://eql.readthedocs.io/en/latest/'], + 'input': 'A filename or ip attribute.', + 'output': 'Attribute containing EQL for a network or file attribute.', } # Map of MISP fields => Endgame fields diff --git a/misp_modules/modules/expansion/eupi.py b/misp_modules/modules/expansion/eupi.py index e230bcf5..9b6f9481 100755 --- a/misp_modules/modules/expansion/eupi.py +++ b/misp_modules/modules/expansion/eupi.py @@ -5,9 +5,19 @@ from pyeupi import PyEUPI misperrors = {'error': 'Error'} mispattributes = {'input': ['hostname', 'domain', 'url'], 'output': ['freetext']} -moduleinfo = {'version': '0.1', 'author': 'Raphaël Vinot', - 'description': 'Query the Phishing Initiative service (https://phishing-initiative.lu)', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Raphaël Vinot', + 'description': 'A module to query the Phishing Initiative service (https://phishing-initiative.lu).', + 'module-type': ['expansion', 'hover'], + 'name': 'EUPI Lookup', + 'logo': 'eupi.png', + 'requirements': ['pyeupi: eupi python library', 'An access to the Phishing Initiative API (apikey & url)'], + 'features': 'This module takes a domain, hostname or url MISP attribute as input to query the Phishing Initiative API. The API returns then the result of the query with some information about the value queried.\n\nPlease note that composite attributes containing domain or hostname are also supported.', + 'references': ['https://phishing-initiative.eu/?lang=en'], + 'input': 'A domain, hostname or url MISP attribute.', + 'output': 'Text containing information about the input, resulting from the query on Phishing Initiative.', +} moduleconfig = ['apikey', 'url'] diff --git a/misp_modules/modules/expansion/extract_url_components.py b/misp_modules/modules/expansion/extract_url_components.py index 3806bf35..dd9c29fa 100644 --- a/misp_modules/modules/expansion/extract_url_components.py +++ b/misp_modules/modules/expansion/extract_url_components.py @@ -5,9 +5,19 @@ from pyfaup.faup import Faup misperrors = {'error': 'Error'} mispattributes = {'input': ['url'], 'format': 'misp_standard'} -moduleinfo = {'version': '1', 'author': 'MISP Team', - 'description': "Extract URL components", - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '1', + 'author': 'MISP Team', + 'description': 'Extract URL components', + 'module-type': ['expansion', 'hover'], + 'name': 'URL Components Extractor', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} moduleconfig = [] @@ -50,16 +60,16 @@ def handler(q=False): if not request.get('attribute') or not check_input_attribute(request['attribute']): return {'error': f'{standard_error_message}, which should contain at least a type, a value and an uuid.'} attribute = request['attribute'] - - if attribute['type'] not in mispattributes['input']: - return {'error': 'Bad attribute type'} - url = attribute['value'] + if attribute['type'] not in mispattributes['input']: + return {'error': 'Bad attribute type'} + + url = attribute['value'] urlObject = createObjectFromURL(url) event = createEvent(urlObject, attribute['uuid'], attribute) event = json.loads(event.to_json()) - + result = {'results': {'Object': event['Object']}} return result diff --git a/misp_modules/modules/expansion/farsight_passivedns.py b/misp_modules/modules/expansion/farsight_passivedns.py index 7cf6f660..835a7be9 100755 --- a/misp_modules/modules/expansion/farsight_passivedns.py +++ b/misp_modules/modules/expansion/farsight_passivedns.py @@ -36,8 +36,15 @@ mispattributes = { moduleinfo = { 'version': '0.5', 'author': 'Christophe Vandeplas', - 'description': 'Module to access Farsight DNSDB Passive DNS', - 'module-type': ['expansion', 'hover'] + 'description': 'Module to access Farsight DNSDB Passive DNS.', + 'module-type': ['expansion', 'hover'], + 'name': 'Farsight DNSDB Lookup', + 'logo': 'farsight.png', + 'requirements': ['An access to the Farsight Passive DNS API (apikey)'], + 'features': 'This module takes a domain, hostname or IP address MISP attribute as input to query the Farsight Passive DNS API.\n The results of rdata and rrset lookups are then returned and parsed into passive-dns objects.\n\nAn API key is required to submit queries to the API.\n It is also possible to define a custom server URL, and to set a limit of results to get.\n This limit is set for each lookup, which means we can have an up to the limit number of passive-dns objects resulting from an rdata query about an IP address, but an up to the limit number of passive-dns objects for each lookup queries about a domain or a hostname (== twice the limit).', + 'references': ['https://www.farsightsecurity.com/', 'https://docs.dnsdb.info/dnsdb-api/'], + 'input': 'A domain, hostname or IP address MISP attribute.', + 'output': 'Passive-dns objects, resulting from the query on the Farsight Passive DNS API.', } moduleconfig = ['apikey', 'server', 'limit', 'flex_queries'] diff --git a/misp_modules/modules/expansion/geoip_asn.py b/misp_modules/modules/expansion/geoip_asn.py index 95d7ee73..16908437 100644 --- a/misp_modules/modules/expansion/geoip_asn.py +++ b/misp_modules/modules/expansion/geoip_asn.py @@ -15,9 +15,20 @@ misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-dst', 'domain|ip'], 'output': ['freetext']} moduleconfig = ['local_geolite_db'] # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '0.1', 'author': 'GlennHD', - 'description': 'Query a local copy of the Maxmind Geolite ASN database (MMDB format)', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'GlennHD', + 'description': 'Query a local copy of the Maxmind Geolite ASN database (MMDB format)', + 'module-type': ['expansion', 'hover'], + 'name': 'GeoIP ASN Lookup', + 'logo': 'maxmind.png', + 'requirements': ["A local copy of Maxmind's Geolite database"], + 'features': "The module takes an IP address attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the related AS number.", + 'references': ['https://www.maxmind.com/en/home'], + 'input': 'An IP address MISP attribute.', + 'output': 'Text containing information about the AS number of the IP address.', + 'descrption': "An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about its related AS number.", +} def handler(q=False): diff --git a/misp_modules/modules/expansion/geoip_city.py b/misp_modules/modules/expansion/geoip_city.py index 01c0627f..643f0858 100644 --- a/misp_modules/modules/expansion/geoip_city.py +++ b/misp_modules/modules/expansion/geoip_city.py @@ -15,9 +15,19 @@ misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-dst', 'domain|ip'], 'output': ['freetext']} moduleconfig = ['local_geolite_db'] # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '0.1', 'author': 'GlennHD', - 'description': 'Query a local copy of the Maxmind Geolite City database (MMDB format)', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'GlennHD', + 'description': "An expansion module to query a local copy of Maxmind's Geolite database with an IP address, in order to get information about the city where it is located.", + 'module-type': ['expansion', 'hover'], + 'name': 'GeoIP City Lookup', + 'logo': 'maxmind.png', + 'requirements': ["A local copy of Maxmind's Geolite database"], + 'features': "The module takes an IP address attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the city where this IP address is located.", + 'references': ['https://www.maxmind.com/en/home'], + 'input': 'An IP address MISP attribute.', + 'output': 'Text containing information about the city where the IP address is located.', +} def handler(q=False): diff --git a/misp_modules/modules/expansion/geoip_country.py b/misp_modules/modules/expansion/geoip_country.py index d28e570e..1b3336da 100644 --- a/misp_modules/modules/expansion/geoip_country.py +++ b/misp_modules/modules/expansion/geoip_country.py @@ -15,9 +15,19 @@ misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-dst', 'domain|ip'], 'output': ['freetext']} moduleconfig = ['local_geolite_db'] # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '0.2', 'author': 'Andreas Muehlemann', - 'description': 'Query a local copy of Maxminds Geolite database, updated for MMDB format', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.2', + 'author': 'Andreas Muehlemann', + 'description': 'Query a local copy of Maxminds Geolite database, updated for MMDB format', + 'module-type': ['expansion', 'hover'], + 'name': 'GeoIP Country Lookup', + 'logo': 'maxmind.png', + 'requirements': ["A local copy of Maxmind's Geolite database"], + 'features': "This module takes an IP address MISP attribute as input and queries a local copy of the Maxmind's Geolite database to get information about the location of this IP address.\n\nPlease note that composite attributes domain|ip are also supported.", + 'references': ['https://www.maxmind.com/en/home'], + 'input': 'An IP address MISP Attribute.', + 'output': 'Text containing information about the location of the IP address.', +} def handler(q=False): diff --git a/misp_modules/modules/expansion/google_safe_browsing.py b/misp_modules/modules/expansion/google_safe_browsing.py index 4920e946..84aca8c4 100644 --- a/misp_modules/modules/expansion/google_safe_browsing.py +++ b/misp_modules/modules/expansion/google_safe_browsing.py @@ -6,9 +6,19 @@ from pysafebrowsing import SafeBrowsing misperrors = {'error': 'Error'} mispattributes = {'input': ['url'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.1', 'author': 'Stephanie S', - 'description': 'Google safe browsing expansion module', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Stephanie S', + 'description': 'Google safe browsing expansion module', + 'module-type': ['expansion', 'hover'], + 'name': 'Google Safe Browsing Lookup', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} moduleconfig = ['api_key'] @@ -24,7 +34,7 @@ def handler(q=False): if request['attribute']['type'] not in mispattributes['input']: return {'error': 'Unsupported attribute type.'} - api_key = request["config"]["api_key"] + api_key = request["config"]["api_key"] url = request["attribute"]["value"] s = SafeBrowsing(api_key) @@ -38,7 +48,7 @@ def handler(q=False): if (response[url]['malicious'] != False): # gsb threat types: THREAT_TYPE_UNSPECIFIED, MALWARE, SOCIAL_ENGINEERING, UNWANTED_SOFTWARE, POTENTIALLY_HARMFUL_APPLICATION gsb_circl_threat_taxonomy = {"MALWARE": 'malware', "SOCIAL_ENGINEERING": 'social-engineering'} - + threats = response[url]['threats'] malicious = response[url]['malicious'] platforms = response[url]['platforms'] @@ -52,18 +62,18 @@ def handler(q=False): threat_attribute.add_tag(f'circl:incident="{gsb_circl_threat_taxonomy.get(threat)}"') else: threat_attribute.add_tag(f'threat-type:{str(threat).lower()}') - obj.add_attribute('platforms', **{'type': 'text', 'value': str(" ".join(platforms))}) - + obj.add_attribute('platforms', **{'type': 'text', 'value': str(" ".join(platforms))}) + else: malicious_attribute = obj.add_attribute('malicious', **{'type': 'boolean', 'value': 0}) # 0 == False malicious_attribute.add_tag(f'ioc:artifact-state="not-malicious"') obj.add_reference(request['attribute']['uuid'], "describes") event.add_object(obj) - + # Avoid serialization issue event = json.loads(event.to_json()) - return {"results": {'Object': event['Object'], 'Attribute': event['Attribute']}} + return {"results": {'Object': event['Object'], 'Attribute': event['Attribute']}} except Exception as error: return {"error": "An error occurred: " + str(error)} diff --git a/misp_modules/modules/expansion/google_search.py b/misp_modules/modules/expansion/google_search.py index 68224abf..fd9febe7 100644 --- a/misp_modules/modules/expansion/google_search.py +++ b/misp_modules/modules/expansion/google_search.py @@ -8,8 +8,19 @@ except ImportError: misperrors = {'error': 'Error'} mispattributes = {'input': ['url'], 'output': ['text']} -moduleinfo = {'author': 'Oun & Gindt', 'module-type': ['hover'], - 'description': 'An expansion hover module to expand google search information about an URL'} +moduleinfo = { + 'author': 'Oun & Gindt', + 'module-type': ['hover'], + 'name': 'Google Search', + 'description': 'An expansion hover module to expand google search information about an URL', + 'version': '1.0', + 'logo': 'google.png', + 'requirements': ['The python Google Search API library'], + 'features': 'The module takes an url as input to query the Google search API. The result of the query is then return as raw text.', + 'references': ['https://github.com/abenassi/Google-Search-API'], + 'input': 'An url attribute.', + 'output': 'Text containing the result of a Google search on the input url.', +} def sleep(retry): diff --git a/misp_modules/modules/expansion/google_threat_intelligence.py b/misp_modules/modules/expansion/google_threat_intelligence.py new file mode 100644 index 00000000..533618a7 --- /dev/null +++ b/misp_modules/modules/expansion/google_threat_intelligence.py @@ -0,0 +1,453 @@ +#!/usr/local/bin/python +# Copyright © 2024 The Google Threat Intelligence authors. All Rights Reserved. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Google Threat Intelligence MISP expansion module.""" + +from urllib import parse +import vt +import pymisp + + +mispattributes = { + 'input': [ + 'hostname', + 'domain', + 'ip-src', + 'ip-dst', + 'md5', + 'sha1', + 'sha256', + 'url', + ], + 'format': 'misp_standard', +} + +moduleinfo = { + 'version': '2', + 'author': 'Google Threat Intelligence team', + 'description': "An expansion module to have the observable's threat score assessed by Google Threat Intelligence.", + 'module-type': ['expansion'], + 'name': 'Google Threat Intelligence Lookup', + 'config': ['apikey', 'event_limit', 'proxy_host', 'proxy_port', 'proxy_username', 'proxy_password'], + 'logo': 'google_threat_intelligence.png', + 'requirements': ['An access to the Google Threat Intelligence API (apikey), with a high request rate limit.'], + 'features': 'GTI assessment for the given observable, this include information about level of severity, a clear verdict (malicious, suspicious, undetected and benign) and additional information provided by the Mandiant expertise combined with the VirusTotal database.\n\n[Output example screeshot](https://github.com/MISP/MISP/assets/4747608/e275db2f-bb1e-4413-8cc0-ec3cb05e0414)', + 'references': ['https://www.virustotal.com/', 'https://gtidocs.virustotal.com/reference'], + 'input': 'A domain, hash (md5, sha1, sha256 or sha512), hostname or IP address attribute.', + 'output': 'Text fields containing the threat score, the severity, the verdict and the threat label of the observable inspected.', +} + +DEFAULT_RESULTS_LIMIT = 10 + + +class GoogleThreatIntelligenceParser: + """Main parser class to create the MISP event.""" + def __init__(self, client: vt.Client, limit: int) -> None: + self.client = client + self.limit = limit or DEFAULT_RESULTS_LIMIT + self.misp_event = pymisp.MISPEvent() + self.attribute = pymisp.MISPAttribute() + self.parsed_objects = {} + self.input_types_mapping = { + 'ip-src': self.parse_ip, + 'ip-dst': self.parse_ip, + 'domain': self.parse_domain, + 'hostname': self.parse_domain, + 'md5': self.parse_hash, + 'sha1': self.parse_hash, + 'sha256': self.parse_hash, + 'url': self.parse_url, + 'ip-src|port': self.parse_ip_port, + 'ip-dst|port': self.parse_ip_port, + } + self.proxies = None + + @staticmethod + def get_total_analysis(analysis: dict, + known_distributors: dict = None) -> int: + """Get total """ + if not analysis: + return 0 + count = sum([analysis['undetected'], + analysis['suspicious'], + analysis['harmless']]) + return count if known_distributors else count + analysis['malicious'] + + def query_api(self, attribute: dict) -> None: + """Get data from the API and parse it.""" + self.attribute.from_dict(**attribute) + self.input_types_mapping[self.attribute.type](self.attribute.value) + + def get_results(self) -> dict: + """Serialize the MISP event.""" + event = self.misp_event.to_dict() + results = { + key: event[key] for key in ('Attribute', 'Object') \ + if (key in event and event[key]) + } + return {'results': results} + + + def add_gti_report(self, report: vt.Object) -> str: + analysis = report.get('last_analysis_stats') + total = self.get_total_analysis(analysis, + report.get('known_distributors')) + if report.type == 'ip_address': + rtype = 'ip-address' + else: + rtype = report.type + permalink = f'https://www.virustotal.com/gui/{rtype}/{report.id}' + + gti_object = pymisp.MISPObject('google-threat-intelligence-report') + gti_object.add_attribute('permalink', type='link', value=permalink) + ratio = f"{analysis['malicious']}/{total}" if analysis else '-/-' + gti_object.add_attribute('detection-ratio', + type='text', + value=ratio, + disable_correlation=True) + report_dict = report.to_dict() + gti_object.add_attribute( + 'threat-score', type='text', + value=get_key(report_dict, + 'attributes.gti_assessment.threat_score.value')) + gti_object.add_attribute( + 'verdict', type='text', + value=get_key(report_dict, + 'attributes.gti_assessment.verdict.value').replace( + 'VERDICT_', '')) + gti_object.add_attribute( + 'severity', type='text', + value=get_key(report_dict, + 'attributes.gti_assessment.severity.value').replace( + 'SEVERITY_', '')) + self.misp_event.add_object(**gti_object) + return gti_object.uuid + + def create_misp_object(self, report: vt.Object) -> pymisp.MISPObject: + misp_object = None + gti_uuid = self.add_gti_report(report) + + if report.type == 'file': + misp_object = pymisp.MISPObject('file') + for hash_type in ('md5', 'sha1', 'sha256', 'tlsh', + 'vhash', 'ssdeep', 'imphash'): + misp_object.add_attribute(hash_type, + **{'type': hash_type, + 'value': report.get(hash_type)}) + elif report.type == 'domain': + misp_object = pymisp.MISPObject('domain-ip') + misp_object.add_attribute('domain', type='domain', value=report.id) + elif report.type == 'ip_address': + misp_object = pymisp.MISPObject('domain-ip') + misp_object.add_attribute('ip', type='ip-dst', value=report.id) + elif report.type == 'url': + misp_object = pymisp.MISPObject('url') + misp_object.add_attribute('url', type='url', value=report.id) + misp_object.add_reference(gti_uuid, 'analyzed-with') + return misp_object + + def parse_domain(self, domain: str) -> str: + domain_report = self.client.get_object(f'/domains/{domain}') + + # DOMAIN + domain_object = self.create_misp_object(domain_report) + + # WHOIS + if domain_report.whois: + whois_object = pymisp.MISPObject('whois') + whois_object.add_attribute('text', type='text', + value=domain_report.whois) + self.misp_event.add_object(**whois_object) + + # SIBLINGS AND SUBDOMAINS + for relationship_name, misp_name in [ + ('siblings', 'sibling-of'), ('subdomains', 'subdomain')]: + rel_iterator = self.client.iterator( + f'/domains/{domain_report.id}/{relationship_name}', + limit=self.limit) + for item in rel_iterator: + attr = pymisp.MISPAttribute() + attr.from_dict(**dict(type='domain', value=item.id)) + self.misp_event.add_attribute(**attr) + domain_object.add_reference(attr.uuid, misp_name) + + # RESOLUTIONS + resolutions_iterator = self.client.iterator( + f'/domains/{domain_report.id}/resolutions', limit=self.limit) + for resolution in resolutions_iterator: + domain_object.add_attribute('ip', type='ip-dst', + value=resolution.ip_address) + + # COMMUNICATING, DOWNLOADED AND REFERRER FILES + for relationship_name, misp_name in [ + ('communicating_files', 'communicates-with'), + ('downloaded_files', 'downloaded-from'), + ('referrer_files', 'referring') + ]: + files_iterator = self.client.iterator( + f'/domains/{domain_report.id}/{relationship_name}', + limit=self.limit) + for file in files_iterator: + file_object = self.create_misp_object(file) + file_object.add_reference(domain_object.uuid, misp_name) + self.misp_event.add_object(**file_object) + + # URLS + urls_iterator = self.client.iterator( + f'/domains/{domain_report.id}/urls', limit=self.limit) + for url in urls_iterator: + url_object = self.create_misp_object(url) + url_object.add_reference(domain_object.uuid, 'hosted-in') + self.misp_event.add_object(**url_object) + + self.misp_event.add_object(**domain_object) + return domain_object.uuid + + def parse_hash(self, file_hash: str) -> str: + file_report = self.client.get_object(f'/files/{file_hash}') + file_object = self.create_misp_object(file_report) + + # ITW URLS + urls_iterator = self.client.iterator( + f'/files/{file_report.id}/itw_urls', limit=self.limit) + for url in urls_iterator: + url_object = self.create_misp_object(url) + url_object.add_reference(file_object.uuid, 'downloaded') + self.misp_event.add_object(**url_object) + + # COMMUNICATING, DOWNLOADED AND REFERRER FILES + for relationship_name, misp_name in [ + ('contacted_urls', 'communicates-with'), + ('contacted_domains', 'communicates-with'), + ('contacted_ips', 'communicates-with') + ]: + related_files_iterator = self.client.iterator( + f'/files/{file_report.id}/{relationship_name}', limit=self.limit) + for related_file in related_files_iterator: + related_file_object = self.create_misp_object(related_file) + related_file_object.add_reference(file_object.uuid, misp_name) + self.misp_event.add_object(**related_file_object) + + self.misp_event.add_object(**file_object) + return file_object.uuid + + def parse_ip_port(self, ipport: str) -> str: + ip = ipport.split('|')[0] + self.parse_ip(ip) + + def parse_ip(self, ip: str) -> str: + ip_report = self.client.get_object(f'/ip_addresses/{ip}') + + # IP + ip_object = self.create_misp_object(ip_report) + + # ASN + asn_object = pymisp.MISPObject('asn') + asn_object.add_attribute('asn', type='AS', value=ip_report.asn) + asn_object.add_attribute('subnet-announced', type='ip-src', + value=ip_report.network) + asn_object.add_attribute('country', type='text', + value=ip_report.country) + self.misp_event.add_object(**asn_object) + + # RESOLUTIONS + resolutions_iterator = self.client.iterator( + f'/ip_addresses/{ip_report.id}/resolutions', limit=self.limit) + for resolution in resolutions_iterator: + ip_object.add_attribute('domain', type='domain', + value=resolution.host_name) + + # URLS + urls_iterator = self.client.iterator( + f'/ip_addresses/{ip_report.id}/urls', limit=self.limit) + for url in urls_iterator: + url_object = self.create_misp_object(url) + url_object.add_reference(ip_object.uuid, 'hosted-in') + self.misp_event.add_object(**url_object) + + self.misp_event.add_object(**ip_object) + return ip_object.uuid + + def parse_url(self, url: str) -> str: + url_id = vt.url_id(url) + url_report = self.client.get_object(f'/urls/{url_id}') + url_object = self.create_misp_object(url_report) + + # COMMUNICATING, DOWNLOADED AND REFERRER FILES + for relationship_name, misp_name in [ + ('communicating_files', 'communicates-with'), + ('downloaded_files', 'downloaded-from'), + ('referrer_files', 'referring') + ]: + files_iterator = self.client.iterator( + f'/urls/{url_report.id}/{relationship_name}', limit=self.limit) + for file in files_iterator: + file_object = self.create_misp_object(file) + file_object.add_reference(url_object.uuid, misp_name) + self.misp_event.add_object(**file_object) + + self.misp_event.add_object(**url_object) + return url_object.uuid + + +def get_key(dictionary, key, default_value=''): + """Get value from nested dictionaries.""" + dictionary = dictionary or {} + keys = key.split('.') + field_name = keys.pop() + for k in keys: + if k not in dictionary: + return default_value + dictionary = dictionary[k] + return dictionary.get(field_name, default_value) + + +def get_proxy_settings(config: dict) -> dict: + """Returns proxy settings in the requests format or None if not set up.""" + proxies = None + host = config.get('proxy_host') + port = config.get('proxy_port') + username = config.get('proxy_username') + password = config.get('proxy_password') + + if host: + if not port: + raise KeyError( + ('The google_threat_intelligence_proxy_host config is set, ' + 'please also set the virustotal_proxy_port.')) + parsed = parse.urlparse(host) + if 'http' in parsed.scheme: + scheme = 'http' + else: + scheme = parsed.scheme + netloc = parsed.netloc + host = f'{netloc}:{port}' + + if username: + if not password: + raise KeyError(('The google_threat_intelligence_' + ' proxy_host config is set, please also' + ' set the virustotal_proxy_password.')) + auth = f'{username}:{password}' + host = auth + '@' + host + + proxies = { + 'http': f'{scheme}://{host}', + 'https': f'{scheme}://{host}' + } + return proxies + + +def dict_handler(request: dict): + """MISP entry point fo the module.""" + if not request.get('config') or not request['config'].get('apikey'): + return { + 'error': ('A Google Threat Intelligence api ' + 'key is required for this module.') + } + + if not request.get('attribute'): + return { + 'error': ('This module requires an "attribute" field as input,' + ' which should contain at least a type, a value and an' + ' uuid.') + } + + if request['attribute']['type'] not in mispattributes['input']: + return {'error': 'Unsupported attribute type.'} + + event_limit = request['config'].get('event_limit') + attribute = request['attribute'] + + try: + proxy_settings = get_proxy_settings(request.get('config')) + client = vt.Client( + request['config']['apikey'], + headers={ + 'x-tool': 'MISPModuleGTIExpansion', + }, + proxy=proxy_settings['http'] if proxy_settings else None) + parser = GoogleThreatIntelligenceParser( + client, int(event_limit) if event_limit else None) + parser.query_api(attribute) + except vt.APIError as ex: + return {'error': ex.message} + except KeyError as ex: + return {'error': str(ex)} + + return parser.get_results() + + +def introspection(): + """Returns the module input attributes required.""" + return mispattributes + + +def version(): + """Returns the module metadata.""" + return moduleinfo + + +if __name__ == '__main__': + # Testing/debug calls. + import os + api_key = os.getenv('GTI_API_KEY') + # File + request_data = { + 'config': {'apikey': api_key}, + 'attribute': { + 'type': 'sha256', + 'value': ('ed01ebfbc9eb5bbea545af4d01bf5f10' + '71661840480439c6e5babe8e080e41aa') + } + } + response = dict_handler(request_data) + report_obj = response['results']['Object'][0] + print(report_obj.to_dict()) + + # URL + request_data = { + 'config': {'apikey': api_key}, + 'attribute': { + 'type': 'url', + 'value': 'http://47.21.48.182:60813/Mozi.a' + } + } + response = dict_handler(request_data) + report_obj = response['results']['Object'][0] + print(report_obj.to_dict()) + + # Ip + request_data = { + 'config': {'apikey': api_key}, + 'attribute': { + 'type': 'ip-src', + 'value': '180.72.148.38' + } + } + response = dict_handler(request_data) + report_obj = response['results']['Object'][0] + print(report_obj.to_dict()) + + # Domain + request_data = { + 'config': {'apikey': api_key}, + 'attribute': { + 'type': 'domain', + 'value': 'qexyhuv.com' + } + } + response = dict_handler(request_data) + report_obj = response['results']['Object'][0] + print(report_obj.to_dict()) diff --git a/misp_modules/modules/expansion/greynoise.py b/misp_modules/modules/expansion/greynoise.py index fbeb88ba..101da078 100644 --- a/misp_modules/modules/expansion/greynoise.py +++ b/misp_modules/modules/expansion/greynoise.py @@ -17,10 +17,17 @@ logger.setLevel(logging.INFO) misperrors = {"error": "Error"} mispattributes = {"input": ["ip-src", "ip-dst", "vulnerability"], "format": "misp_standard"} moduleinfo = { - "version": "1.2", - "author": "Brad Chiappetta ", - "description": "Used to query IP and CVE intel from GreyNoise", - "module-type": ["expansion", "hover"], + 'version': '1.2', + 'author': 'Brad Chiappetta ', + 'description': 'Module to query IP and CVE information from GreyNoise', + 'module-type': ['expansion', 'hover'], + 'name': 'GreyNoise Lookup', + 'logo': 'greynoise.png', + 'requirements': ['A Greynoise API key. Both Enterprise (Paid) and Community (Free) API keys are supported, however Community API users will only be able to perform IP lookups.'], + 'features': 'This module supports: 1) Query an IP from GreyNoise to see if it is internet background noise or a common business service 2) Query a CVE from GreyNoise to see the total number of internet scanners looking for the CVE in the last 7 days.', + 'references': ['https://greynoise.io/', 'https://docs.greyniose.io/', 'https://www.greynoise.io/viz/account/'], + 'input': 'An IP address or CVE ID', + 'output': 'IP Lookup information or CVE scanning profile for past 7 days', } moduleconfig = ["api_key", "api_type"] diff --git a/misp_modules/modules/expansion/hashdd.py b/misp_modules/modules/expansion/hashdd.py index 17e1029d..310cfb70 100755 --- a/misp_modules/modules/expansion/hashdd.py +++ b/misp_modules/modules/expansion/hashdd.py @@ -3,7 +3,19 @@ import requests misperrors = {'error': 'Error'} mispattributes = {'input': ['md5'], 'output': ['text']} -moduleinfo = {'version': '0.2', 'author': 'Alexandre Dulaunoy', 'description': 'An expansion module to check hashes against hashdd.com including NSLR dataset.', 'module-type': ['hover']} +moduleinfo = { + 'version': '0.2', + 'author': 'Alexandre Dulaunoy', + 'description': 'A hover module to check hashes against hashdd.com including NSLR dataset.', + 'module-type': ['hover'], + 'name': 'Hashdd Lookup', + 'logo': '', + 'requirements': [], + 'features': 'This module takes a hash attribute as input to check its known level, using the hashdd API. This information is then displayed.', + 'references': ['https://hashdd.com/'], + 'input': 'A hash MISP attribute (md5).', + 'output': 'Text describing the known level of the hash in the hashdd databases.', +} moduleconfig = [] hashddapi_url = 'https://api.hashdd.com/v1/knownlevel/nsrl/' diff --git a/misp_modules/modules/expansion/hashlookup.py b/misp_modules/modules/expansion/hashlookup.py index eeca95f2..1752ced9 100644 --- a/misp_modules/modules/expansion/hashlookup.py +++ b/misp_modules/modules/expansion/hashlookup.py @@ -6,9 +6,19 @@ from pymisp import MISPEvent, MISPObject misperrors = {'error': 'Error'} mispattributes = {'input': ['md5', 'sha1', 'sha256'], 'format': 'misp_standard'} -moduleinfo = {'version': '2', 'author': 'Alexandre Dulaunoy', - 'description': 'An expansion module to enrich a file hash with hashlookup.circl.lu services (NSRL and other sources)', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '2', + 'author': 'Alexandre Dulaunoy', + 'description': 'An expansion module to query the CIRCL hashlookup services to find it if a hash is part of a known set such as NSRL.', + 'module-type': ['expansion', 'hover'], + 'name': 'CIRCL Hashlookup Lookup', + 'logo': 'circl.png', + 'requirements': [], + 'features': 'The module takes file hashes as input such as a MD5 or SHA1.\n It queries the public CIRCL.lu hashlookup service and return all the hits if the hashes are known in an existing dataset. The module can be configured with a custom hashlookup url if required.\n The module can be used an hover module but also an expansion model to add related MISP objects.\n', + 'references': ['https://www.circl.lu/services/hashlookup/'], + 'input': 'File hashes (MD5, SHA1)', + 'output': 'Object with the filename associated hashes if the hash is part of a known set.', +} moduleconfig = ["custom_API"] hashlookup_url = 'https://hashlookup.circl.lu/' diff --git a/misp_modules/modules/expansion/hibp.py b/misp_modules/modules/expansion/hibp.py index b2d1c166..60a12347 100644 --- a/misp_modules/modules/expansion/hibp.py +++ b/misp_modules/modules/expansion/hibp.py @@ -4,7 +4,19 @@ import json misperrors = {'error': 'Error'} mispattributes = {'input': ['email-dst', 'email-src'], 'output': ['text']} -moduleinfo = {'version': '0.2', 'author': 'Corsin Camichel, Aurélien Schwab', 'description': 'Module to access haveibeenpwned.com API (v3).', 'module-type': ['hover']} +moduleinfo = { + 'version': '0.2', + 'author': 'Corsin Camichel, Aurélien Schwab', + 'description': 'Module to access haveibeenpwned.com API.', + 'module-type': ['hover'], + 'name': 'Have I Been Pwned Lookup', + 'logo': 'hibp.png', + 'requirements': [], + 'features': 'The module takes an email address as input and queries haveibeenpwned.com API to find additional information about it. This additional information actually tells if any account using the email address has already been compromised in a data breach.', + 'references': ['https://haveibeenpwned.com/'], + 'input': 'An email address', + 'output': 'Additional information about the email address.', +} moduleconfig = ['api_key'] haveibeenpwned_api_url = 'https://haveibeenpwned.com/api/v3/breachedaccount/' diff --git a/misp_modules/modules/expansion/html_to_markdown.py b/misp_modules/modules/expansion/html_to_markdown.py index 228b4bcb..629f5935 100755 --- a/misp_modules/modules/expansion/html_to_markdown.py +++ b/misp_modules/modules/expansion/html_to_markdown.py @@ -5,9 +5,19 @@ from bs4 import BeautifulSoup misperrors = {'error': 'Error'} mispattributes = {'input': ['url'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Sami Mokaddem', - 'description': 'Simple HTML fetcher', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sami Mokaddem', + 'description': 'Expansion module to fetch the html content from an url and convert it into markdown.', + 'module-type': ['expansion'], + 'name': 'HTML to Markdown', + 'logo': '', + 'requirements': ['The markdownify python library'], + 'features': 'The module take an URL as input and the HTML content is fetched from it. This content is then converted into markdown that is returned as text.', + 'references': [], + 'input': 'URL attribute.', + 'output': 'Markdown content converted from the HTML fetched from the url.', +} def fetchHTML(url): diff --git a/misp_modules/modules/expansion/hyasinsight.py b/misp_modules/modules/expansion/hyasinsight.py index c8497091..9d1a6970 100644 --- a/misp_modules/modules/expansion/hyasinsight.py +++ b/misp_modules/modules/expansion/hyasinsight.py @@ -1,874 +1,881 @@ -import json -import logging -from typing import Dict, List, Any - -import requests -import re -from requests.exceptions import ( - HTTPError, - ProxyError, - InvalidURL, - ConnectTimeout -) -from . import check_input_attribute, standard_error_message -from pymisp import MISPEvent, MISPObject, Distribution - -ip_query_input_type = [ - 'ip-src', - 'ip-dst' -] -domain_query_input_type = [ - 'hostname', - 'domain' -] -email_query_input_type = [ - 'email', - 'email-src', - 'email-dst', - 'target-email', - 'whois-registrant-email' -] -phone_query_input_type = [ - 'phone-number', - 'whois-registrant-phone' -] - -md5_query_input_type = [ - 'md5', - 'x509-fingerprint-md5', - 'ja3-fingerprint-md5', - 'hassh-md5', - 'hasshserver-md5' -] - -sha1_query_input_type = [ - 'sha1', - 'x509-fingerprint-sha1' -] - -sha256_query_input_type = [ - 'sha256', - 'x509-fingerprint-sha256' -] - -sha512_query_input_type = [ - 'sha512' -] - -misperrors = { - 'error': 'Error' -} -mispattributes = { - 'input': ip_query_input_type + domain_query_input_type + email_query_input_type + phone_query_input_type - + md5_query_input_type + sha1_query_input_type + sha256_query_input_type + sha512_query_input_type, - 'format': 'misp_standard' -} - -moduleinfo = { - 'version': '0.1', - 'author': 'Mike Champ', - 'description': '', - 'module-type': ['expansion', 'hover'] -} -moduleconfig = ['apikey'] -TIMEOUT = 60 -logger = logging.getLogger('hyasinsight') -logger.setLevel(logging.DEBUG) -HYAS_API_BASE_URL = 'https://insight.hyas.com/api/ext/' -WHOIS_CURRENT_BASE_URL = 'https://api.hyas.com/' -DEFAULT_DISTRIBUTION_SETTING = Distribution.your_organisation_only.value -IPV4_REGEX = r'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b([^\/]|$)' -IPV6_REGEX = r'\b(?:(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:(?:(:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\b' # noqa: E501 -# Enrichment Types -# HYAS API endpoints -PASSIVE_DNS_ENDPOINT = 'passivedns' -DYNAMIC_DNS_ENDPOINT = 'dynamicdns' -PASSIVE_HASH_ENDPOINT = 'passivehash' -SINKHOLE_ENDPOINT = 'sinkhole' -SSL_CERTIFICATE_ENDPOINT = 'ssl_certificate' -DEVICE_GEO_ENDPOINT = 'device_geo' -WHOIS_HISTORIC_ENDPOINT = 'whois' -WHOIS_CURRENT_ENDPOINT = 'whois/v1' -MALWARE_RECORDS_ENDPOINT = 'sample' -MALWARE_INFORMATION_ENDPOINT = 'sample/information' -C2ATTRIBUTION_ENDPOINT = 'c2attribution' -OPEN_SOURCE_INDICATORS_ENDPOINT = 'os_indicators' - -# HYAS API endpoint params -DOMAIN_PARAM = 'domain' -IP_PARAM = 'ip' -IPV4_PARAM = 'ipv4' -IPV6_PARAM = 'ipv6' -EMAIL_PARAM = 'email' -PHONE_PARAM = 'phone' -MD5_PARAM = 'md5' -SHA256_PARAM = 'sha256' -SHA512_PARAM = 'sha512' -HASH_PARAM = 'hash' -SHA1_PARAM = 'sha1' - -HYAS_IP_ENRICHMENT_ENDPOINTS_LIST = [DYNAMIC_DNS_ENDPOINT, PASSIVE_DNS_ENDPOINT, PASSIVE_HASH_ENDPOINT, - SINKHOLE_ENDPOINT, - SSL_CERTIFICATE_ENDPOINT, DEVICE_GEO_ENDPOINT, C2ATTRIBUTION_ENDPOINT, - MALWARE_RECORDS_ENDPOINT, OPEN_SOURCE_INDICATORS_ENDPOINT] -HYAS_DOMAIN_ENRICHMENT_ENDPOINTS_LIST = [PASSIVE_DNS_ENDPOINT, DYNAMIC_DNS_ENDPOINT, WHOIS_HISTORIC_ENDPOINT, - MALWARE_RECORDS_ENDPOINT, WHOIS_CURRENT_ENDPOINT, PASSIVE_HASH_ENDPOINT, - C2ATTRIBUTION_ENDPOINT, SSL_CERTIFICATE_ENDPOINT, - OPEN_SOURCE_INDICATORS_ENDPOINT] -HYAS_EMAIL_ENRICHMENT_ENDPOINTS_LIST = [DYNAMIC_DNS_ENDPOINT, WHOIS_HISTORIC_ENDPOINT, C2ATTRIBUTION_ENDPOINT] -HYAS_PHONE_ENRICHMENT_ENDPOINTS_LIST = [WHOIS_HISTORIC_ENDPOINT] -HYAS_SHA1_ENRICHMENT_ENDPOINTS_LIST = [SSL_CERTIFICATE_ENDPOINT, MALWARE_INFORMATION_ENDPOINT, - OPEN_SOURCE_INDICATORS_ENDPOINT] -HYAS_SHA256_ENRICHMENT_ENDPOINTS_LIST = [C2ATTRIBUTION_ENDPOINT, MALWARE_INFORMATION_ENDPOINT, - OPEN_SOURCE_INDICATORS_ENDPOINT] -HYAS_SHA512_ENRICHMENT_ENDPOINTS_LIST = [MALWARE_INFORMATION_ENDPOINT] -HYAS_MD5_ENRICHMENT_ENDPOINTS_LIST = [MALWARE_RECORDS_ENDPOINT, MALWARE_INFORMATION_ENDPOINT, - OPEN_SOURCE_INDICATORS_ENDPOINT] - -HYAS_OBJECT_NAMES = { - DYNAMIC_DNS_ENDPOINT: "Dynamic DNS Information", - PASSIVE_HASH_ENDPOINT: "Passive Hash Information", - SINKHOLE_ENDPOINT: "Sinkhole Information", - SSL_CERTIFICATE_ENDPOINT: "SSL Certificate Information", - DEVICE_GEO_ENDPOINT: "Mobile Geolocation Information", - C2ATTRIBUTION_ENDPOINT: "C2 Attribution Information", - PASSIVE_DNS_ENDPOINT: "Passive DNS Information", - WHOIS_HISTORIC_ENDPOINT: "Whois Related Information", - WHOIS_CURRENT_ENDPOINT: "Whois Current Related Information", - MALWARE_INFORMATION_ENDPOINT: "Malware Sample Information", - OPEN_SOURCE_INDICATORS_ENDPOINT: "Open Source Intel for malware, ssl certificates and other indicators Information", - MALWARE_RECORDS_ENDPOINT: "Malware Sample Records Information" -} - - -def parse_attribute(comment, feature, value): - """Generic Method for parsing the attributes in the object""" - attribute = { - 'type': 'text', - 'value': value, - 'comment': comment, - 'distribution': DEFAULT_DISTRIBUTION_SETTING, - 'object_relation': feature - } - return attribute - - -def misp_object(endpoint, attribute_value): - object_name = HYAS_OBJECT_NAMES[endpoint] - hyas_object = MISPObject(object_name) - hyas_object.distribution = DEFAULT_DISTRIBUTION_SETTING - hyas_object.template_uuid = "d69d3d15-7b4d-49b1-9e0a-bb29f3d421d9" - hyas_object.template_id = "1" - hyas_object.description = "HYAS INSIGHT " + object_name - hyas_object.comment = "HYAS INSIGHT " + object_name + " for " + attribute_value - setattr(hyas_object, 'meta-category', 'network') - description = ( - "An object containing the enriched attribute and " - "related entities from HYAS Insight." - ) - hyas_object.from_dict( - **{"meta-category": "misc", "description": description, - "distribution": DEFAULT_DISTRIBUTION_SETTING} - ) - return hyas_object - - -def flatten_json(y: Dict) -> Dict[str, Any]: - """ - :param y: raw_response from HYAS api - :return: Flatten json response - """ - out = {} - - def flatten(x, name=''): - # If the Nested key-value - # pair is of dict type - if type(x) is dict: - for a in x: - flatten(x[a], name + a + '_') - else: - out[name[:-1]] = x - - flatten(y) - return out - - -def get_flatten_json_response(raw_api_response: List[Dict]) -> List[Dict]: - """ - :param raw_api_response: raw_api response from the API - :return: Flatten Json response - """ - flatten_json_response = [] - if raw_api_response: - for obj in raw_api_response: - flatten_json_response.append(flatten_json(obj)) - - return flatten_json_response - - -def request_body(query_input, query_param, current): - """ - This Method returns the request body for specific endpoint. - """ - - if current: - return { - "applied_filters": { - query_input: query_param, - "current": True - } - } - else: - return { - "applied_filters": { - query_input: query_param - } - } - - -def malware_info_lookup_to_markdown(results: Dict) -> list: - scan_results = results.get('scan_results', []) - out = [] - if scan_results: - for res in scan_results: - malware_info_data = { - "avscan_score": results.get( - "avscan_score", ''), - "md5": results.get("md5", ''), - 'av_name': res.get( - "av_name", ''), - 'def_time': res.get( - "def_time", ''), - 'threat_found': res.get( - 'threat_found', ''), - 'scan_time': results.get("scan_time", ''), - 'sha1': results.get('sha1', ''), - 'sha256': results.get('sha256', ''), - 'sha512': results.get('sha512', '') - } - out.append(malware_info_data) - else: - malware_info_data = { - "avscan_score": results.get("avscan_score", ''), - "md5": results.get("md5", ''), - 'av_name': '', - 'def_time': '', - 'threat_found': '', - 'scan_time': results.get("scan_time", ''), - 'sha1': results.get('sha1', ''), - 'sha256': results.get('sha256', ''), - 'sha512': results.get('sha512', '') - } - out.append(malware_info_data) - return out - - -class RequestHandler: - """A class for handling any outbound requests from this module.""" - - def __init__(self, apikey): - self.session = requests.Session() - self.api_key = apikey - - def get(self, url: str, headers: dict = None, req_body=None) -> requests.Response: - """General post method to fetch the response from HYAS Insight.""" - response = [] - try: - response = self.session.post( - url, headers=headers, json=req_body - ) - if response: - response = response.json() - except (ConnectTimeout, ProxyError, InvalidURL) as error: - msg = "Error connecting with the HYAS Insight." - logger.error(f"{msg} Error: {error}") - misperrors["error"] = msg - return response - - def hyas_lookup(self, end_point: str, query_input, query_param, current=False) -> requests.Response: - """Do a lookup call.""" - # Building the request - if current: - url = f'{WHOIS_CURRENT_BASE_URL}{WHOIS_CURRENT_ENDPOINT}' - else: - url = f'{HYAS_API_BASE_URL}{end_point}' - headers = { - 'Content-type': 'application/json', - 'X-API-Key': self.api_key, - 'User-Agent': 'Misp Modules' - } - req_body = request_body(query_input, query_param, current) - try: - response = self.get(url, headers, req_body) - except HTTPError as error: - msg = f"Error when requesting data from HYAS Insight. {error.response}: {error.response.reason}" - logger.error(msg) - misperrors["error"] = msg - raise - return response - - -class HyasInsightParser: - """A class for handling the enrichment objects""" - - def __init__(self, attribute): - self.attribute = attribute - self.misp_event = MISPEvent() - self.misp_event.add_attribute(**attribute) - - self.c2_attribution_data_items = [ - 'actor_ipv4', - 'c2_domain', - 'c2_ip', - 'c2_url', - 'datetime', - 'email', - 'email_domain', - 'referrer_domain', - 'referrer_ipv4', - 'referrer_url', - 'sha256' - ] - self.c2_attribution_data_items_friendly_names = { - 'actor_ipv4': 'Actor IPv4', - 'c2_domain': 'C2 Domain', - 'c2_ip': 'C2 IP', - 'c2_url': 'C2 URL', - 'datetime': 'DateTime', - 'email': 'Email', - 'email_domain': 'Email Domain', - 'referrer_domain': 'Referrer Domain', - 'referrer_ipv4': 'Referrer IPv4', - 'referrer_url': 'Referrer URL', - 'sha256': 'SHA256' - } - - self.device_geo_data_items = [ - 'datetime', - 'device_user_agent', - 'geo_country_alpha_2', - 'geo_horizontal_accuracy', - 'ipv4', - 'ipv6', - 'latitude', - 'longitude', - 'wifi_bssid' - ] - - self.device_geo_data_items_friendly_names = { - 'datetime': 'DateTime', - 'device_user_agent': 'Device User Agent', - 'geo_country_alpha_2': 'Alpha-2 Code', - 'geo_horizontal_accuracy': 'GPS Horizontal Accuracy', - 'ipv4': 'IPv4 Address', - 'ipv6': 'IPv6 Address', - 'latitude': 'Latitude', - 'longitude': 'Longitude', - 'wifi_bssid': 'WIFI BSSID' - } - - self.dynamic_dns_data_items = [ - 'a_record', - 'account', - 'created', - 'created_ip', - 'domain', - 'domain_creator_ip', - 'email', - ] - - self.dynamic_dns_data_items_friendly_names = { - 'a_record': 'A Record', - 'account': 'Account Holder', - 'created': 'Created Date', - 'created_ip': 'Account Holder IP Address', - 'domain': 'Domain', - 'domain_creator_ip': 'Domain Creator IP Address', - 'email': 'Email Address', - } - - self.os_indicators_data_items = [ - 'context', - 'datetime', - 'domain', - 'domain_2tld', - 'first_seen', - 'ipv4', - 'ipv6', - 'last_seen', - 'md5', - 'sha1', - 'sha256', - 'source_name', - 'source_url', - 'url' - ] - - self.os_indicators_data_items_friendly_names = { - 'context': 'Context', - 'datetime': 'DateTime', - 'domain': 'Domain', - 'domain_2tld': 'Domain 2TLD', - 'first_seen': 'First Seen', - 'ipv4': 'IPv4 Address', - 'ipv6': 'IPv6 Address', - 'last_seen': 'Last Seen', - 'md5': 'MD5', - 'sha1': 'SHA1', - 'sha256': 'SHA256', - 'source_name': 'Source Name', - 'source_url': 'Source URL', - 'url': 'URL' - } - - self.passive_dns_data_items = [ - 'cert_name', - 'count', - 'domain', - 'first_seen', - 'ip_geo_city_name', - 'ip_geo_country_iso_code', - 'ip_geo_country_name', - 'ip_geo_location_latitude', - 'ip_geo_location_longitude', - 'ip_geo_postal_code', - 'ip_ip', - 'ip_isp_autonomous_system_number', - 'ip_isp_autonomous_system_organization', - 'ip_isp_ip_address', - 'ip_isp_isp', - 'ip_isp_organization', - 'ipv4', - 'ipv6', - 'last_seen' - ] - - self.passive_dns_data_items_friendly_names = { - 'cert_name': 'Certificate Provider Name', - 'count': 'Passive DNS Count', - 'domain': 'Domain', - 'first_seen': 'First Seen', - 'ip_geo_city_name': 'IP Organization City', - 'ip_geo_country_iso_code': 'IP Organization Country ISO Code', - 'ip_geo_country_name': 'IP Organization Country Name', - 'ip_geo_location_latitude': 'IP Organization Latitude', - 'ip_geo_location_longitude': 'IP Organization Longitude', - 'ip_geo_postal_code': 'IP Organization Postal Code', - 'ip_ip': 'IP Address', - 'ip_isp_autonomous_system_number': 'ASN IP', - 'ip_isp_autonomous_system_organization': 'ASO IP', - 'ip_isp_ip_address': 'IP Address', - 'ip_isp_isp': 'ISP', - 'ip_isp_organization': 'ISP Organization', - 'ipv4': 'IPv4 Address', - 'ipv6': 'IPv6 Address', - 'last_seen': 'Last Seen' - } - - self.passive_hash_data_items = [ - 'domain', - 'md5_count' - ] - - self.passive_hash_data_items_friendly_names = { - 'domain': 'Domain', - 'md5_count': 'Passive DNS Count' - } - - self.malware_records_data_items = [ - 'datetime', - 'domain', - 'ipv4', - 'ipv6', - 'md5', - 'sha1', - 'sha256' - ] - - self.malware_records_data_items_friendly_names = { - 'datetime': 'DateTime', - 'domain': 'Domain', - 'ipv4': 'IPv4 Address', - 'ipv6': 'IPv6 Address', - 'md5': 'MD5', - 'sha1': 'SHA1', - 'sha256': 'SHA256' - } - - self.malware_information_data_items = [ - 'avscan_score', - 'md5', - 'av_name', - 'def_time', - 'threat_found', - 'scan_time', - 'sha1', - 'sha256', - 'sha512' - ] - - self.malware_information_data_items_friendly_names = { - 'avscan_score': 'AV Scan Score', - 'md5': 'MD5', - 'av_name': 'AV Name', - 'def_time': 'AV DateTime', - 'threat_found': 'Source', - 'scan_time': 'Scan DateTime', - 'sha1': 'SHA1', - 'sha256': 'SHA256', - 'sha512': 'SHA512' - } - - self.sinkhole_data_items = [ - 'count', - 'country_name', - 'country_code', - 'data_port', - 'datetime', - 'ipv4', - 'last_seen', - 'organization_name', - 'sink_source' - ] - - self.sinkhole_data_items_friendly_names = { - 'count': 'Sinkhole Count', - 'country_name': 'IP Address Country', - 'country_code': 'IP Address Country Code', - 'data_port': 'Data Port', - 'datetime': 'First Seen', - 'ipv4': 'IP Address', - 'last_seen': 'Last Seen', - 'organization_name': 'ISP Organization', - 'sink_source': 'Sink Source IP' - } - - self.ssl_certificate_data_items = [ - 'ip', - 'ssl_cert_cert_key', - 'ssl_cert_expire_date', - 'ssl_cert_issue_date', - 'ssl_cert_issuer_commonName', - 'ssl_cert_issuer_countryName', - 'ssl_cert_issuer_localityName', - 'ssl_cert_issuer_organizationName', - 'ssl_cert_issuer_organizationalUnitName', - 'ssl_cert_issuer_stateOrProvinceName', - 'ssl_cert_md5', - 'ssl_cert_serial_number', - 'ssl_cert_sha1', - 'ssl_cert_sha_256', - 'ssl_cert_sig_algo', - 'ssl_cert_ssl_version', - 'ssl_cert_subject_commonName', - 'ssl_cert_subject_countryName', - 'ssl_cert_subject_localityName', - 'ssl_cert_subject_organizationName', - 'ssl_cert_subject_organizationalUnitName', - 'ssl_cert_timestamp' - ] - - self.ssl_certificate_data_items_friendly_names = { - 'ip': 'IP Address', - 'ssl_cert_cert_key': 'Certificate Key', - 'ssl_cert_expire_date': 'Certificate Expiration Date', - 'ssl_cert_issue_date': 'Certificate Issue Date', - 'ssl_cert_issuer_commonName': 'Issuer Common Name', - 'ssl_cert_issuer_countryName': 'Issuer Country Name', - 'ssl_cert_issuer_localityName': 'Issuer City Name', - 'ssl_cert_issuer_organizationName': 'Issuer Organization Name', - 'ssl_cert_issuer_organizationalUnitName': 'Issuer Organization Unit Name', - 'ssl_cert_issuer_stateOrProvinceName': 'Issuer State or Province Name', - 'ssl_cert_md5': 'Certificate MD5', - 'ssl_cert_serial_number': 'Certificate Serial Number', - 'ssl_cert_sha1': 'Certificate SHA1', - 'ssl_cert_sha_256': 'Certificate SHA256', - 'ssl_cert_sig_algo': 'Certificate Signature Algorithm', - 'ssl_cert_ssl_version': 'SSL Version', - 'ssl_cert_subject_commonName': 'Reciever Subject Name', - 'ssl_cert_subject_countryName': 'Receiver Country Name', - 'ssl_cert_subject_localityName': 'Receiver City Name', - 'ssl_cert_subject_organizationName': 'Receiver Organization Name', - 'ssl_cert_subject_organizationalUnitName': 'Receiver Organization Unit Name', - 'ssl_cert_timestamp': 'Certificate DateTime' - } - - self.whois_historic_data_items = [ - 'abuse_emails', - 'address', - 'city', - 'country', - 'datetime', - 'domain', - 'domain_2tld', - 'domain_created_datetime', - 'domain_expires_datetime', - 'domain_updated_datetime', - 'email', - 'idn_name', - 'name', - 'nameserver', - 'organization', - 'phone', - 'privacy_punch', - 'registrar' - ] - - self.whois_historic_data_items_friendly_names = { - 'abuse_emails': 'Abuse Emails', - 'address': 'Address', - 'city': 'City', - 'country': 'Country', - 'datetime': 'Datetime', - 'domain': 'Domain', - 'domain_2tld': 'Domain 2tld', - 'domain_created_datetime': 'Domain Created Time', - 'domain_expires_datetime': 'Domain Expires Time', - 'domain_updated_datetime': 'Domain Updated Time', - 'email': 'Email Address', - 'idn_name': 'IDN Name', - 'name': 'Name', - 'nameserver': 'Nameserver', - 'organization': 'Organization', - 'phone': 'Phone Info', - 'privacy_punch': 'Privacy Punch', - 'registrar': 'Registrar' - } - - self.whois_current_data_items = [ - 'abuse_emails', - 'address', - 'city', - 'country', - 'datetime', - 'domain', - 'domain_2tld', - 'domain_created_datetime', - 'domain_expires_datetime', - 'domain_updated_datetime', - 'email', - 'idn_name', - 'name', - 'nameserver', - 'organization', - 'phone', - 'privacy_punch', - 'registrar', - 'state' - ] - - self.whois_current_data_items_friendly_names = { - 'abuse_emails': 'Abuse Emails', - 'address': 'Address', - 'city': 'City', - 'country': 'Country', - 'datetime': 'Datetime', - 'domain': 'Domain', - 'domain_2tld': 'Domain 2tld', - 'domain_created_datetime': 'Domain Created Time', - 'domain_expires_datetime': 'Domain Expires Time', - 'domain_updated_datetime': 'Domain Updated Time', - 'email': 'Email Address', - 'idn_name': 'IDN Name', - 'name': 'Name', - 'nameserver': 'Nameserver', - 'organization': 'Organization', - 'phone': 'Phone', - 'privacy_punch': 'Privacy Punch', - 'registrar': 'Registrar', - 'state': 'State' - } - - def create_misp_attributes_and_objects(self, response, endpoint, attribute_value): - flatten_json_response = get_flatten_json_response(response) - data_items: List[str] = [] - data_items_friendly_names: Dict[str, str] = {} - if endpoint == DEVICE_GEO_ENDPOINT: - data_items: List[str] = self.device_geo_data_items - data_items_friendly_names: Dict[str, str] = self.device_geo_data_items_friendly_names - elif endpoint == DYNAMIC_DNS_ENDPOINT: - data_items: List[str] = self.dynamic_dns_data_items - data_items_friendly_names: Dict[str, str] = self.dynamic_dns_data_items_friendly_names - elif endpoint == PASSIVE_DNS_ENDPOINT: - data_items: List[str] = self.passive_dns_data_items - data_items_friendly_names: Dict[str, str] = self.passive_dns_data_items_friendly_names - elif endpoint == PASSIVE_HASH_ENDPOINT: - data_items: List[str] = self.passive_hash_data_items - data_items_friendly_names: Dict[str, str] = self.passive_hash_data_items_friendly_names - elif endpoint == SINKHOLE_ENDPOINT: - data_items: List[str] = self.sinkhole_data_items - data_items_friendly_names: Dict[str, str] = self.sinkhole_data_items_friendly_names - elif endpoint == WHOIS_HISTORIC_ENDPOINT: - data_items = self.whois_historic_data_items - data_items_friendly_names = self.whois_historic_data_items_friendly_names - elif endpoint == WHOIS_CURRENT_ENDPOINT: - data_items: List[str] = self.whois_current_data_items - data_items_friendly_names: Dict[str, str] = self.whois_current_data_items_friendly_names - elif endpoint == SSL_CERTIFICATE_ENDPOINT: - data_items: List[str] = self.ssl_certificate_data_items - data_items_friendly_names: Dict[str, str] = self.ssl_certificate_data_items_friendly_names - elif endpoint == MALWARE_INFORMATION_ENDPOINT: - data_items: List[str] = self.malware_information_data_items - data_items_friendly_names = self.malware_information_data_items_friendly_names - elif endpoint == MALWARE_RECORDS_ENDPOINT: - data_items: List[str] = self.malware_records_data_items - data_items_friendly_names = self.malware_records_data_items_friendly_names - elif endpoint == OPEN_SOURCE_INDICATORS_ENDPOINT: - data_items: List[str] = self.os_indicators_data_items - data_items_friendly_names = self.os_indicators_data_items_friendly_names - elif endpoint == C2ATTRIBUTION_ENDPOINT: - data_items: List[str] = self.c2_attribution_data_items - data_items_friendly_names = self.c2_attribution_data_items_friendly_names - - for result in flatten_json_response: - hyas_object = misp_object(endpoint, attribute_value) - for data_item in result.keys(): - if data_item in data_items: - data_item_text = data_items_friendly_names[data_item] - data_item_value = str(result[data_item]) - hyas_object.add_attribute( - **parse_attribute(hyas_object.comment, data_item_text, data_item_value)) - hyas_object.add_reference(self.attribute['uuid'], 'related-to') - self.misp_event.add_object(hyas_object) - - def get_results(self): - """returns the dictionary object to MISP Instance""" - event = json.loads(self.misp_event.to_json()) - results = {key: event[key] for key in ('Attribute', 'Object')} - return {'results': results} - - -def handler(q=False): - """The function which accepts a JSON document to expand the values and return a dictionary of the expanded - values. """ - if q is False: - return False - request = json.loads(q) - # check if the apikey is provided - if not request.get('config') or not request['config'].get('apikey'): - misperrors['error'] = 'HYAS Insight apikey is missing' - return misperrors - apikey = request['config'].get('apikey') - # check attribute is added to the event - if not request.get('attribute') or not check_input_attribute(request['attribute']): - return {'error': f'{standard_error_message}, which should contain at least a type, a value and an uuid.'} - - attribute = request['attribute'] - attribute_type = attribute['type'] - attribute_value = attribute['value'] - - # check if the attribute type is supported by IPQualityScore - if attribute_type not in mispattributes['input']: - return {'error': 'Unsupported attributes type for HYAS Insight Enrichment'} - request_handler = RequestHandler(apikey) - parser = HyasInsightParser(attribute) - has_results = False - if attribute_type in ip_query_input_type: - ip_param = '' - for endpoint in HYAS_IP_ENRICHMENT_ENDPOINTS_LIST: - if endpoint == DEVICE_GEO_ENDPOINT: - if re.match(IPV4_REGEX, attribute_value): - ip_param = IPV4_PARAM - elif re.match(IPV6_REGEX, attribute_value): - ip_param = IPV6_PARAM - elif endpoint == PASSIVE_HASH_ENDPOINT: - ip_param = IPV4_PARAM - elif endpoint == SINKHOLE_ENDPOINT: - ip_param = IPV4_PARAM - elif endpoint == MALWARE_RECORDS_ENDPOINT: - ip_param = IPV4_PARAM - else: - ip_param = IP_PARAM - enrich_response = request_handler.hyas_lookup(endpoint, ip_param, attribute_value) - if endpoint == SSL_CERTIFICATE_ENDPOINT: - enrich_response = enrich_response.get('ssl_certs') - if enrich_response: - has_results = True - parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) - elif attribute_type in domain_query_input_type: - for endpoint in HYAS_DOMAIN_ENRICHMENT_ENDPOINTS_LIST: - if not endpoint == WHOIS_CURRENT_ENDPOINT: - enrich_response = request_handler.hyas_lookup(endpoint, DOMAIN_PARAM, attribute_value) - else: - enrich_response = request_handler.hyas_lookup(endpoint, DOMAIN_PARAM, attribute_value, - endpoint == WHOIS_CURRENT_ENDPOINT) - enrich_response = enrich_response.get('items') - if enrich_response: - has_results = True - parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) - elif attribute_type in email_query_input_type: - for endpoint in HYAS_EMAIL_ENRICHMENT_ENDPOINTS_LIST: - enrich_response = request_handler.hyas_lookup(endpoint, EMAIL_PARAM, attribute_value) - if enrich_response: - has_results = True - parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) - elif attribute_type in phone_query_input_type: - for endpoint in HYAS_PHONE_ENRICHMENT_ENDPOINTS_LIST: - enrich_response = request_handler.hyas_lookup(endpoint, PHONE_PARAM, attribute_value) - if enrich_response: - has_results = True - parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) - elif attribute_type in md5_query_input_type: - md5_param = MD5_PARAM - for endpoint in HYAS_MD5_ENRICHMENT_ENDPOINTS_LIST: - if endpoint == MALWARE_INFORMATION_ENDPOINT: - md5_param = HASH_PARAM - enrich_response = request_handler.hyas_lookup(endpoint, md5_param, attribute_value) - if enrich_response: - has_results = True - if endpoint == MALWARE_INFORMATION_ENDPOINT: - enrich_response = malware_info_lookup_to_markdown(enrich_response) - parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) - elif attribute_type in sha1_query_input_type: - sha1_param = SHA1_PARAM - for endpoint in HYAS_SHA1_ENRICHMENT_ENDPOINTS_LIST: - if endpoint == MALWARE_INFORMATION_ENDPOINT: - sha1_param = HASH_PARAM - elif endpoint == SSL_CERTIFICATE_ENDPOINT: - sha1_param = HASH_PARAM - enrich_response = request_handler.hyas_lookup(endpoint, sha1_param, attribute_value) - - if enrich_response: - has_results = True - if endpoint == MALWARE_INFORMATION_ENDPOINT: - enrich_response = malware_info_lookup_to_markdown(enrich_response) - parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) - elif attribute_type in sha256_query_input_type: - sha256_param = SHA256_PARAM - for endpoint in HYAS_SHA256_ENRICHMENT_ENDPOINTS_LIST: - if endpoint == MALWARE_INFORMATION_ENDPOINT: - sha256_param = HASH_PARAM - enrich_response = request_handler.hyas_lookup(endpoint, sha256_param, attribute_value) - if enrich_response: - has_results = True - if endpoint == MALWARE_INFORMATION_ENDPOINT: - enrich_response = malware_info_lookup_to_markdown(enrich_response) - parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) - elif attribute_type in sha512_query_input_type: - sha512_param = '' - for endpoint in HYAS_SHA512_ENRICHMENT_ENDPOINTS_LIST: - if endpoint == MALWARE_INFORMATION_ENDPOINT: - sha512_param = HASH_PARAM - enrich_response = request_handler.hyas_lookup(endpoint, sha512_param, attribute_value) - if enrich_response: - has_results = True - if endpoint == MALWARE_INFORMATION_ENDPOINT: - enrich_response = malware_info_lookup_to_markdown(enrich_response) - parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) - - if has_results: - return parser.get_results() - else: - return {'error': 'No records found in HYAS Insight for the provided attribute.'} - - -def introspection(): - """The function that returns a dict of the supported attributes (input and output) by your expansion module.""" - return mispattributes - - -def version(): - """The function that returns a dict with the version and the associated meta-data including potential - configurations required of the module. """ - moduleinfo['config'] = moduleconfig - return moduleinfo +import json +import logging +from typing import Dict, List, Any + +import requests +import re +from requests.exceptions import ( + HTTPError, + ProxyError, + InvalidURL, + ConnectTimeout +) +from . import check_input_attribute, standard_error_message +from pymisp import MISPEvent, MISPObject, Distribution + +ip_query_input_type = [ + 'ip-src', + 'ip-dst' +] +domain_query_input_type = [ + 'hostname', + 'domain' +] +email_query_input_type = [ + 'email', + 'email-src', + 'email-dst', + 'target-email', + 'whois-registrant-email' +] +phone_query_input_type = [ + 'phone-number', + 'whois-registrant-phone' +] + +md5_query_input_type = [ + 'md5', + 'x509-fingerprint-md5', + 'ja3-fingerprint-md5', + 'hassh-md5', + 'hasshserver-md5' +] + +sha1_query_input_type = [ + 'sha1', + 'x509-fingerprint-sha1' +] + +sha256_query_input_type = [ + 'sha256', + 'x509-fingerprint-sha256' +] + +sha512_query_input_type = [ + 'sha512' +] + +misperrors = { + 'error': 'Error' +} +mispattributes = { + 'input': ip_query_input_type + domain_query_input_type + email_query_input_type + phone_query_input_type + + md5_query_input_type + sha1_query_input_type + sha256_query_input_type + sha512_query_input_type, + 'format': 'misp_standard' +} + +moduleinfo = { + 'version': '0.1', + 'author': 'Mike Champ', + 'description': 'HYAS Insight integration to MISP provides direct, high volume access to HYAS Insight data. It enables investigators and analysts to understand and defend against cyber adversaries and their infrastructure.', + 'module-type': ['expansion', 'hover'], + 'name': 'HYAS Insight Lookup', + 'logo': 'hyas.png', + 'requirements': ['A HYAS Insight API Key.'], + 'features': 'This Module takes the IP Address, Domain, URL, Email, Phone Number, MD5, SHA1, Sha256, SHA512 MISP Attributes as input to query the HYAS Insight API.\n The results of the HYAS Insight API are than are then returned and parsed into Hyas Insight Objects. \n\nAn API key is required to submit queries to the HYAS Insight API.\n', + 'references': ['https://www.hyas.com/hyas-insight/'], + 'input': 'A MISP attribute of type IP Address(ip-src, ip-dst), Domain(hostname, domain), Email Address(email, email-src, email-dst, target-email, whois-registrant-email), Phone Number(phone-number, whois-registrant-phone), MDS(md5, x509-fingerprint-md5, ja3-fingerprint-md5, hassh-md5, hasshserver-md5), SHA1(sha1, x509-fingerprint-sha1), SHA256(sha256, x509-fingerprint-sha256), SHA512(sha512)', + 'output': 'Hyas Insight objects, resulting from the query on the HYAS Insight API.', +} +moduleconfig = ['apikey'] +TIMEOUT = 60 +logger = logging.getLogger('hyasinsight') +logger.setLevel(logging.DEBUG) +HYAS_API_BASE_URL = 'https://insight.hyas.com/api/ext/' +WHOIS_CURRENT_BASE_URL = 'https://api.hyas.com/' +DEFAULT_DISTRIBUTION_SETTING = Distribution.your_organisation_only.value +IPV4_REGEX = r'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b([^\/]|$)' +IPV6_REGEX = r'\b(?:(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:(?:(:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\b' # noqa: E501 +# Enrichment Types +# HYAS API endpoints +PASSIVE_DNS_ENDPOINT = 'passivedns' +DYNAMIC_DNS_ENDPOINT = 'dynamicdns' +PASSIVE_HASH_ENDPOINT = 'passivehash' +SINKHOLE_ENDPOINT = 'sinkhole' +SSL_CERTIFICATE_ENDPOINT = 'ssl_certificate' +DEVICE_GEO_ENDPOINT = 'device_geo' +WHOIS_HISTORIC_ENDPOINT = 'whois' +WHOIS_CURRENT_ENDPOINT = 'whois/v1' +MALWARE_RECORDS_ENDPOINT = 'sample' +MALWARE_INFORMATION_ENDPOINT = 'sample/information' +C2ATTRIBUTION_ENDPOINT = 'c2attribution' +OPEN_SOURCE_INDICATORS_ENDPOINT = 'os_indicators' + +# HYAS API endpoint params +DOMAIN_PARAM = 'domain' +IP_PARAM = 'ip' +IPV4_PARAM = 'ipv4' +IPV6_PARAM = 'ipv6' +EMAIL_PARAM = 'email' +PHONE_PARAM = 'phone' +MD5_PARAM = 'md5' +SHA256_PARAM = 'sha256' +SHA512_PARAM = 'sha512' +HASH_PARAM = 'hash' +SHA1_PARAM = 'sha1' + +HYAS_IP_ENRICHMENT_ENDPOINTS_LIST = [DYNAMIC_DNS_ENDPOINT, PASSIVE_DNS_ENDPOINT, PASSIVE_HASH_ENDPOINT, + SINKHOLE_ENDPOINT, + SSL_CERTIFICATE_ENDPOINT, DEVICE_GEO_ENDPOINT, C2ATTRIBUTION_ENDPOINT, + MALWARE_RECORDS_ENDPOINT, OPEN_SOURCE_INDICATORS_ENDPOINT] +HYAS_DOMAIN_ENRICHMENT_ENDPOINTS_LIST = [PASSIVE_DNS_ENDPOINT, DYNAMIC_DNS_ENDPOINT, WHOIS_HISTORIC_ENDPOINT, + MALWARE_RECORDS_ENDPOINT, WHOIS_CURRENT_ENDPOINT, PASSIVE_HASH_ENDPOINT, + C2ATTRIBUTION_ENDPOINT, SSL_CERTIFICATE_ENDPOINT, + OPEN_SOURCE_INDICATORS_ENDPOINT] +HYAS_EMAIL_ENRICHMENT_ENDPOINTS_LIST = [DYNAMIC_DNS_ENDPOINT, WHOIS_HISTORIC_ENDPOINT, C2ATTRIBUTION_ENDPOINT] +HYAS_PHONE_ENRICHMENT_ENDPOINTS_LIST = [WHOIS_HISTORIC_ENDPOINT] +HYAS_SHA1_ENRICHMENT_ENDPOINTS_LIST = [SSL_CERTIFICATE_ENDPOINT, MALWARE_INFORMATION_ENDPOINT, + OPEN_SOURCE_INDICATORS_ENDPOINT] +HYAS_SHA256_ENRICHMENT_ENDPOINTS_LIST = [C2ATTRIBUTION_ENDPOINT, MALWARE_INFORMATION_ENDPOINT, + OPEN_SOURCE_INDICATORS_ENDPOINT] +HYAS_SHA512_ENRICHMENT_ENDPOINTS_LIST = [MALWARE_INFORMATION_ENDPOINT] +HYAS_MD5_ENRICHMENT_ENDPOINTS_LIST = [MALWARE_RECORDS_ENDPOINT, MALWARE_INFORMATION_ENDPOINT, + OPEN_SOURCE_INDICATORS_ENDPOINT] + +HYAS_OBJECT_NAMES = { + DYNAMIC_DNS_ENDPOINT: "Dynamic DNS Information", + PASSIVE_HASH_ENDPOINT: "Passive Hash Information", + SINKHOLE_ENDPOINT: "Sinkhole Information", + SSL_CERTIFICATE_ENDPOINT: "SSL Certificate Information", + DEVICE_GEO_ENDPOINT: "Mobile Geolocation Information", + C2ATTRIBUTION_ENDPOINT: "C2 Attribution Information", + PASSIVE_DNS_ENDPOINT: "Passive DNS Information", + WHOIS_HISTORIC_ENDPOINT: "Whois Related Information", + WHOIS_CURRENT_ENDPOINT: "Whois Current Related Information", + MALWARE_INFORMATION_ENDPOINT: "Malware Sample Information", + OPEN_SOURCE_INDICATORS_ENDPOINT: "Open Source Intel for malware, ssl certificates and other indicators Information", + MALWARE_RECORDS_ENDPOINT: "Malware Sample Records Information" +} + + +def parse_attribute(comment, feature, value): + """Generic Method for parsing the attributes in the object""" + attribute = { + 'type': 'text', + 'value': value, + 'comment': comment, + 'distribution': DEFAULT_DISTRIBUTION_SETTING, + 'object_relation': feature + } + return attribute + + +def misp_object(endpoint, attribute_value): + object_name = HYAS_OBJECT_NAMES[endpoint] + hyas_object = MISPObject(object_name) + hyas_object.distribution = DEFAULT_DISTRIBUTION_SETTING + hyas_object.template_uuid = "d69d3d15-7b4d-49b1-9e0a-bb29f3d421d9" + hyas_object.template_id = "1" + hyas_object.description = "HYAS INSIGHT " + object_name + hyas_object.comment = "HYAS INSIGHT " + object_name + " for " + attribute_value + setattr(hyas_object, 'meta-category', 'network') + description = ( + "An object containing the enriched attribute and " + "related entities from HYAS Insight." + ) + hyas_object.from_dict( + **{"meta-category": "misc", "description": description, + "distribution": DEFAULT_DISTRIBUTION_SETTING} + ) + return hyas_object + + +def flatten_json(y: Dict) -> Dict[str, Any]: + """ + :param y: raw_response from HYAS api + :return: Flatten json response + """ + out = {} + + def flatten(x, name=''): + # If the Nested key-value + # pair is of dict type + if type(x) is dict: + for a in x: + flatten(x[a], name + a + '_') + else: + out[name[:-1]] = x + + flatten(y) + return out + + +def get_flatten_json_response(raw_api_response: List[Dict]) -> List[Dict]: + """ + :param raw_api_response: raw_api response from the API + :return: Flatten Json response + """ + flatten_json_response = [] + if raw_api_response: + for obj in raw_api_response: + flatten_json_response.append(flatten_json(obj)) + + return flatten_json_response + + +def request_body(query_input, query_param, current): + """ + This Method returns the request body for specific endpoint. + """ + + if current: + return { + "applied_filters": { + query_input: query_param, + "current": True + } + } + else: + return { + "applied_filters": { + query_input: query_param + } + } + + +def malware_info_lookup_to_markdown(results: Dict) -> list: + scan_results = results.get('scan_results', []) + out = [] + if scan_results: + for res in scan_results: + malware_info_data = { + "avscan_score": results.get( + "avscan_score", ''), + "md5": results.get("md5", ''), + 'av_name': res.get( + "av_name", ''), + 'def_time': res.get( + "def_time", ''), + 'threat_found': res.get( + 'threat_found', ''), + 'scan_time': results.get("scan_time", ''), + 'sha1': results.get('sha1', ''), + 'sha256': results.get('sha256', ''), + 'sha512': results.get('sha512', '') + } + out.append(malware_info_data) + else: + malware_info_data = { + "avscan_score": results.get("avscan_score", ''), + "md5": results.get("md5", ''), + 'av_name': '', + 'def_time': '', + 'threat_found': '', + 'scan_time': results.get("scan_time", ''), + 'sha1': results.get('sha1', ''), + 'sha256': results.get('sha256', ''), + 'sha512': results.get('sha512', '') + } + out.append(malware_info_data) + return out + + +class RequestHandler: + """A class for handling any outbound requests from this module.""" + + def __init__(self, apikey): + self.session = requests.Session() + self.api_key = apikey + + def get(self, url: str, headers: dict = None, req_body=None) -> requests.Response: + """General post method to fetch the response from HYAS Insight.""" + response = [] + try: + response = self.session.post( + url, headers=headers, json=req_body + ) + if response: + response = response.json() + except (ConnectTimeout, ProxyError, InvalidURL) as error: + msg = "Error connecting with the HYAS Insight." + logger.error(f"{msg} Error: {error}") + misperrors["error"] = msg + return response + + def hyas_lookup(self, end_point: str, query_input, query_param, current=False) -> requests.Response: + """Do a lookup call.""" + # Building the request + if current: + url = f'{WHOIS_CURRENT_BASE_URL}{WHOIS_CURRENT_ENDPOINT}' + else: + url = f'{HYAS_API_BASE_URL}{end_point}' + headers = { + 'Content-type': 'application/json', + 'X-API-Key': self.api_key, + 'User-Agent': 'Misp Modules' + } + req_body = request_body(query_input, query_param, current) + try: + response = self.get(url, headers, req_body) + except HTTPError as error: + msg = f"Error when requesting data from HYAS Insight. {error.response}: {error.response.reason}" + logger.error(msg) + misperrors["error"] = msg + raise + return response + + +class HyasInsightParser: + """A class for handling the enrichment objects""" + + def __init__(self, attribute): + self.attribute = attribute + self.misp_event = MISPEvent() + self.misp_event.add_attribute(**attribute) + + self.c2_attribution_data_items = [ + 'actor_ipv4', + 'c2_domain', + 'c2_ip', + 'c2_url', + 'datetime', + 'email', + 'email_domain', + 'referrer_domain', + 'referrer_ipv4', + 'referrer_url', + 'sha256' + ] + self.c2_attribution_data_items_friendly_names = { + 'actor_ipv4': 'Actor IPv4', + 'c2_domain': 'C2 Domain', + 'c2_ip': 'C2 IP', + 'c2_url': 'C2 URL', + 'datetime': 'DateTime', + 'email': 'Email', + 'email_domain': 'Email Domain', + 'referrer_domain': 'Referrer Domain', + 'referrer_ipv4': 'Referrer IPv4', + 'referrer_url': 'Referrer URL', + 'sha256': 'SHA256' + } + + self.device_geo_data_items = [ + 'datetime', + 'device_user_agent', + 'geo_country_alpha_2', + 'geo_horizontal_accuracy', + 'ipv4', + 'ipv6', + 'latitude', + 'longitude', + 'wifi_bssid' + ] + + self.device_geo_data_items_friendly_names = { + 'datetime': 'DateTime', + 'device_user_agent': 'Device User Agent', + 'geo_country_alpha_2': 'Alpha-2 Code', + 'geo_horizontal_accuracy': 'GPS Horizontal Accuracy', + 'ipv4': 'IPv4 Address', + 'ipv6': 'IPv6 Address', + 'latitude': 'Latitude', + 'longitude': 'Longitude', + 'wifi_bssid': 'WIFI BSSID' + } + + self.dynamic_dns_data_items = [ + 'a_record', + 'account', + 'created', + 'created_ip', + 'domain', + 'domain_creator_ip', + 'email', + ] + + self.dynamic_dns_data_items_friendly_names = { + 'a_record': 'A Record', + 'account': 'Account Holder', + 'created': 'Created Date', + 'created_ip': 'Account Holder IP Address', + 'domain': 'Domain', + 'domain_creator_ip': 'Domain Creator IP Address', + 'email': 'Email Address', + } + + self.os_indicators_data_items = [ + 'context', + 'datetime', + 'domain', + 'domain_2tld', + 'first_seen', + 'ipv4', + 'ipv6', + 'last_seen', + 'md5', + 'sha1', + 'sha256', + 'source_name', + 'source_url', + 'url' + ] + + self.os_indicators_data_items_friendly_names = { + 'context': 'Context', + 'datetime': 'DateTime', + 'domain': 'Domain', + 'domain_2tld': 'Domain 2TLD', + 'first_seen': 'First Seen', + 'ipv4': 'IPv4 Address', + 'ipv6': 'IPv6 Address', + 'last_seen': 'Last Seen', + 'md5': 'MD5', + 'sha1': 'SHA1', + 'sha256': 'SHA256', + 'source_name': 'Source Name', + 'source_url': 'Source URL', + 'url': 'URL' + } + + self.passive_dns_data_items = [ + 'cert_name', + 'count', + 'domain', + 'first_seen', + 'ip_geo_city_name', + 'ip_geo_country_iso_code', + 'ip_geo_country_name', + 'ip_geo_location_latitude', + 'ip_geo_location_longitude', + 'ip_geo_postal_code', + 'ip_ip', + 'ip_isp_autonomous_system_number', + 'ip_isp_autonomous_system_organization', + 'ip_isp_ip_address', + 'ip_isp_isp', + 'ip_isp_organization', + 'ipv4', + 'ipv6', + 'last_seen' + ] + + self.passive_dns_data_items_friendly_names = { + 'cert_name': 'Certificate Provider Name', + 'count': 'Passive DNS Count', + 'domain': 'Domain', + 'first_seen': 'First Seen', + 'ip_geo_city_name': 'IP Organization City', + 'ip_geo_country_iso_code': 'IP Organization Country ISO Code', + 'ip_geo_country_name': 'IP Organization Country Name', + 'ip_geo_location_latitude': 'IP Organization Latitude', + 'ip_geo_location_longitude': 'IP Organization Longitude', + 'ip_geo_postal_code': 'IP Organization Postal Code', + 'ip_ip': 'IP Address', + 'ip_isp_autonomous_system_number': 'ASN IP', + 'ip_isp_autonomous_system_organization': 'ASO IP', + 'ip_isp_ip_address': 'IP Address', + 'ip_isp_isp': 'ISP', + 'ip_isp_organization': 'ISP Organization', + 'ipv4': 'IPv4 Address', + 'ipv6': 'IPv6 Address', + 'last_seen': 'Last Seen' + } + + self.passive_hash_data_items = [ + 'domain', + 'md5_count' + ] + + self.passive_hash_data_items_friendly_names = { + 'domain': 'Domain', + 'md5_count': 'Passive DNS Count' + } + + self.malware_records_data_items = [ + 'datetime', + 'domain', + 'ipv4', + 'ipv6', + 'md5', + 'sha1', + 'sha256' + ] + + self.malware_records_data_items_friendly_names = { + 'datetime': 'DateTime', + 'domain': 'Domain', + 'ipv4': 'IPv4 Address', + 'ipv6': 'IPv6 Address', + 'md5': 'MD5', + 'sha1': 'SHA1', + 'sha256': 'SHA256' + } + + self.malware_information_data_items = [ + 'avscan_score', + 'md5', + 'av_name', + 'def_time', + 'threat_found', + 'scan_time', + 'sha1', + 'sha256', + 'sha512' + ] + + self.malware_information_data_items_friendly_names = { + 'avscan_score': 'AV Scan Score', + 'md5': 'MD5', + 'av_name': 'AV Name', + 'def_time': 'AV DateTime', + 'threat_found': 'Source', + 'scan_time': 'Scan DateTime', + 'sha1': 'SHA1', + 'sha256': 'SHA256', + 'sha512': 'SHA512' + } + + self.sinkhole_data_items = [ + 'count', + 'country_name', + 'country_code', + 'data_port', + 'datetime', + 'ipv4', + 'last_seen', + 'organization_name', + 'sink_source' + ] + + self.sinkhole_data_items_friendly_names = { + 'count': 'Sinkhole Count', + 'country_name': 'IP Address Country', + 'country_code': 'IP Address Country Code', + 'data_port': 'Data Port', + 'datetime': 'First Seen', + 'ipv4': 'IP Address', + 'last_seen': 'Last Seen', + 'organization_name': 'ISP Organization', + 'sink_source': 'Sink Source IP' + } + + self.ssl_certificate_data_items = [ + 'ip', + 'ssl_cert_cert_key', + 'ssl_cert_expire_date', + 'ssl_cert_issue_date', + 'ssl_cert_issuer_commonName', + 'ssl_cert_issuer_countryName', + 'ssl_cert_issuer_localityName', + 'ssl_cert_issuer_organizationName', + 'ssl_cert_issuer_organizationalUnitName', + 'ssl_cert_issuer_stateOrProvinceName', + 'ssl_cert_md5', + 'ssl_cert_serial_number', + 'ssl_cert_sha1', + 'ssl_cert_sha_256', + 'ssl_cert_sig_algo', + 'ssl_cert_ssl_version', + 'ssl_cert_subject_commonName', + 'ssl_cert_subject_countryName', + 'ssl_cert_subject_localityName', + 'ssl_cert_subject_organizationName', + 'ssl_cert_subject_organizationalUnitName', + 'ssl_cert_timestamp' + ] + + self.ssl_certificate_data_items_friendly_names = { + 'ip': 'IP Address', + 'ssl_cert_cert_key': 'Certificate Key', + 'ssl_cert_expire_date': 'Certificate Expiration Date', + 'ssl_cert_issue_date': 'Certificate Issue Date', + 'ssl_cert_issuer_commonName': 'Issuer Common Name', + 'ssl_cert_issuer_countryName': 'Issuer Country Name', + 'ssl_cert_issuer_localityName': 'Issuer City Name', + 'ssl_cert_issuer_organizationName': 'Issuer Organization Name', + 'ssl_cert_issuer_organizationalUnitName': 'Issuer Organization Unit Name', + 'ssl_cert_issuer_stateOrProvinceName': 'Issuer State or Province Name', + 'ssl_cert_md5': 'Certificate MD5', + 'ssl_cert_serial_number': 'Certificate Serial Number', + 'ssl_cert_sha1': 'Certificate SHA1', + 'ssl_cert_sha_256': 'Certificate SHA256', + 'ssl_cert_sig_algo': 'Certificate Signature Algorithm', + 'ssl_cert_ssl_version': 'SSL Version', + 'ssl_cert_subject_commonName': 'Reciever Subject Name', + 'ssl_cert_subject_countryName': 'Receiver Country Name', + 'ssl_cert_subject_localityName': 'Receiver City Name', + 'ssl_cert_subject_organizationName': 'Receiver Organization Name', + 'ssl_cert_subject_organizationalUnitName': 'Receiver Organization Unit Name', + 'ssl_cert_timestamp': 'Certificate DateTime' + } + + self.whois_historic_data_items = [ + 'abuse_emails', + 'address', + 'city', + 'country', + 'datetime', + 'domain', + 'domain_2tld', + 'domain_created_datetime', + 'domain_expires_datetime', + 'domain_updated_datetime', + 'email', + 'idn_name', + 'name', + 'nameserver', + 'organization', + 'phone', + 'privacy_punch', + 'registrar' + ] + + self.whois_historic_data_items_friendly_names = { + 'abuse_emails': 'Abuse Emails', + 'address': 'Address', + 'city': 'City', + 'country': 'Country', + 'datetime': 'Datetime', + 'domain': 'Domain', + 'domain_2tld': 'Domain 2tld', + 'domain_created_datetime': 'Domain Created Time', + 'domain_expires_datetime': 'Domain Expires Time', + 'domain_updated_datetime': 'Domain Updated Time', + 'email': 'Email Address', + 'idn_name': 'IDN Name', + 'name': 'Name', + 'nameserver': 'Nameserver', + 'organization': 'Organization', + 'phone': 'Phone Info', + 'privacy_punch': 'Privacy Punch', + 'registrar': 'Registrar' + } + + self.whois_current_data_items = [ + 'abuse_emails', + 'address', + 'city', + 'country', + 'datetime', + 'domain', + 'domain_2tld', + 'domain_created_datetime', + 'domain_expires_datetime', + 'domain_updated_datetime', + 'email', + 'idn_name', + 'name', + 'nameserver', + 'organization', + 'phone', + 'privacy_punch', + 'registrar', + 'state' + ] + + self.whois_current_data_items_friendly_names = { + 'abuse_emails': 'Abuse Emails', + 'address': 'Address', + 'city': 'City', + 'country': 'Country', + 'datetime': 'Datetime', + 'domain': 'Domain', + 'domain_2tld': 'Domain 2tld', + 'domain_created_datetime': 'Domain Created Time', + 'domain_expires_datetime': 'Domain Expires Time', + 'domain_updated_datetime': 'Domain Updated Time', + 'email': 'Email Address', + 'idn_name': 'IDN Name', + 'name': 'Name', + 'nameserver': 'Nameserver', + 'organization': 'Organization', + 'phone': 'Phone', + 'privacy_punch': 'Privacy Punch', + 'registrar': 'Registrar', + 'state': 'State' + } + + def create_misp_attributes_and_objects(self, response, endpoint, attribute_value): + flatten_json_response = get_flatten_json_response(response) + data_items: List[str] = [] + data_items_friendly_names: Dict[str, str] = {} + if endpoint == DEVICE_GEO_ENDPOINT: + data_items: List[str] = self.device_geo_data_items + data_items_friendly_names: Dict[str, str] = self.device_geo_data_items_friendly_names + elif endpoint == DYNAMIC_DNS_ENDPOINT: + data_items: List[str] = self.dynamic_dns_data_items + data_items_friendly_names: Dict[str, str] = self.dynamic_dns_data_items_friendly_names + elif endpoint == PASSIVE_DNS_ENDPOINT: + data_items: List[str] = self.passive_dns_data_items + data_items_friendly_names: Dict[str, str] = self.passive_dns_data_items_friendly_names + elif endpoint == PASSIVE_HASH_ENDPOINT: + data_items: List[str] = self.passive_hash_data_items + data_items_friendly_names: Dict[str, str] = self.passive_hash_data_items_friendly_names + elif endpoint == SINKHOLE_ENDPOINT: + data_items: List[str] = self.sinkhole_data_items + data_items_friendly_names: Dict[str, str] = self.sinkhole_data_items_friendly_names + elif endpoint == WHOIS_HISTORIC_ENDPOINT: + data_items = self.whois_historic_data_items + data_items_friendly_names = self.whois_historic_data_items_friendly_names + elif endpoint == WHOIS_CURRENT_ENDPOINT: + data_items: List[str] = self.whois_current_data_items + data_items_friendly_names: Dict[str, str] = self.whois_current_data_items_friendly_names + elif endpoint == SSL_CERTIFICATE_ENDPOINT: + data_items: List[str] = self.ssl_certificate_data_items + data_items_friendly_names: Dict[str, str] = self.ssl_certificate_data_items_friendly_names + elif endpoint == MALWARE_INFORMATION_ENDPOINT: + data_items: List[str] = self.malware_information_data_items + data_items_friendly_names = self.malware_information_data_items_friendly_names + elif endpoint == MALWARE_RECORDS_ENDPOINT: + data_items: List[str] = self.malware_records_data_items + data_items_friendly_names = self.malware_records_data_items_friendly_names + elif endpoint == OPEN_SOURCE_INDICATORS_ENDPOINT: + data_items: List[str] = self.os_indicators_data_items + data_items_friendly_names = self.os_indicators_data_items_friendly_names + elif endpoint == C2ATTRIBUTION_ENDPOINT: + data_items: List[str] = self.c2_attribution_data_items + data_items_friendly_names = self.c2_attribution_data_items_friendly_names + + for result in flatten_json_response: + hyas_object = misp_object(endpoint, attribute_value) + for data_item in result.keys(): + if data_item in data_items: + data_item_text = data_items_friendly_names[data_item] + data_item_value = str(result[data_item]) + hyas_object.add_attribute( + **parse_attribute(hyas_object.comment, data_item_text, data_item_value)) + hyas_object.add_reference(self.attribute['uuid'], 'related-to') + self.misp_event.add_object(hyas_object) + + def get_results(self): + """returns the dictionary object to MISP Instance""" + event = json.loads(self.misp_event.to_json()) + results = {key: event[key] for key in ('Attribute', 'Object')} + return {'results': results} + + +def handler(q=False): + """The function which accepts a JSON document to expand the values and return a dictionary of the expanded + values. """ + if q is False: + return False + request = json.loads(q) + # check if the apikey is provided + if not request.get('config') or not request['config'].get('apikey'): + misperrors['error'] = 'HYAS Insight apikey is missing' + return misperrors + apikey = request['config'].get('apikey') + # check attribute is added to the event + if not request.get('attribute') or not check_input_attribute(request['attribute']): + return {'error': f'{standard_error_message}, which should contain at least a type, a value and an uuid.'} + + attribute = request['attribute'] + attribute_type = attribute['type'] + attribute_value = attribute['value'] + + # check if the attribute type is supported by IPQualityScore + if attribute_type not in mispattributes['input']: + return {'error': 'Unsupported attributes type for HYAS Insight Enrichment'} + request_handler = RequestHandler(apikey) + parser = HyasInsightParser(attribute) + has_results = False + if attribute_type in ip_query_input_type: + ip_param = '' + for endpoint in HYAS_IP_ENRICHMENT_ENDPOINTS_LIST: + if endpoint == DEVICE_GEO_ENDPOINT: + if re.match(IPV4_REGEX, attribute_value): + ip_param = IPV4_PARAM + elif re.match(IPV6_REGEX, attribute_value): + ip_param = IPV6_PARAM + elif endpoint == PASSIVE_HASH_ENDPOINT: + ip_param = IPV4_PARAM + elif endpoint == SINKHOLE_ENDPOINT: + ip_param = IPV4_PARAM + elif endpoint == MALWARE_RECORDS_ENDPOINT: + ip_param = IPV4_PARAM + else: + ip_param = IP_PARAM + enrich_response = request_handler.hyas_lookup(endpoint, ip_param, attribute_value) + if endpoint == SSL_CERTIFICATE_ENDPOINT: + enrich_response = enrich_response.get('ssl_certs') + if enrich_response: + has_results = True + parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) + elif attribute_type in domain_query_input_type: + for endpoint in HYAS_DOMAIN_ENRICHMENT_ENDPOINTS_LIST: + if not endpoint == WHOIS_CURRENT_ENDPOINT: + enrich_response = request_handler.hyas_lookup(endpoint, DOMAIN_PARAM, attribute_value) + else: + enrich_response = request_handler.hyas_lookup(endpoint, DOMAIN_PARAM, attribute_value, + endpoint == WHOIS_CURRENT_ENDPOINT) + enrich_response = enrich_response.get('items') + if enrich_response: + has_results = True + parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) + elif attribute_type in email_query_input_type: + for endpoint in HYAS_EMAIL_ENRICHMENT_ENDPOINTS_LIST: + enrich_response = request_handler.hyas_lookup(endpoint, EMAIL_PARAM, attribute_value) + if enrich_response: + has_results = True + parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) + elif attribute_type in phone_query_input_type: + for endpoint in HYAS_PHONE_ENRICHMENT_ENDPOINTS_LIST: + enrich_response = request_handler.hyas_lookup(endpoint, PHONE_PARAM, attribute_value) + if enrich_response: + has_results = True + parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) + elif attribute_type in md5_query_input_type: + md5_param = MD5_PARAM + for endpoint in HYAS_MD5_ENRICHMENT_ENDPOINTS_LIST: + if endpoint == MALWARE_INFORMATION_ENDPOINT: + md5_param = HASH_PARAM + enrich_response = request_handler.hyas_lookup(endpoint, md5_param, attribute_value) + if enrich_response: + has_results = True + if endpoint == MALWARE_INFORMATION_ENDPOINT: + enrich_response = malware_info_lookup_to_markdown(enrich_response) + parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) + elif attribute_type in sha1_query_input_type: + sha1_param = SHA1_PARAM + for endpoint in HYAS_SHA1_ENRICHMENT_ENDPOINTS_LIST: + if endpoint == MALWARE_INFORMATION_ENDPOINT: + sha1_param = HASH_PARAM + elif endpoint == SSL_CERTIFICATE_ENDPOINT: + sha1_param = HASH_PARAM + enrich_response = request_handler.hyas_lookup(endpoint, sha1_param, attribute_value) + + if enrich_response: + has_results = True + if endpoint == MALWARE_INFORMATION_ENDPOINT: + enrich_response = malware_info_lookup_to_markdown(enrich_response) + parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) + elif attribute_type in sha256_query_input_type: + sha256_param = SHA256_PARAM + for endpoint in HYAS_SHA256_ENRICHMENT_ENDPOINTS_LIST: + if endpoint == MALWARE_INFORMATION_ENDPOINT: + sha256_param = HASH_PARAM + enrich_response = request_handler.hyas_lookup(endpoint, sha256_param, attribute_value) + if enrich_response: + has_results = True + if endpoint == MALWARE_INFORMATION_ENDPOINT: + enrich_response = malware_info_lookup_to_markdown(enrich_response) + parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) + elif attribute_type in sha512_query_input_type: + sha512_param = '' + for endpoint in HYAS_SHA512_ENRICHMENT_ENDPOINTS_LIST: + if endpoint == MALWARE_INFORMATION_ENDPOINT: + sha512_param = HASH_PARAM + enrich_response = request_handler.hyas_lookup(endpoint, sha512_param, attribute_value) + if enrich_response: + has_results = True + if endpoint == MALWARE_INFORMATION_ENDPOINT: + enrich_response = malware_info_lookup_to_markdown(enrich_response) + parser.create_misp_attributes_and_objects(enrich_response, endpoint, attribute_value) + + if has_results: + return parser.get_results() + else: + return {'error': 'No records found in HYAS Insight for the provided attribute.'} + + +def introspection(): + """The function that returns a dict of the supported attributes (input and output) by your expansion module.""" + return mispattributes + + +def version(): + """The function that returns a dict with the version and the associated meta-data including potential + configurations required of the module. """ + moduleinfo['config'] = moduleconfig + return moduleinfo diff --git a/misp_modules/modules/expansion/intel471.py b/misp_modules/modules/expansion/intel471.py index bf95b2e3..a8127c7a 100755 --- a/misp_modules/modules/expansion/intel471.py +++ b/misp_modules/modules/expansion/intel471.py @@ -5,8 +5,20 @@ misperrors = {'error': 'Error'} mispattributes = {'input': ['hostname', 'domain', 'url', 'ip-src', 'ip-dst', 'email-src', 'email-dst', 'target-email', 'whois-registrant-email', 'whois-registrant-name', 'md5', 'sha1', 'sha256'], 'output': ['freetext']} -moduleinfo = {'version': '0.1', 'author': 'Raphaël Vinot', 'description': 'Module to access Intel 471', - 'module-type': ['hover', 'expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Raphaël Vinot', + 'description': 'Module to access Intel 471', + 'module-type': ['hover', 'expansion'], + 'name': 'Intel471 Lookup', + 'logo': 'intel471.png', + 'requirements': ['The intel471 python library'], + 'features': 'The module uses the Intel471 python library to query the Intel471 API with the value of the input attribute. The result of the query is then returned as freetext so the Freetext import parses it.', + 'references': ['https://public.intel471.com/'], + 'input': 'A MISP attribute whose type is included in the following list:\n- hostname\n- domain\n- url\n- ip-src\n- ip-dst\n- email-src\n- email-dst\n- target-email\n- whois-registrant-email\n- whois-registrant-name\n- md5\n- sha1\n- sha256', + 'output': 'Freetext', + 'descrption': 'An expansion module to query Intel471 in order to get additional information about a domain, ip address, email address, url or hash.', +} moduleconfig = ['email', 'authkey'] diff --git a/misp_modules/modules/expansion/ip2locationio.py b/misp_modules/modules/expansion/ip2locationio.py index 5303b15c..607ff042 100644 --- a/misp_modules/modules/expansion/ip2locationio.py +++ b/misp_modules/modules/expansion/ip2locationio.py @@ -10,8 +10,15 @@ mispattributes = { moduleinfo = { 'version': 1, 'author': 'IP2Location.io', - 'description': 'An expansion module to query IP2Location.io for additional information on an IP address', - 'module-type': ['expansion', 'hover'] + 'description': 'An expansion module to query IP2Location.io to gather more information on a given IP address.', + 'module-type': ['expansion', 'hover'], + 'name': 'IP2Location.io Lookup', + 'logo': 'ip2locationio.png', + 'requirements': ['An IP2Location.io token'], + 'features': 'The module takes an IP address attribute as input and queries the IP2Location.io API. \nFree plan user will get the basic geolocation informaiton, and different subsription plan will get more information on the IP address. \n Refer to [pricing page](https://www.ip2location.io/pricing) for more information on data available for each plan. \n\nMore information on the responses content is available in the [documentation](https://www.ip2location.io/ip2location-documentation).', + 'references': ['https://www.ip2location.io/ip2location-documentation'], + 'input': 'IP address attribute.', + 'output': 'Additional information on the IP address, such as geolocation, proxy and so on. Refer to the Response Format section in https://www.ip2location.io/ip2location-documentation to find out the full format of the data returned.', } moduleconfig = ['key'] diff --git a/misp_modules/modules/expansion/ipasn.py b/misp_modules/modules/expansion/ipasn.py index 3a32358c..8f7948d4 100755 --- a/misp_modules/modules/expansion/ipasn.py +++ b/misp_modules/modules/expansion/ipasn.py @@ -6,10 +6,20 @@ from pyipasnhistory import IPASNHistory from pymisp import MISPAttribute, MISPEvent, MISPObject misperrors = {'error': 'Error'} -mispattributes = {'input': ['ip-src', 'ip-dst'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.2', 'author': 'Raphaël Vinot', - 'description': 'Query an IP ASN history service (https://github.com/CIRCL/IP-ASN-history.git)', - 'module-type': ['expansion', 'hover']} +mispattributes = {'input': ['ip-src', 'ip-dst', 'ip'], 'format': 'misp_standard'} +moduleinfo = { + 'version': '0.3', + 'author': 'Raphaël Vinot', + 'description': 'Module to query an IP ASN history service (https://github.com/D4-project/IPASN-History).', + 'module-type': ['expansion', 'hover'], + 'name': 'IPASN-History Lookup', + 'logo': '', + 'requirements': ['pyipasnhistory: Python library to access IPASN-history instance'], + 'features': 'This module takes an IP address attribute as input and queries the CIRCL IPASN service. The result of the query is the latest asn related to the IP address, that is returned as a MISP object.', + 'references': ['https://github.com/D4-project/IPASN-History'], + 'input': 'An IP address MISP attribute.', + 'output': 'Asn object(s) objects related to the IP address used as input.', +} def parse_result(attribute, values): @@ -18,7 +28,6 @@ def parse_result(attribute, values): initial_attribute.from_dict(**attribute) event.add_attribute(**initial_attribute) mapping = {'asn': ('AS', 'asn'), 'prefix': ('ip-src', 'subnet-announced')} - print(values) for last_seen, response in values['response'].items(): asn = MISPObject('asn') asn.add_attribute('last-seen', **{'type': 'datetime', 'value': last_seen}) @@ -39,6 +48,9 @@ def handler(q=False): return {'error': f'{standard_error_message}, which should contain at least a type, a value and an uuid.'} if request['attribute']['type'] not in mispattributes['input']: return {'error': 'Unsupported attribute type.'} + if request['attribute']['type'] == 'ip': + request['attribute']['type'] = 'ip-src' + toquery = request['attribute']['value'] ipasn = IPASNHistory() diff --git a/misp_modules/modules/expansion/ipinfo.py b/misp_modules/modules/expansion/ipinfo.py index e83f4ad8..6fb0ca27 100644 --- a/misp_modules/modules/expansion/ipinfo.py +++ b/misp_modules/modules/expansion/ipinfo.py @@ -10,8 +10,15 @@ mispattributes = { moduleinfo = { 'version': 1, 'author': 'Christian Studer', - 'description': 'An expansion module to query ipinfo.io for additional information on an IP address', - 'module-type': ['expansion', 'hover'] + 'description': 'An expansion module to query ipinfo.io to gather more information on a given IP address.', + 'module-type': ['expansion', 'hover'], + 'name': 'IPInfo.io Lookup', + 'logo': 'ipinfo.png', + 'requirements': ['An ipinfo.io token'], + 'features': 'The module takes an IP address attribute as input and queries the ipinfo.io API. \nThe geolocation information on the IP address is always returned.\n\nDepending on the subscription plan, the API returns different pieces of information then:\n- With a basic plan (free) you get the AS number and the AS organisation name concatenated in the `org` field.\n- With a paid subscription, the AS information is returned in the `asn` field with additional AS information, and depending on which plan the user has, you can also get information on the privacy method used to protect the IP address, the related domains, or the point of contact related to the IP address in case of an abuse.\n\nMore information on the responses content is available in the [documentation](https://ipinfo.io/developers).', + 'references': ['https://ipinfo.io/developers'], + 'input': 'IP address attribute.', + 'output': 'Additional information on the IP address, like its geolocation, the autonomous system it is included in, and the related domain(s).', } moduleconfig = ['token'] @@ -87,7 +94,7 @@ def handler(q=False): asn.add_attribute('asn', as_value) asn.add_attribute('description', ' '.join(description)) misp_event.add_object(asn) - + # Return the results in MISP format event = json.loads(misp_event.to_json()) diff --git a/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py b/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py index bb582849..68063775 100644 --- a/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py +++ b/misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py @@ -1,627 +1,633 @@ -import json -import logging -import requests -from requests.exceptions import ( - HTTPError, - ProxyError, - InvalidURL, - ConnectTimeout -) -from . import check_input_attribute, standard_error_message -from pymisp import MISPEvent, MISPAttribute, MISPObject, MISPTag, Distribution - -ip_query_input_type = [ - 'ip-src', - 'ip-dst' -] -url_query_input_type = [ - 'hostname', - 'domain', - 'url', - 'uri' -] -email_query_input_type = [ - 'email', - 'email-src', - 'email-dst', - 'target-email', - 'whois-registrant-email' -] -phone_query_input_type = [ - 'phone-number', - 'whois-registrant-phone' -] - -misperrors = { - 'error': 'Error' -} -mispattributes = { - 'input': ip_query_input_type + url_query_input_type + email_query_input_type + phone_query_input_type, - 'format': 'misp_standard' -} -moduleinfo = { - 'version': '0.1', - 'author': 'David Mackler', - 'description': 'IPQualityScore MISP Expansion Module for IP reputation, Email Validation, Phone Number Validation,' - 'Malicious Domain and Malicious URL Scanner.', - 'module-type': ['expansion', 'hover'] -} -moduleconfig = ['apikey'] - -logger = logging.getLogger('ipqualityscore') -logger.setLevel(logging.DEBUG) -BASE_URL = 'https://ipqualityscore.com/api/json' -DEFAULT_DISTRIBUTION_SETTING = Distribution.your_organisation_only.value -IP_ENRICH = 'ip' -URL_ENRICH = 'url' -EMAIL_ENRICH = 'email' -PHONE_ENRICH = 'phone' - - -class RequestHandler: - """A class for handling any outbound requests from this module.""" - - def __init__(self, apikey): - self.session = requests.Session() - self.api_key = apikey - - def get(self, url: str, headers: dict = None, params: dict = None) -> requests.Response: - """General get method to fetch the response from IPQualityScore.""" - try: - response = self.session.get( - url, headers=headers, params=params - ).json() - if str(response["success"]) != "True": - msg = response["message"] - logger.error(f"Error: {msg}") - misperrors["error"] = msg - else: - return response - except (ConnectTimeout, ProxyError, InvalidURL) as error: - msg = "Error connecting with the IPQualityScore." - logger.error(f"{msg} Error: {error}") - misperrors["error"] = msg - - def ipqs_lookup(self, reputation_type: str, ioc: str) -> requests.Response: - """Do a lookup call.""" - url = f"{BASE_URL}/{reputation_type}" - payload = {reputation_type: ioc} - headers = {"IPQS-KEY": self.api_key} - try: - response = self.get(url, headers, payload) - except HTTPError as error: - msg = f"Error when requesting data from IPQualityScore. {error.response}: {error.response.reason}" - logger.error(msg) - misperrors["error"] = msg - raise - return response - - -def parse_attribute(comment, feature, value): - """Generic Method for parsing the attributes in the object""" - attribute = { - 'type': 'text', - 'value': value, - 'comment': comment, - 'distribution': DEFAULT_DISTRIBUTION_SETTING, - 'object_relation': feature - } - return attribute - - -class IPQualityScoreParser: - """A class for handling the enrichment objects""" - - def __init__(self, attribute): - self.rf_white = "#CCCCCC" - self.rf_grey = " #CDCDCD" - self.rf_yellow = "#FFCF00" - self.rf_red = "#D10028" - self.clean = "CLEAN" - self.low = "LOW RISK" - self.medium = "MODERATE RISK" - self.high = "HIGH RISK" - self.critical = "CRITICAL" - self.invalid = "INVALID" - self.suspicious = "SUSPICIOUS" - self.malware = "CRITICAL" - self.phishing = "CRITICAL" - self.disposable = "CRITICAL" - self.attribute = attribute - self.misp_event = MISPEvent() - self.misp_event.add_attribute(**attribute) - self.ipqs_object = MISPObject('IPQS Fraud and Risk Scoring Object') - self.ipqs_object.template_uuid = "57d066e6-6d66-42a7-a1ad-e075e39b2b5e" - self.ipqs_object.template_id = "1" - self.ipqs_object.description = "IPQS Fraud and Risk Scoring Data" - setattr(self.ipqs_object, 'meta-category', 'network') - description = ( - "An object containing the enriched attribute and " - "related entities from IPQualityScore." - ) - self.ipqs_object.from_dict( - **{"meta-category": "misc", "description": description, "distribution": DEFAULT_DISTRIBUTION_SETTING} - ) - - temp_attr = MISPAttribute() - temp_attr.from_dict(**attribute) - self.enriched_attribute = MISPAttribute() - self.enriched_attribute.from_dict( - **{"value": temp_attr.value, "type": temp_attr.type, "distribution": DEFAULT_DISTRIBUTION_SETTING} - ) - self.ipqs_object.distribution = DEFAULT_DISTRIBUTION_SETTING - self.ip_data_items = [ - 'fraud_score', - 'country_code', - 'region', - 'city', - 'zip_code', - 'ISP', - 'ASN', - 'organization', - 'is_crawler', - 'timezone', - 'mobile', - 'host', - 'proxy', - 'vpn', - 'tor', - 'active_vpn', - 'active_tor', - 'recent_abuse', - 'bot_status', - 'connection_type', - 'abuse_velocity', - 'latitude', - 'longitude' - ] - self.ip_data_items_friendly_names = { - 'fraud_score': 'IPQS: Fraud Score', - 'country_code': 'IPQS: Country Code', - 'region': 'IPQS: Region', - 'city': 'IPQS: City', - 'zip_code': 'IPQS: Zip Code', - 'ISP': 'IPQS: ISP', - 'ASN': 'IPQS: ASN', - 'organization': 'IPQS: Organization', - 'is_crawler': 'IPQS: Is Crawler', - 'timezone': 'IPQS: Timezone', - 'mobile': 'IPQS: Mobile', - 'host': 'IPQS: Host', - 'proxy': 'IPQS: Proxy', - 'vpn': 'IPQS: VPN', - 'tor': 'IPQS: TOR', - 'active_vpn': 'IPQS: Active VPN', - 'active_tor': 'IPQS: Active TOR', - 'recent_abuse': 'IPQS: Recent Abuse', - 'bot_status': 'IPQS: Bot Status', - 'connection_type': 'IPQS: Connection Type', - 'abuse_velocity': 'IPQS: Abuse Velocity', - 'latitude': 'IPQS: Latitude', - 'longitude': 'IPQS: Longitude' - } - self.url_data_items = [ - 'unsafe', - 'domain', - 'ip_address', - 'server', - 'domain_rank', - 'dns_valid', - 'parking', - 'spamming', - 'malware', - 'phishing', - 'suspicious', - 'adult', - 'risk_score', - 'category', - 'domain_age' - ] - self.url_data_items_friendly_names = { - 'unsafe': 'IPQS: Unsafe', - 'domain': 'IPQS: Domain', - 'ip_address': 'IPQS: IP Address', - 'server': 'IPQS: Server', - 'domain_rank': 'IPQS: Domain Rank', - 'dns_valid': 'IPQS: DNS Valid', - 'parking': 'IPQS: Parking', - 'spamming': 'IPQS: Spamming', - 'malware': 'IPQS: Malware', - 'phishing': 'IPQS: Phishing', - 'suspicious': 'IPQS: Suspicious', - 'adult': 'IPQS: Adult', - 'risk_score': 'IPQS: Risk Score', - 'category': 'IPQS: Category', - 'domain_age': 'IPQS: Domain Age' - } - self.email_data_items = [ - 'valid', - 'disposable', - 'smtp_score', - 'overall_score', - 'first_name', - 'generic', - 'common', - 'dns_valid', - 'honeypot', - 'deliverability', - 'frequent_complainer', - 'spam_trap_score', - 'catch_all', - 'timed_out', - 'suspect', - 'recent_abuse', - 'fraud_score', - 'suggested_domain', - 'leaked', - 'sanitized_email', - 'domain_age', - 'first_seen' - ] - self.email_data_items_friendly_names = { - 'valid': 'IPQS: Valid', - 'disposable': 'IPQS: Disposable', - 'smtp_score': 'IPQS: SMTP Score', - 'overall_score': 'IPQS: Overall Score', - 'first_name': 'IPQS: First Name', - 'generic': 'IPQS: Generic', - 'common': 'IPQS: Common', - 'dns_valid': 'IPQS: DNS Valid', - 'honeypot': 'IPQS: Honeypot', - 'deliverability': 'IPQS: Deliverability', - 'frequent_complainer': 'IPQS: Frequent Complainer', - 'spam_trap_score': 'IPQS: Spam Trap Score', - 'catch_all': 'IPQS: Catch All', - 'timed_out': 'IPQS: Timed Out', - 'suspect': 'IPQS: Suspect', - 'recent_abuse': 'IPQS: Recent Abuse', - 'fraud_score': 'IPQS: Fraud Score', - 'suggested_domain': 'IPQS: Suggested Domain', - 'leaked': 'IPQS: Leaked', - 'sanitized_email': 'IPQS: Sanitized Email', - 'domain_age': 'IPQS: Domain Age', - 'first_seen': 'IPQS: First Seen' - } - self.phone_data_items = [ - 'formatted', - 'local_format', - 'valid', - 'fraud_score', - 'recent_abuse', - 'VOIP', - 'prepaid', - 'risky', - 'active', - 'carrier', - 'line_type', - 'country', - 'city', - 'zip_code', - 'region', - 'dialing_code', - 'active_status', - 'leaked', - 'name', - 'timezone', - 'do_not_call', - ] - self.phone_data_items_friendly_names = { - 'formatted': 'IPQS: Formatted', - 'local_format': 'IPQS: Local Format', - 'valid': 'IPQS: Valid', - 'fraud_score': 'IPQS: Fraud Score', - 'recent_abuse': 'IPQS: Recent Abuse', - 'VOIP': 'IPQS: VOIP', - 'prepaid': 'IPQS: Prepaid', - 'risky': 'IPQS: Risky', - 'active': 'IPQS: Active', - 'carrier': 'IPQS: Carrier', - 'line_type': 'IPQS: Line Type', - 'country': 'IPQS: Country', - 'city': 'IPQS: City', - 'zip_code': 'IPQS: Zip Code', - 'region': 'IPQS: Region', - 'dialing_code': 'IPQS: Dialing Code', - 'active_status': 'IPQS: Active Status', - 'leaked': 'IPQS: Leaked', - 'name': 'IPQS: Name', - 'timezone': 'IPQS: Timezone', - 'do_not_call': 'IPQS: Do Not Call', - } - self.timestamp_items_friendly_name = { - 'human': ' Human', - 'timestamp': ' Timestamp', - 'iso': ' ISO' - } - self.timestamp_items = [ - 'human', - 'timestamp', - 'iso' - ] - - def criticality_color(self, criticality) -> str: - """method which maps the color to the criticality level""" - mapper = { - self.clean: self.rf_grey, - self.low: self.rf_grey, - self.medium: self.rf_yellow, - self.suspicious: self.rf_yellow, - self.high: self.rf_red, - self.critical: self.rf_red, - self.invalid: self.rf_red, - self.disposable: self.rf_red, - self.malware: self.rf_red, - self.phishing: self.rf_red - } - return mapper.get(criticality, self.rf_white) - - def add_tag(self, tag_name: str, hex_color: str = None) -> None: - """Helper method for adding a tag to the enriched attribute.""" - tag = MISPTag() - tag_properties = {"name": tag_name} - if hex_color: - tag_properties["colour"] = hex_color - tag.from_dict(**tag_properties) - self.enriched_attribute.add_tag(tag) - - def ipqs_parser(self, query_response, enrich_type): - """ helper method to call the enrichment function according to the type""" - if enrich_type == IP_ENRICH: - self.ip_reputation_data(query_response) - elif enrich_type == URL_ENRICH: - self.url_reputation_data(query_response) - elif enrich_type == EMAIL_ENRICH: - self.email_reputation_data(query_response) - elif enrich_type == PHONE_ENRICH: - self.phone_reputation_data(query_response) - - def ip_reputation_data(self, query_response): - """method to create object for IP address""" - comment = "Results from IPQualityScore IP Reputation API" - for ip_data_item in self.ip_data_items: - if ip_data_item in query_response: - data_item = self.ip_data_items_friendly_names[ip_data_item] - data_item_value = str(query_response[ip_data_item]) - self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) - if ip_data_item == "fraud_score": - fraud_score = int(data_item_value) - self.ip_address_risk_scoring(fraud_score) - - self.ipqs_object.add_attribute( - "Enriched attribute", **self.enriched_attribute - ) - self.ipqs_object.add_reference(self.attribute['uuid'], 'related-to') - self.misp_event.add_object(self.ipqs_object) - - def ip_address_risk_scoring(self, score): - """method to create calculate verdict for IP Address""" - risk_criticality = "" - if score == 100: - risk_criticality = self.critical - elif 85 <= score <= 99: - risk_criticality = self.high - elif 75 <= score <= 84: - risk_criticality = self.medium - elif 60 <= score <= 74: - risk_criticality = self.suspicious - elif score <= 59: - risk_criticality = self.clean - - hex_color = self.criticality_color(risk_criticality) - tag_name = f'IPQS:VERDICT="{risk_criticality}"' - self.add_tag(tag_name, hex_color) - - def url_reputation_data(self, query_response): - """method to create object for URL/Domain""" - malware = False - phishing = False - risk_score = 0 - comment = "Results from IPQualityScore Malicious URL Scanner API" - for url_data_item in self.url_data_items: - if url_data_item in query_response: - data_item_value = "" - if url_data_item == "domain_age": - for timestamp_item in self.timestamp_items: - data_item = self.url_data_items_friendly_names[url_data_item] + \ - self.timestamp_items_friendly_name[timestamp_item] - data_item_value = str(query_response[url_data_item][timestamp_item]) - self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) - else: - data_item = self.url_data_items_friendly_names[url_data_item] - data_item_value = str(query_response[url_data_item]) - self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) - - if url_data_item == "malware": - malware = data_item_value - if url_data_item == "phishing": - phishing = data_item_value - if url_data_item == "risk_score": - risk_score = int(data_item_value) - - self.url_risk_scoring(risk_score, malware, phishing) - self.ipqs_object.add_attribute( - "Enriched attribute", **self.enriched_attribute - ) - self.ipqs_object.add_reference(self.attribute['uuid'], 'related-to') - self.misp_event.add_object(self.ipqs_object) - - def url_risk_scoring(self, score, malware, phishing): - """method to create calculate verdict for URL/Domain""" - risk_criticality = "" - if malware == 'True': - risk_criticality = self.malware - elif phishing == 'True': - risk_criticality = self.phishing - elif score >= 90: - risk_criticality = self.high - elif 80 <= score <= 89: - risk_criticality = self.medium - elif 70 <= score <= 79: - risk_criticality = self.low - elif 55 <= score <= 69: - risk_criticality = self.suspicious - elif score <= 54: - risk_criticality = self.clean - - hex_color = self.criticality_color(risk_criticality) - tag_name = f'IPQS:VERDICT="{risk_criticality}"' - self.add_tag(tag_name, hex_color) - - def email_reputation_data(self, query_response): - """method to create object for Email Address""" - comment = "Results from IPQualityScore Email Verification API" - disposable = False - valid = False - fraud_score = 0 - for email_data_item in self.email_data_items: - if email_data_item in query_response: - data_item_value = "" - if email_data_item not in ("domain_age", "first_seen"): - data_item = self.email_data_items_friendly_names[email_data_item] - data_item_value = str(query_response[email_data_item]) - self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) - else: - for timestamp_item in self.timestamp_items: - data_item = self.email_data_items_friendly_names[email_data_item] + \ - self.timestamp_items_friendly_name[timestamp_item] - data_item_value = str(query_response[email_data_item][timestamp_item]) - self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) - - if email_data_item == "disposable": - disposable = data_item_value - if email_data_item == "valid": - valid = data_item_value - if email_data_item == "fraud_score": - fraud_score = int(data_item_value) - - self.email_address_risk_scoring(fraud_score, disposable, valid) - self.ipqs_object.add_attribute( - "Enriched attribute", **self.enriched_attribute - ) - self.ipqs_object.add_reference(self.attribute['uuid'], 'related-to') - self.misp_event.add_object(self.ipqs_object) - - def email_address_risk_scoring(self, score, disposable, valid): - """method to create calculate verdict for Email Address""" - risk_criticality = "" - if disposable == "True": - risk_criticality = self.disposable - elif valid == "False": - risk_criticality = self.invalid - elif score == 100: - risk_criticality = self.high - elif 88 <= score <= 99: - risk_criticality = self.medium - elif 80 <= score <= 87: - risk_criticality = self.low - elif score <= 79: - risk_criticality = self.clean - hex_color = self.criticality_color(risk_criticality) - tag_name = f'IPQS:VERDICT="{risk_criticality}"' - - self.add_tag(tag_name, hex_color) - - def phone_reputation_data(self, query_response): - """method to create object for Phone Number""" - fraud_score = 0 - valid = False - active = False - comment = "Results from IPQualityScore Phone Number Validation API" - for phone_data_item in self.phone_data_items: - if phone_data_item in query_response: - data_item = self.phone_data_items_friendly_names[phone_data_item] - data_item_value = str(query_response[phone_data_item]) - self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) - if phone_data_item == "active": - active = data_item_value - if phone_data_item == "valid": - valid = data_item_value - if phone_data_item == "fraud_score": - fraud_score = int(data_item_value) - - - self.phone_address_risk_scoring(fraud_score, valid, active) - self.ipqs_object.add_attribute( - "Enriched attribute", **self.enriched_attribute - ) - self.ipqs_object.add_reference(self.attribute['uuid'], 'related-to') - self.misp_event.add_object(self.ipqs_object) - - def phone_address_risk_scoring(self, score, valid, active): - """method to create calculate verdict for Phone Number""" - risk_criticality = "" - if valid == "False": - risk_criticality = self.medium - elif active == "False": - risk_criticality = self.medium - elif 90 <= score <= 100: - risk_criticality = self.high - elif 80 <= score <= 89: - risk_criticality = self.low - elif 50 <= score <= 79: - risk_criticality = self.suspicious - elif score <= 49: - risk_criticality = self.clean - hex_color = self.criticality_color(risk_criticality) - tag_name = f'IPQS:VERDICT="{risk_criticality}"' - self.add_tag(tag_name, hex_color) - - def get_results(self): - """returns the dictionary object to MISP Instance""" - event = json.loads(self.misp_event.to_json()) - results = {key: event[key] for key in ('Attribute', 'Object')} - return {'results': results} - - -def handler(q=False): - """The function which accepts a JSON document to expand the values and return a dictionary of the expanded - values. """ - if q is False: - return False - request = json.loads(q) - # check if the apikey is provided - if not request.get('config') or not request['config'].get('apikey'): - misperrors['error'] = 'IPQualityScore apikey is missing' - return misperrors - apikey = request['config'].get('apikey') - # check attribute is added to the event - if not request.get('attribute') or not check_input_attribute(request['attribute']): - return {'error': f'{standard_error_message}, which should contain at least a type, a value and an uuid.'} - - attribute = request['attribute'] - attribute_type = attribute['type'] - attribute_value = attribute['value'] - - # check if the attribute type is supported by IPQualityScore - if attribute_type not in mispattributes['input']: - return {'error': 'Unsupported attributes type for IPqualityScore Enrichment'} - request_handler = RequestHandler(apikey) - enrich_type = "" - if attribute_type in ip_query_input_type: - enrich_type = IP_ENRICH - json_response = request_handler.ipqs_lookup(IP_ENRICH, attribute_value) - elif attribute_type in url_query_input_type: - enrich_type = URL_ENRICH - json_response = request_handler.ipqs_lookup(URL_ENRICH, attribute_value) - elif attribute_type in email_query_input_type: - enrich_type = EMAIL_ENRICH - json_response = request_handler.ipqs_lookup(EMAIL_ENRICH, attribute_value) - elif attribute_type in phone_query_input_type: - enrich_type = PHONE_ENRICH - json_response = request_handler.ipqs_lookup(PHONE_ENRICH, attribute_value) - - parser = IPQualityScoreParser(attribute) - parser.ipqs_parser(json_response, enrich_type) - return parser.get_results() - - -def introspection(): - """The function that returns a dict of the supported attributes (input and output) by your expansion module.""" - return mispattributes - - -def version(): - """The function that returns a dict with the version and the associated meta-data including potential - configurations required of the module. """ - moduleinfo['config'] = moduleconfig - return moduleinfo +import json +import logging +import requests +from requests.exceptions import ( + HTTPError, + ProxyError, + InvalidURL, + ConnectTimeout +) +from . import check_input_attribute, standard_error_message +from pymisp import MISPEvent, MISPAttribute, MISPObject, MISPTag, Distribution + +ip_query_input_type = [ + 'ip-src', + 'ip-dst' +] +url_query_input_type = [ + 'hostname', + 'domain', + 'url', + 'uri' +] +email_query_input_type = [ + 'email', + 'email-src', + 'email-dst', + 'target-email', + 'whois-registrant-email' +] +phone_query_input_type = [ + 'phone-number', + 'whois-registrant-phone' +] + +misperrors = { + 'error': 'Error' +} +mispattributes = { + 'input': ip_query_input_type + url_query_input_type + email_query_input_type + phone_query_input_type, + 'format': 'misp_standard' +} +moduleinfo = { + 'version': '0.1', + 'author': 'David Mackler', + 'description': 'IPQualityScore MISP Expansion Module for IP reputation, Email Validation, Phone Number Validation, Malicious Domain and Malicious URL Scanner.', + 'module-type': ['expansion', 'hover'], + 'name': 'IPQualityScore Lookup', + 'logo': 'ipqualityscore.png', + 'requirements': ['A IPQualityScore API Key.'], + 'features': 'This Module takes the IP Address, Domain, URL, Email and Phone Number MISP Attributes as input to query the IPQualityScore API.\n The results of the IPQualityScore API are than returned as IPQS Fraud and Risk Scoring Object. \n The object contains a copy of the enriched attribute with added tags presenting the verdict based on fraud score,risk score and other attributes from IPQualityScore.', + 'references': ['https://www.ipqualityscore.com/'], + 'input': 'A MISP attribute of type IP Address(ip-src, ip-dst), Domain(hostname, domain), URL(url, uri), Email Address(email, email-src, email-dst, target-email, whois-registrant-email) and Phone Number(phone-number, whois-registrant-phone).', + 'output': 'IPQualityScore object, resulting from the query on the IPQualityScore API.', +} +moduleconfig = ['apikey'] + +logger = logging.getLogger('ipqualityscore') +logger.setLevel(logging.DEBUG) +BASE_URL = 'https://ipqualityscore.com/api/json' +DEFAULT_DISTRIBUTION_SETTING = Distribution.your_organisation_only.value +IP_ENRICH = 'ip' +URL_ENRICH = 'url' +EMAIL_ENRICH = 'email' +PHONE_ENRICH = 'phone' + + +class RequestHandler: + """A class for handling any outbound requests from this module.""" + + def __init__(self, apikey): + self.session = requests.Session() + self.api_key = apikey + + def get(self, url: str, headers: dict = None, params: dict = None) -> requests.Response: + """General get method to fetch the response from IPQualityScore.""" + try: + response = self.session.get( + url, headers=headers, params=params + ).json() + if str(response["success"]) != "True": + msg = response["message"] + logger.error(f"Error: {msg}") + misperrors["error"] = msg + else: + return response + except (ConnectTimeout, ProxyError, InvalidURL) as error: + msg = "Error connecting with the IPQualityScore." + logger.error(f"{msg} Error: {error}") + misperrors["error"] = msg + + def ipqs_lookup(self, reputation_type: str, ioc: str) -> requests.Response: + """Do a lookup call.""" + url = f"{BASE_URL}/{reputation_type}" + payload = {reputation_type: ioc} + headers = {"IPQS-KEY": self.api_key} + try: + response = self.get(url, headers, payload) + except HTTPError as error: + msg = f"Error when requesting data from IPQualityScore. {error.response}: {error.response.reason}" + logger.error(msg) + misperrors["error"] = msg + raise + return response + + +def parse_attribute(comment, feature, value): + """Generic Method for parsing the attributes in the object""" + attribute = { + 'type': 'text', + 'value': value, + 'comment': comment, + 'distribution': DEFAULT_DISTRIBUTION_SETTING, + 'object_relation': feature + } + return attribute + + +class IPQualityScoreParser: + """A class for handling the enrichment objects""" + + def __init__(self, attribute): + self.rf_white = "#CCCCCC" + self.rf_grey = " #CDCDCD" + self.rf_yellow = "#FFCF00" + self.rf_red = "#D10028" + self.clean = "CLEAN" + self.low = "LOW RISK" + self.medium = "MODERATE RISK" + self.high = "HIGH RISK" + self.critical = "CRITICAL" + self.invalid = "INVALID" + self.suspicious = "SUSPICIOUS" + self.malware = "CRITICAL" + self.phishing = "CRITICAL" + self.disposable = "CRITICAL" + self.attribute = attribute + self.misp_event = MISPEvent() + self.misp_event.add_attribute(**attribute) + self.ipqs_object = MISPObject('IPQS Fraud and Risk Scoring Object') + self.ipqs_object.template_uuid = "57d066e6-6d66-42a7-a1ad-e075e39b2b5e" + self.ipqs_object.template_id = "1" + self.ipqs_object.description = "IPQS Fraud and Risk Scoring Data" + setattr(self.ipqs_object, 'meta-category', 'network') + description = ( + "An object containing the enriched attribute and " + "related entities from IPQualityScore." + ) + self.ipqs_object.from_dict( + **{"meta-category": "misc", "description": description, "distribution": DEFAULT_DISTRIBUTION_SETTING} + ) + + temp_attr = MISPAttribute() + temp_attr.from_dict(**attribute) + self.enriched_attribute = MISPAttribute() + self.enriched_attribute.from_dict( + **{"value": temp_attr.value, "type": temp_attr.type, "distribution": DEFAULT_DISTRIBUTION_SETTING} + ) + self.ipqs_object.distribution = DEFAULT_DISTRIBUTION_SETTING + self.ip_data_items = [ + 'fraud_score', + 'country_code', + 'region', + 'city', + 'zip_code', + 'ISP', + 'ASN', + 'organization', + 'is_crawler', + 'timezone', + 'mobile', + 'host', + 'proxy', + 'vpn', + 'tor', + 'active_vpn', + 'active_tor', + 'recent_abuse', + 'bot_status', + 'connection_type', + 'abuse_velocity', + 'latitude', + 'longitude' + ] + self.ip_data_items_friendly_names = { + 'fraud_score': 'IPQS: Fraud Score', + 'country_code': 'IPQS: Country Code', + 'region': 'IPQS: Region', + 'city': 'IPQS: City', + 'zip_code': 'IPQS: Zip Code', + 'ISP': 'IPQS: ISP', + 'ASN': 'IPQS: ASN', + 'organization': 'IPQS: Organization', + 'is_crawler': 'IPQS: Is Crawler', + 'timezone': 'IPQS: Timezone', + 'mobile': 'IPQS: Mobile', + 'host': 'IPQS: Host', + 'proxy': 'IPQS: Proxy', + 'vpn': 'IPQS: VPN', + 'tor': 'IPQS: TOR', + 'active_vpn': 'IPQS: Active VPN', + 'active_tor': 'IPQS: Active TOR', + 'recent_abuse': 'IPQS: Recent Abuse', + 'bot_status': 'IPQS: Bot Status', + 'connection_type': 'IPQS: Connection Type', + 'abuse_velocity': 'IPQS: Abuse Velocity', + 'latitude': 'IPQS: Latitude', + 'longitude': 'IPQS: Longitude' + } + self.url_data_items = [ + 'unsafe', + 'domain', + 'ip_address', + 'server', + 'domain_rank', + 'dns_valid', + 'parking', + 'spamming', + 'malware', + 'phishing', + 'suspicious', + 'adult', + 'risk_score', + 'category', + 'domain_age' + ] + self.url_data_items_friendly_names = { + 'unsafe': 'IPQS: Unsafe', + 'domain': 'IPQS: Domain', + 'ip_address': 'IPQS: IP Address', + 'server': 'IPQS: Server', + 'domain_rank': 'IPQS: Domain Rank', + 'dns_valid': 'IPQS: DNS Valid', + 'parking': 'IPQS: Parking', + 'spamming': 'IPQS: Spamming', + 'malware': 'IPQS: Malware', + 'phishing': 'IPQS: Phishing', + 'suspicious': 'IPQS: Suspicious', + 'adult': 'IPQS: Adult', + 'risk_score': 'IPQS: Risk Score', + 'category': 'IPQS: Category', + 'domain_age': 'IPQS: Domain Age' + } + self.email_data_items = [ + 'valid', + 'disposable', + 'smtp_score', + 'overall_score', + 'first_name', + 'generic', + 'common', + 'dns_valid', + 'honeypot', + 'deliverability', + 'frequent_complainer', + 'spam_trap_score', + 'catch_all', + 'timed_out', + 'suspect', + 'recent_abuse', + 'fraud_score', + 'suggested_domain', + 'leaked', + 'sanitized_email', + 'domain_age', + 'first_seen' + ] + self.email_data_items_friendly_names = { + 'valid': 'IPQS: Valid', + 'disposable': 'IPQS: Disposable', + 'smtp_score': 'IPQS: SMTP Score', + 'overall_score': 'IPQS: Overall Score', + 'first_name': 'IPQS: First Name', + 'generic': 'IPQS: Generic', + 'common': 'IPQS: Common', + 'dns_valid': 'IPQS: DNS Valid', + 'honeypot': 'IPQS: Honeypot', + 'deliverability': 'IPQS: Deliverability', + 'frequent_complainer': 'IPQS: Frequent Complainer', + 'spam_trap_score': 'IPQS: Spam Trap Score', + 'catch_all': 'IPQS: Catch All', + 'timed_out': 'IPQS: Timed Out', + 'suspect': 'IPQS: Suspect', + 'recent_abuse': 'IPQS: Recent Abuse', + 'fraud_score': 'IPQS: Fraud Score', + 'suggested_domain': 'IPQS: Suggested Domain', + 'leaked': 'IPQS: Leaked', + 'sanitized_email': 'IPQS: Sanitized Email', + 'domain_age': 'IPQS: Domain Age', + 'first_seen': 'IPQS: First Seen' + } + self.phone_data_items = [ + 'formatted', + 'local_format', + 'valid', + 'fraud_score', + 'recent_abuse', + 'VOIP', + 'prepaid', + 'risky', + 'active', + 'carrier', + 'line_type', + 'country', + 'city', + 'zip_code', + 'region', + 'dialing_code', + 'active_status', + 'leaked', + 'name', + 'timezone', + 'do_not_call', + ] + self.phone_data_items_friendly_names = { + 'formatted': 'IPQS: Formatted', + 'local_format': 'IPQS: Local Format', + 'valid': 'IPQS: Valid', + 'fraud_score': 'IPQS: Fraud Score', + 'recent_abuse': 'IPQS: Recent Abuse', + 'VOIP': 'IPQS: VOIP', + 'prepaid': 'IPQS: Prepaid', + 'risky': 'IPQS: Risky', + 'active': 'IPQS: Active', + 'carrier': 'IPQS: Carrier', + 'line_type': 'IPQS: Line Type', + 'country': 'IPQS: Country', + 'city': 'IPQS: City', + 'zip_code': 'IPQS: Zip Code', + 'region': 'IPQS: Region', + 'dialing_code': 'IPQS: Dialing Code', + 'active_status': 'IPQS: Active Status', + 'leaked': 'IPQS: Leaked', + 'name': 'IPQS: Name', + 'timezone': 'IPQS: Timezone', + 'do_not_call': 'IPQS: Do Not Call', + } + self.timestamp_items_friendly_name = { + 'human': ' Human', + 'timestamp': ' Timestamp', + 'iso': ' ISO' + } + self.timestamp_items = [ + 'human', + 'timestamp', + 'iso' + ] + + def criticality_color(self, criticality) -> str: + """method which maps the color to the criticality level""" + mapper = { + self.clean: self.rf_grey, + self.low: self.rf_grey, + self.medium: self.rf_yellow, + self.suspicious: self.rf_yellow, + self.high: self.rf_red, + self.critical: self.rf_red, + self.invalid: self.rf_red, + self.disposable: self.rf_red, + self.malware: self.rf_red, + self.phishing: self.rf_red + } + return mapper.get(criticality, self.rf_white) + + def add_tag(self, tag_name: str, hex_color: str = None) -> None: + """Helper method for adding a tag to the enriched attribute.""" + tag = MISPTag() + tag_properties = {"name": tag_name} + if hex_color: + tag_properties["colour"] = hex_color + tag.from_dict(**tag_properties) + self.enriched_attribute.add_tag(tag) + + def ipqs_parser(self, query_response, enrich_type): + """ helper method to call the enrichment function according to the type""" + if enrich_type == IP_ENRICH: + self.ip_reputation_data(query_response) + elif enrich_type == URL_ENRICH: + self.url_reputation_data(query_response) + elif enrich_type == EMAIL_ENRICH: + self.email_reputation_data(query_response) + elif enrich_type == PHONE_ENRICH: + self.phone_reputation_data(query_response) + + def ip_reputation_data(self, query_response): + """method to create object for IP address""" + comment = "Results from IPQualityScore IP Reputation API" + for ip_data_item in self.ip_data_items: + if ip_data_item in query_response: + data_item = self.ip_data_items_friendly_names[ip_data_item] + data_item_value = str(query_response[ip_data_item]) + self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) + if ip_data_item == "fraud_score": + fraud_score = int(data_item_value) + self.ip_address_risk_scoring(fraud_score) + + self.ipqs_object.add_attribute( + "Enriched attribute", **self.enriched_attribute + ) + self.ipqs_object.add_reference(self.attribute['uuid'], 'related-to') + self.misp_event.add_object(self.ipqs_object) + + def ip_address_risk_scoring(self, score): + """method to create calculate verdict for IP Address""" + risk_criticality = "" + if score == 100: + risk_criticality = self.critical + elif 85 <= score <= 99: + risk_criticality = self.high + elif 75 <= score <= 84: + risk_criticality = self.medium + elif 60 <= score <= 74: + risk_criticality = self.suspicious + elif score <= 59: + risk_criticality = self.clean + + hex_color = self.criticality_color(risk_criticality) + tag_name = f'IPQS:VERDICT="{risk_criticality}"' + self.add_tag(tag_name, hex_color) + + def url_reputation_data(self, query_response): + """method to create object for URL/Domain""" + malware = False + phishing = False + risk_score = 0 + comment = "Results from IPQualityScore Malicious URL Scanner API" + for url_data_item in self.url_data_items: + if url_data_item in query_response: + data_item_value = "" + if url_data_item == "domain_age": + for timestamp_item in self.timestamp_items: + data_item = self.url_data_items_friendly_names[url_data_item] + \ + self.timestamp_items_friendly_name[timestamp_item] + data_item_value = str(query_response[url_data_item][timestamp_item]) + self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) + else: + data_item = self.url_data_items_friendly_names[url_data_item] + data_item_value = str(query_response[url_data_item]) + self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) + + if url_data_item == "malware": + malware = data_item_value + if url_data_item == "phishing": + phishing = data_item_value + if url_data_item == "risk_score": + risk_score = int(data_item_value) + + self.url_risk_scoring(risk_score, malware, phishing) + self.ipqs_object.add_attribute( + "Enriched attribute", **self.enriched_attribute + ) + self.ipqs_object.add_reference(self.attribute['uuid'], 'related-to') + self.misp_event.add_object(self.ipqs_object) + + def url_risk_scoring(self, score, malware, phishing): + """method to create calculate verdict for URL/Domain""" + risk_criticality = "" + if malware == 'True': + risk_criticality = self.malware + elif phishing == 'True': + risk_criticality = self.phishing + elif score >= 90: + risk_criticality = self.high + elif 80 <= score <= 89: + risk_criticality = self.medium + elif 70 <= score <= 79: + risk_criticality = self.low + elif 55 <= score <= 69: + risk_criticality = self.suspicious + elif score <= 54: + risk_criticality = self.clean + + hex_color = self.criticality_color(risk_criticality) + tag_name = f'IPQS:VERDICT="{risk_criticality}"' + self.add_tag(tag_name, hex_color) + + def email_reputation_data(self, query_response): + """method to create object for Email Address""" + comment = "Results from IPQualityScore Email Verification API" + disposable = False + valid = False + fraud_score = 0 + for email_data_item in self.email_data_items: + if email_data_item in query_response: + data_item_value = "" + if email_data_item not in ("domain_age", "first_seen"): + data_item = self.email_data_items_friendly_names[email_data_item] + data_item_value = str(query_response[email_data_item]) + self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) + else: + for timestamp_item in self.timestamp_items: + data_item = self.email_data_items_friendly_names[email_data_item] + \ + self.timestamp_items_friendly_name[timestamp_item] + data_item_value = str(query_response[email_data_item][timestamp_item]) + self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) + + if email_data_item == "disposable": + disposable = data_item_value + if email_data_item == "valid": + valid = data_item_value + if email_data_item == "fraud_score": + fraud_score = int(data_item_value) + + self.email_address_risk_scoring(fraud_score, disposable, valid) + self.ipqs_object.add_attribute( + "Enriched attribute", **self.enriched_attribute + ) + self.ipqs_object.add_reference(self.attribute['uuid'], 'related-to') + self.misp_event.add_object(self.ipqs_object) + + def email_address_risk_scoring(self, score, disposable, valid): + """method to create calculate verdict for Email Address""" + risk_criticality = "" + if disposable == "True": + risk_criticality = self.disposable + elif valid == "False": + risk_criticality = self.invalid + elif score == 100: + risk_criticality = self.high + elif 88 <= score <= 99: + risk_criticality = self.medium + elif 80 <= score <= 87: + risk_criticality = self.low + elif score <= 79: + risk_criticality = self.clean + hex_color = self.criticality_color(risk_criticality) + tag_name = f'IPQS:VERDICT="{risk_criticality}"' + + self.add_tag(tag_name, hex_color) + + def phone_reputation_data(self, query_response): + """method to create object for Phone Number""" + fraud_score = 0 + valid = False + active = False + comment = "Results from IPQualityScore Phone Number Validation API" + for phone_data_item in self.phone_data_items: + if phone_data_item in query_response: + data_item = self.phone_data_items_friendly_names[phone_data_item] + data_item_value = str(query_response[phone_data_item]) + self.ipqs_object.add_attribute(**parse_attribute(comment, data_item, data_item_value)) + if phone_data_item == "active": + active = data_item_value + if phone_data_item == "valid": + valid = data_item_value + if phone_data_item == "fraud_score": + fraud_score = int(data_item_value) + + + self.phone_address_risk_scoring(fraud_score, valid, active) + self.ipqs_object.add_attribute( + "Enriched attribute", **self.enriched_attribute + ) + self.ipqs_object.add_reference(self.attribute['uuid'], 'related-to') + self.misp_event.add_object(self.ipqs_object) + + def phone_address_risk_scoring(self, score, valid, active): + """method to create calculate verdict for Phone Number""" + risk_criticality = "" + if valid == "False": + risk_criticality = self.medium + elif active == "False": + risk_criticality = self.medium + elif 90 <= score <= 100: + risk_criticality = self.high + elif 80 <= score <= 89: + risk_criticality = self.low + elif 50 <= score <= 79: + risk_criticality = self.suspicious + elif score <= 49: + risk_criticality = self.clean + hex_color = self.criticality_color(risk_criticality) + tag_name = f'IPQS:VERDICT="{risk_criticality}"' + self.add_tag(tag_name, hex_color) + + def get_results(self): + """returns the dictionary object to MISP Instance""" + event = json.loads(self.misp_event.to_json()) + results = {key: event[key] for key in ('Attribute', 'Object')} + return {'results': results} + + +def handler(q=False): + """The function which accepts a JSON document to expand the values and return a dictionary of the expanded + values. """ + if q is False: + return False + request = json.loads(q) + # check if the apikey is provided + if not request.get('config') or not request['config'].get('apikey'): + misperrors['error'] = 'IPQualityScore apikey is missing' + return misperrors + apikey = request['config'].get('apikey') + # check attribute is added to the event + if not request.get('attribute') or not check_input_attribute(request['attribute']): + return {'error': f'{standard_error_message}, which should contain at least a type, a value and an uuid.'} + + attribute = request['attribute'] + attribute_type = attribute['type'] + attribute_value = attribute['value'] + + # check if the attribute type is supported by IPQualityScore + if attribute_type not in mispattributes['input']: + return {'error': 'Unsupported attributes type for IPqualityScore Enrichment'} + request_handler = RequestHandler(apikey) + enrich_type = "" + if attribute_type in ip_query_input_type: + enrich_type = IP_ENRICH + json_response = request_handler.ipqs_lookup(IP_ENRICH, attribute_value) + elif attribute_type in url_query_input_type: + enrich_type = URL_ENRICH + json_response = request_handler.ipqs_lookup(URL_ENRICH, attribute_value) + elif attribute_type in email_query_input_type: + enrich_type = EMAIL_ENRICH + json_response = request_handler.ipqs_lookup(EMAIL_ENRICH, attribute_value) + elif attribute_type in phone_query_input_type: + enrich_type = PHONE_ENRICH + json_response = request_handler.ipqs_lookup(PHONE_ENRICH, attribute_value) + + parser = IPQualityScoreParser(attribute) + parser.ipqs_parser(json_response, enrich_type) + return parser.get_results() + + +def introspection(): + """The function that returns a dict of the supported attributes (input and output) by your expansion module.""" + return mispattributes + + +def version(): + """The function that returns a dict with the version and the associated meta-data including potential + configurations required of the module. """ + moduleinfo['config'] = moduleconfig + return moduleinfo diff --git a/misp_modules/modules/expansion/iprep.py b/misp_modules/modules/expansion/iprep.py index 558dbdd7..8a5e959c 100755 --- a/misp_modules/modules/expansion/iprep.py +++ b/misp_modules/modules/expansion/iprep.py @@ -6,9 +6,19 @@ import requests misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-dst'], 'output': ['text']} -moduleinfo = {'version': '1.0', 'author': 'Keith Faber', - 'description': 'Query IPRep Data for IP Address', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '1.0', + 'author': 'Keith Faber', + 'description': 'Module to query IPRep data for IP addresses.', + 'module-type': ['expansion'], + 'name': 'IPRep Lookup', + 'logo': '', + 'requirements': ['An access to the packetmail API (apikey)'], + 'features': 'This module takes an IP address attribute as input and queries the database from packetmail.net to get some information about the reputation of the IP.', + 'references': ['https://github.com/mahesh557/packetmail'], + 'input': 'An IP address MISP attribute.', + 'output': 'Text describing additional information about the input after a query on the IPRep API.', +} moduleconfig = ['apikey'] diff --git a/misp_modules/modules/expansion/jinja_template_rendering.py b/misp_modules/modules/expansion/jinja_template_rendering.py index 5749abaf..d65cb65b 100755 --- a/misp_modules/modules/expansion/jinja_template_rendering.py +++ b/misp_modules/modules/expansion/jinja_template_rendering.py @@ -5,9 +5,19 @@ from jinja2.sandbox import SandboxedEnvironment misperrors = {'error': 'Error'} mispattributes = {'input': ['text'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Sami Mokaddem', - 'description': 'Render the template with the data passed', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sami Mokaddem', + 'description': 'Render the template with the data passed', + 'module-type': ['expansion'], + 'name': 'Ninja Template Rendering', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} default_template = '- Default template -' diff --git a/misp_modules/modules/expansion/joesandbox_query.py b/misp_modules/modules/expansion/joesandbox_query.py index e3035124..f9c27a51 100644 --- a/misp_modules/modules/expansion/joesandbox_query.py +++ b/misp_modules/modules/expansion/joesandbox_query.py @@ -8,9 +8,19 @@ misperrors = {'error': 'Error'} inputSource = ['link'] -moduleinfo = {'version': '0.2', 'author': 'Christian Studer', - 'description': 'Query Joe Sandbox API with a report URL to get the parsed data.', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.2', + 'author': 'Christian Studer', + 'description': 'Query Joe Sandbox API with a submission url to get the json report and extract its data that is parsed and converted into MISP attributes and objects.', + 'module-type': ['expansion'], + 'name': 'Joe Sandbox Import', + 'logo': 'joesandbox.png', + 'requirements': ['jbxapi: Joe Sandbox API python3 library'], + 'features': "Module using the new format of modules able to return attributes and objects.\n\nThe module returns the same results as the import module [joe_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/joe_import.py) taking directly the json report as input.\n\nEven if the introspection will allow all kinds of links to call this module, obviously only the ones presenting a sample or url submission in the Joe Sandbox API will return results.\n\nTo make it work you will need to fill the 'apikey' configuration with your Joe Sandbox API key and provide a valid link as input.", + 'references': ['https://www.joesecurity.org', 'https://www.joesandbox.com/'], + 'input': 'Link of a Joe Sandbox sample or url submission.', + 'output': 'MISP attributes & objects parsed from the analysis report.', +} moduleconfig = ['apiurl', 'apikey', 'import_executable', 'import_mitre_attack'] diff --git a/misp_modules/modules/expansion/joesandbox_submit.py b/misp_modules/modules/expansion/joesandbox_submit.py index 39b140e2..b124bb7c 100644 --- a/misp_modules/modules/expansion/joesandbox_submit.py +++ b/misp_modules/modules/expansion/joesandbox_submit.py @@ -21,10 +21,17 @@ sh.setFormatter(fmt) log.addHandler(sh) moduleinfo = { - "version": "1.0", - "author": "Joe Security LLC", - "description": "Submit files and URLs to Joe Sandbox", - "module-type": ["expansion", "hover"] + 'version': '1.0', + 'author': 'Joe Security LLC', + 'description': 'A module to submit files or URLs to Joe Sandbox for an advanced analysis, and return the link of the submission.', + 'module-type': ['expansion', 'hover'], + 'name': 'Joe Sandbox Submit', + 'logo': 'joesandbox.png', + 'requirements': ['jbxapi: Joe Sandbox API python3 library'], + 'features': 'The module requires a Joe Sandbox API key to submit files or URL, and returns the link of the submitted analysis.\n\nIt is then possible, when the analysis is completed, to query the Joe Sandbox API to get the data related to the analysis, using the [joesandbox_query module](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) directly on this submission link.', + 'references': ['https://www.joesecurity.org', 'https://www.joesandbox.com/'], + 'input': 'Sample, url (or domain) to submit to Joe Sandbox for an advanced analysis.', + 'output': 'Link of the report generated in Joe Sandbox.', } moduleconfig = [ "apiurl", diff --git a/misp_modules/modules/expansion/lastline_query.py b/misp_modules/modules/expansion/lastline_query.py index 501a0bd8..46310800 100644 --- a/misp_modules/modules/expansion/lastline_query.py +++ b/misp_modules/modules/expansion/lastline_query.py @@ -22,10 +22,17 @@ mispattributes = { } moduleinfo = { - "version": "0.1", - "author": "Stefano Ortolani", - "description": "Get a Lastline report from an analysis link.", - "module-type": ["expansion"], + 'version': '0.1', + 'author': 'Stefano Ortolani', + 'description': 'Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module.\n\nQuery Lastline with an analysis link and parse the report into MISP attributes and objects.', + 'module-type': ['expansion'], + 'name': 'Lastline Lookup', + 'logo': 'lastline.png', + 'requirements': [], + 'features': 'The module requires a Lastline Portal `username` and `password`.\nThe module uses the new format and it is able to return MISP attributes and objects.\nThe module returns the same results as the [lastline_import](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/import_mod/lastline_import.py) import module.', + 'references': ['https://www.lastline.com'], + 'input': 'Link to a Lastline analysis.', + 'output': 'MISP attributes and objects parsed from the analysis report.', } moduleconfig = [ diff --git a/misp_modules/modules/expansion/lastline_submit.py b/misp_modules/modules/expansion/lastline_submit.py index fef165b4..52f15cfc 100644 --- a/misp_modules/modules/expansion/lastline_submit.py +++ b/misp_modules/modules/expansion/lastline_submit.py @@ -28,10 +28,17 @@ mispattributes = { } moduleinfo = { - "version": "0.1", - "author": "Stefano Ortolani", - "description": "Submit files and URLs to Lastline analyst", - "module-type": ["expansion", "hover"], + 'version': '0.1', + 'author': 'Stefano Ortolani', + 'description': 'Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module.\n\nModule to submit a file or URL to Lastline.', + 'module-type': ['expansion', 'hover'], + 'name': 'Lastline Submit', + 'logo': 'lastline.png', + 'requirements': [], + 'features': 'The module requires a Lastline Analysis `api_token` and `key`.\nWhen the analysis is completed, it is possible to import the generated report by feeding the analysis link to the [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) module.', + 'references': ['https://www.lastline.com'], + 'input': 'File or URL to submit to Lastline.', + 'output': 'Link to the report generated by Lastline.', } moduleconfig = [ diff --git a/misp_modules/modules/expansion/macaddress_io.py b/misp_modules/modules/expansion/macaddress_io.py index 72f950a7..72e928e0 100644 --- a/misp_modules/modules/expansion/macaddress_io.py +++ b/misp_modules/modules/expansion/macaddress_io.py @@ -14,7 +14,14 @@ moduleinfo = { 'version': '1.0', 'author': 'CodeLine OY - macaddress.io', 'description': 'MISP hover module for macaddress.io', - 'module-type': ['hover'] + 'module-type': ['hover'], + 'name': 'Macaddress.io Lookup', + 'logo': 'macaddress_io.png', + 'requirements': ['maclookup: macaddress.io python library', 'An access to the macaddress.io API (apikey)'], + 'features': 'This module takes a MAC address attribute as input and queries macaddress.io for additional information.\n\nThis information contains data about:\n- MAC address details\n- Vendor details\n- Block details', + 'references': ['https://macaddress.io/', 'https://github.com/CodeLineFi/maclookup-python'], + 'input': 'MAC address MISP attribute.', + 'output': 'Text containing information on the MAC address fetched from a query on macaddress.io.', } moduleconfig = ['api_key'] diff --git a/misp_modules/modules/expansion/macvendors.py b/misp_modules/modules/expansion/macvendors.py index bb98366f..3b21dd9e 100644 --- a/misp_modules/modules/expansion/macvendors.py +++ b/misp_modules/modules/expansion/macvendors.py @@ -3,7 +3,19 @@ import json misperrors = {'error': 'Error'} mispattributes = {'input': ['mac-address'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Aurélien Schwab', 'description': 'Module to access Macvendors API.', 'module-type': ['hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Aurélien Schwab', + 'description': 'Module to access Macvendors API.', + 'module-type': ['hover'], + 'name': 'Macvendors Lookup', + 'logo': 'macvendors.png', + 'requirements': [], + 'features': 'The module takes a MAC address as input and queries macvendors.com for some information about it. The API returns the name of the vendor related to the address.', + 'references': ['https://macvendors.com/', 'https://macvendors.com/api'], + 'input': 'A MAC address.', + 'output': 'Additional information about the MAC address.', +} moduleconfig = ['user-agent'] macvendors_api_url = 'https://api.macvendors.com/' diff --git a/misp_modules/modules/expansion/malshare_upload.py b/misp_modules/modules/expansion/malshare_upload.py new file mode 100644 index 00000000..b810e209 --- /dev/null +++ b/misp_modules/modules/expansion/malshare_upload.py @@ -0,0 +1,107 @@ +import json +import sys +import base64 +import io +import zipfile +import requests +import hashlib +import re + +misperrors = {'error': 'Error'} +mispattributes = {'input': ['attachment', 'malware-sample'], 'output': ['link']} +moduleinfo = { + 'version': '1', + 'author': 'Karen Yousefi', + 'description': 'Module to push malware samples to MalShare', + 'module-type': ['expansion'], + 'name': 'MalShare Upload', + 'requirements': ['requests library'], + 'logo': '', +} + +moduleconfig = ['malshare_apikey'] + + +def handler(q=False): + if q is False: + return False + request = json.loads(q) + + try: + data = request.get("data") + if 'malware-sample' in request: + sample_filename = request.get("malware-sample").split("|", 1)[0] + data = base64.b64decode(data) + fl = io.BytesIO(data) + zf = zipfile.ZipFile(fl) + sample_hashname = zf.namelist()[0] + data = zf.read(sample_hashname, b"infected") + zf.close() + elif 'attachment' in request: + sample_filename = request.get("attachment") + data = base64.b64decode(data) + else: + misperrors['error'] = "No malware sample or attachment supplied" + return misperrors + except Exception: + misperrors['error'] = "Unable to process submitted sample data" + return misperrors + + if request["config"].get("malshare_apikey") is None: + misperrors["error"] = "Missing MalShare API key" + return misperrors + + malshare_apikey = request["config"].get("malshare_apikey") + + try: + url = "https://malshare.com/api.php" + params = {'api_key': malshare_apikey, 'action': 'upload'} + files = {"upload": (sample_filename, data)} + response = requests.post(url, params=params, files=files) + response.raise_for_status() + + response_text = response.text.strip() + + # Calculate SHA256 of the file + sha256 = hashlib.sha256(data).hexdigest() + + if response_text.startswith("Success"): + # If upload was successful or file already exists + malshare_link = ( + f"https://malshare.com/sample.php?action=detail&hash={sha256}" + ) + elif "sample already exists" in response_text: + # If file already exists, extract SHA256 from response + match = re.search(r'([a-fA-F0-9]{64})', response_text) + if match: + sha256 = match.group(1) + malshare_link = ( + f"https://malshare.com/sample.php?action=detail&hash={sha256}" + ) + else: + # If there's any other error + raise Exception(f"Upload failed: {response_text}") + + except Exception as e: + misperrors['error'] = f"Unable to send sample to MalShare: {str(e)}" + return misperrors + + r = { + 'results': [ + { + 'types': 'link', + 'values': malshare_link, + 'comment': 'Link to MalShare analysis', + } + ] + } + return r + + +def introspection(): + return mispattributes + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo diff --git a/misp_modules/modules/expansion/malwarebazaar.py b/misp_modules/modules/expansion/malwarebazaar.py index 60739e89..5ad90477 100644 --- a/misp_modules/modules/expansion/malwarebazaar.py +++ b/misp_modules/modules/expansion/malwarebazaar.py @@ -5,9 +5,19 @@ from pymisp import MISPEvent, MISPObject mispattributes = {'input': ['md5', 'sha1', 'sha256'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.1', 'author': 'Christian Studer', - 'description': 'Query Malware Bazaar to get additional information about the input hash.', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Christian Studer', + 'description': 'Query Malware Bazaar to get additional information about the input hash.', + 'module-type': ['expansion', 'hover'], + 'name': 'Malware Bazaar Lookup', + 'logo': '', + 'requirements': [], + 'features': "The module takes a hash attribute as input and queries MALWAREbazaar's API to fetch additional data about it. The result, if the payload is known on the databases, is at least one file object describing the file the input hash is related to.\n\nThe module is using the new format of modules able to return object since the result is one or multiple MISP object(s).", + 'references': ['https://bazaar.abuse.ch/'], + 'input': 'A hash attribute (md5, sha1 or sha256).', + 'output': 'File object(s) related to the input attribute found on MALWAREbazaar databases.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/mcafee_insights_enrich.py b/misp_modules/modules/expansion/mcafee_insights_enrich.py index 8026d7fc..dca67b8b 100644 --- a/misp_modules/modules/expansion/mcafee_insights_enrich.py +++ b/misp_modules/modules/expansion/mcafee_insights_enrich.py @@ -14,9 +14,19 @@ mispattributes = {'input': ["md5", "sha1", "sha256"], 'format': 'misp_standard'} # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '1', 'author': 'Martin Ohl', - 'description': 'Lookup McAfee MVISION Insights Details', - 'module-type': ['hover']} +moduleinfo = { + 'version': '1', + 'author': 'Martin Ohl', + 'description': 'Lookup McAfee MVISION Insights Details', + 'module-type': ['hover'], + 'name': 'McAfee MVISION Insights Lookup', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} # config fields that your code expects from the site admin moduleconfig = ['api_key', 'client_id', 'client_secret'] diff --git a/misp_modules/modules/expansion/mmdb_lookup.py b/misp_modules/modules/expansion/mmdb_lookup.py index e3a0eff4..21848563 100644 --- a/misp_modules/modules/expansion/mmdb_lookup.py +++ b/misp_modules/modules/expansion/mmdb_lookup.py @@ -5,10 +5,19 @@ from pymisp import MISPEvent, MISPObject misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-src|port', 'ip-dst', 'ip-dst|port'], 'format': 'misp_standard'} -moduleinfo = {'version': '1', 'author': 'Jeroen Pinoy', - 'description': "An expansion module to enrich an ip with geolocation and asn information from an mmdb server " - "such as ip.circl.lu.", - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '1', + 'author': 'Jeroen Pinoy', + 'description': "A hover and expansion module to enrich an ip with geolocation and ASN information from an mmdb server instance, such as CIRCL's ip.circl.lu.", + 'module-type': ['expansion', 'hover'], + 'name': 'GeoIP Enrichment', + 'logo': 'circl.png', + 'requirements': [], + 'features': 'The module takes an IP address related attribute as input.\n It queries the public CIRCL.lu mmdb-server instance, available at ip.circl.lu, by default. The module can be configured with a custom mmdb server url if required.\n It is also possible to filter results on 1 db_source by configuring db_source_filter.', + 'references': ['https://data.public.lu/fr/datasets/geo-open-ip-address-geolocation-per-country-in-mmdb-format/', 'https://github.com/adulau/mmdb-server'], + 'input': 'An IP address attribute (for example ip-src or ip-src|port).', + 'output': 'Geolocation and asn objects.', +} moduleconfig = ["custom_API", "db_source_filter"] mmdblookup_url = 'https://ip.circl.lu/' diff --git a/misp_modules/modules/expansion/mwdb.py b/misp_modules/modules/expansion/mwdb.py index 66f5fe45..a6fdc1e6 100644 --- a/misp_modules/modules/expansion/mwdb.py +++ b/misp_modules/modules/expansion/mwdb.py @@ -11,9 +11,19 @@ from mwdblib import MWDB misperrors = {'error': 'Error'} mispattributes = {'input': ['attachment', 'malware-sample'], 'output': ['link']} -moduleinfo = {'version': '1', 'author': 'Koen Van Impe', - 'description': 'Module to push malware samples to a MWDB instance', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '1', + 'author': 'Koen Van Impe', + 'description': 'Module to push malware samples to a MWDB instance', + 'module-type': ['expansion'], + 'name': 'MWDB Submit', + 'logo': '', + 'requirements': ['* mwdblib installed (pip install mwdblib) ; * (optional) keys.py file to add tags of events/attributes to MWDB * (optional) MWDB attribute created for the link back to MISP (defined in mwdb_misp_attribute)'], + 'features': 'An expansion module to push malware samples to a MWDB (https://github.com/CERT-Polska/mwdb-core) instance. This module does not push samples to a sandbox. This can be achieved via Karton (connected to the MWDB). Does: * Upload of attachment or malware sample to MWDB * Tags of events and/or attributes are added to MWDB. * Comment of the MISP attribute is added to MWDB. * A link back to the MISP event is added to MWDB via the MWDB attribute. * A link to the MWDB attribute is added as an enrichted attribute to the MISP event.', + 'references': [], + 'input': 'Attachment or malware sample', + 'output': 'Link attribute that points to the sample at the MWDB instane', +} moduleconfig = ['mwdb_apikey', 'mwdb_url', 'mwdb_misp_attribute', 'mwdb_public', 'include_tags_event', 'include_tags_attribute'] diff --git a/misp_modules/modules/expansion/ocr_enrich.py b/misp_modules/modules/expansion/ocr_enrich.py index ff0a70c7..0fbaea4c 100644 --- a/misp_modules/modules/expansion/ocr_enrich.py +++ b/misp_modules/modules/expansion/ocr_enrich.py @@ -7,9 +7,19 @@ import pytesseract misperrors = {'error': 'Error'} mispattributes = {'input': ['attachment'], 'output': ['freetext']} -moduleinfo = {'version': '0.2', 'author': 'Sascha Rommelfangen', - 'description': 'OCR decoder', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.2', + 'author': 'Sascha Rommelfangen', + 'description': 'Module to process some optical character recognition on pictures.', + 'module-type': ['expansion'], + 'name': 'OCR Enrich', + 'logo': '', + 'requirements': ['cv2: The OpenCV python library.'], + 'features': 'The module takes an attachment attributes as input and process some optical character recognition on it. The text found is then passed to the Freetext importer to extract potential IoCs.', + 'references': [], + 'input': 'A picture attachment.', + 'output': 'Text and freetext fetched from the input picture.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/ods_enrich.py b/misp_modules/modules/expansion/ods_enrich.py index 69aca771..6d25f321 100644 --- a/misp_modules/modules/expansion/ods_enrich.py +++ b/misp_modules/modules/expansion/ods_enrich.py @@ -9,9 +9,19 @@ import logging misperrors = {'error': 'Error'} mispattributes = {'input': ['attachment'], 'output': ['freetext', 'text']} -moduleinfo = {'version': '0.1', 'author': 'Sascha Rommelfangen', - 'description': '.ods to freetext-import IOC extractor', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sascha Rommelfangen', + 'description': 'Module to extract freetext from a .ods document.', + 'module-type': ['expansion'], + 'name': 'ODS Enrich', + 'logo': 'ods.png', + 'requirements': ['ezodf: Python package to create/manipulate OpenDocumentFormat files.', 'pandas_ods_reader: Python library to read in ODS files.'], + 'features': 'The module reads the text contained in a .ods document. The result is passed to the freetext import parser so IoCs can be extracted out of it.', + 'references': [], + 'input': 'Attachment attribute containing a .ods document.', + 'output': 'Text and freetext parsed from the document.', +} moduleconfig = [] @@ -36,7 +46,12 @@ def handler(q=False): num_sheets = len(doc.sheets) try: for i in range(0, num_sheets): - ods = pandas_ods_reader.algo.read_data(pandas_ods_reader.parsers.ods, ods_file, i, headers=False) + rows = pandas_ods_reader.parsers.ods.get_rows(doc, i) + try: + ods = pandas_ods_reader.algo.parse_data(pandas_ods_reader.parsers.ods, rows, headers=False, columns=[], skiprows=0) + ods = pandas_ods_reader.utils.sanitize_df(ods) + except TypeError: + ods = pandas_ods_reader.algo.read_data(pandas_ods_reader.parsers.ods, ods_file, i, headers=False) ods_content = ods_content + "\n" + ods.to_string(max_rows=None) return {'results': [{'types': ['freetext'], 'values': ods_content, 'comment': ".ods-to-text from file " + filename}, {'types': ['text'], 'values': ods_content, 'comment': ".ods-to-text from file " + filename}]} diff --git a/misp_modules/modules/expansion/odt_enrich.py b/misp_modules/modules/expansion/odt_enrich.py index c4513ae8..04d120f2 100644 --- a/misp_modules/modules/expansion/odt_enrich.py +++ b/misp_modules/modules/expansion/odt_enrich.py @@ -7,9 +7,19 @@ import io misperrors = {'error': 'Error'} mispattributes = {'input': ['attachment'], 'output': ['freetext', 'text']} -moduleinfo = {'version': '0.1', 'author': 'Sascha Rommelfangen', - 'description': '.odt to freetext-import IOC extractor', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sascha Rommelfangen', + 'description': 'Module to extract freetext from a .odt document.', + 'module-type': ['expansion'], + 'name': 'ODT Enrich', + 'logo': 'odt.png', + 'requirements': ['ODT reader python library.'], + 'features': 'The module reads the text contained in a .odt document. The result is passed to the freetext import parser so IoCs can be extracted out of it.', + 'references': [], + 'input': 'Attachment attribute containing a .odt document.', + 'output': 'Text and freetext parsed from the document.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/onyphe.py b/misp_modules/modules/expansion/onyphe.py index c7777077..29213b46 100644 --- a/misp_modules/modules/expansion/onyphe.py +++ b/misp_modules/modules/expansion/onyphe.py @@ -15,9 +15,19 @@ mispattributes = {'input': ['ip-src', 'ip-dst', 'hostname', 'domain'], 'output': ['hostname', 'domain', 'ip-src', 'ip-dst', 'url'], 'format': 'misp_standard'} # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '2', 'author': 'Sebastien Larinier @sebdraven', - 'description': 'Query on Onyphe', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '2', + 'author': 'Sebastien Larinier @sebdraven', + 'description': 'Module to process a query on Onyphe.', + 'module-type': ['expansion', 'hover'], + 'name': 'Onyphe Lookup', + 'logo': 'onyphe.jpg', + 'requirements': ['onyphe python library', 'An access to the Onyphe API (apikey)'], + 'features': 'This module takes a domain, hostname, or IP address attribute as input in order to query the Onyphe API. Data fetched from the query is then parsed and MISP attributes are extracted.', + 'references': ['https://www.onyphe.io/', 'https://github.com/sebdraven/pyonyphe'], + 'input': 'A domain, hostname or IP address MISP attribute.', + 'output': 'MISP attributes fetched from the Onyphe query.', +} # config fields that your code expects from the site admin moduleconfig = ['apikey'] diff --git a/misp_modules/modules/expansion/onyphe_full.py b/misp_modules/modules/expansion/onyphe_full.py index 3b1c554e..417d751d 100644 --- a/misp_modules/modules/expansion/onyphe_full.py +++ b/misp_modules/modules/expansion/onyphe_full.py @@ -12,9 +12,19 @@ mispattributes = {'input': ['ip-src', 'ip-dst', 'hostname', 'domain'], 'output': ['hostname', 'domain', 'ip-src', 'ip-dst', 'url']} # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '1', 'author': 'Sebastien Larinier @sebdraven', - 'description': 'Query on Onyphe', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '1', + 'author': 'Sebastien Larinier @sebdraven', + 'description': 'Module to process a full query on Onyphe.', + 'module-type': ['expansion', 'hover'], + 'name': 'Onyphe Full Lookup', + 'logo': 'onyphe.jpg', + 'requirements': ['onyphe python library', 'An access to the Onyphe API (apikey)'], + 'features': 'This module takes a domain, hostname, or IP address attribute as input in order to query the Onyphe API. Data fetched from the query is then parsed and MISP attributes are extracted.\n\nThe parsing is here more advanced than the one on onyphe module, and is returning more attributes, since more fields of the query result are watched and parsed.', + 'references': ['https://www.onyphe.io/', 'https://github.com/sebdraven/pyonyphe'], + 'input': 'A domain, hostname or IP address MISP attribute.', + 'output': 'MISP attributes fetched from the Onyphe query.', +} # config fields that your code expects from the site admin moduleconfig = ['apikey'] diff --git a/misp_modules/modules/expansion/otx.py b/misp_modules/modules/expansion/otx.py index e5861807..97c169fc 100755 --- a/misp_modules/modules/expansion/otx.py +++ b/misp_modules/modules/expansion/otx.py @@ -8,9 +8,19 @@ mispattributes = {'input': ["hostname", "domain", "ip-src", "ip-dst", "md5", "sh } # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '1', 'author': 'chrisdoman', - 'description': 'Get information from AlienVault OTX', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '1', + 'author': 'chrisdoman', + 'description': 'Module to get information from AlienVault OTX.', + 'module-type': ['expansion'], + 'name': 'AlienVault OTX Lookup', + 'logo': 'otx.png', + 'requirements': ['An access to the OTX API (apikey)'], + 'features': 'This module takes a MISP attribute as input to query the OTX Alienvault API. The API returns then the result of the query with some types we map into compatible types we add as MISP attributes.', + 'references': ['https://www.alienvault.com/open-threat-exchange'], + 'input': 'A MISP attribute included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- md5\n- sha1\n- sha256\n- sha512', + 'output': 'MISP attributes mapped from the result of the query on OTX, included in the following list:\n- domain\n- ip-src\n- ip-dst\n- text\n- md5\n- sha1\n- sha256\n- sha512\n- email', +} # We're not actually using the API key yet moduleconfig = ["apikey"] diff --git a/misp_modules/modules/expansion/passive-ssh.py b/misp_modules/modules/expansion/passive_ssh.py similarity index 92% rename from misp_modules/modules/expansion/passive-ssh.py rename to misp_modules/modules/expansion/passive_ssh.py index bf70ec99..2a3175ab 100644 --- a/misp_modules/modules/expansion/passive-ssh.py +++ b/misp_modules/modules/expansion/passive_ssh.py @@ -9,9 +9,19 @@ misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-dst', 'ssh-fingerprint'], 'format': 'misp_standard'} -moduleinfo = {'version': '1', 'author': 'Jean-Louis Huynen', - 'description': 'An expansion module to enrich, SSH key fingerprints and IP addresses with information collected by passive-ssh', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '1', + 'author': 'Jean-Louis Huynen', + 'description': 'An expansion module to enrich, SSH key fingerprints and IP addresses with information collected by passive-ssh', + 'module-type': ['expansion', 'hover'], + 'name': 'Passive SSH Enrichment', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} moduleconfig = ["custom_api_url", "api_user", "api_key"] diff --git a/misp_modules/modules/expansion/passivetotal.py b/misp_modules/modules/expansion/passivetotal.py index dfcedada..679d434c 100755 --- a/misp_modules/modules/expansion/passivetotal.py +++ b/misp_modules/modules/expansion/passivetotal.py @@ -31,7 +31,14 @@ moduleinfo = { 'version': '1.0', 'author': 'Brandon Dixon', 'description': 'The PassiveTotal MISP expansion module brings the datasets derived from Internet scanning directly into your MISP instance. This module supports passive DNS, historic SSL, WHOIS, and host attributes. In order to use the module, you must have a valid PassiveTotal account username and API key. Registration is free and can be done by visiting https://www.passivetotal.org/register', - 'module-type': ['expansion', 'hover'] + 'module-type': ['expansion', 'hover'], + 'name': 'PassiveTotal Lookup', + 'logo': 'passivetotal.png', + 'requirements': ['Passivetotal python library', 'An access to the PassiveTotal API (apikey)'], + 'features': 'The PassiveTotal MISP expansion module brings the datasets derived from Internet scanning directly into your MISP instance. This module supports passive DNS, historic SSL, WHOIS, and host attributes. In order to use the module, you must have a valid PassiveTotal account username and API key. Registration is free and can be done by visiting https://www.passivetotal.org/register', + 'references': ['https://www.passivetotal.org/register'], + 'input': 'A MISP attribute included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- x509-fingerprint-sha1\n- email-src\n- email-dst\n- target-email\n- whois-registrant-email\n- whois-registrant-phone\n- text\n- whois-registrant-name\n- whois-registrar\n- whois-creation-date', + 'output': 'MISP attributes mapped from the result of the query on PassiveTotal, included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- x509-fingerprint-sha1\n- email-src\n- email-dst\n- target-email\n- whois-registrant-email\n- whois-registrant-phone\n- text\n- whois-registrant-name\n- whois-registrar\n- whois-creation-date\n- md5\n- sha1\n- sha256\n- link', } moduleconfig = ['username', 'api_key'] query_playbook = [ diff --git a/misp_modules/modules/expansion/pdf_enrich.py b/misp_modules/modules/expansion/pdf_enrich.py index ef85fde2..15231c09 100644 --- a/misp_modules/modules/expansion/pdf_enrich.py +++ b/misp_modules/modules/expansion/pdf_enrich.py @@ -7,9 +7,19 @@ import io misperrors = {'error': 'Error'} mispattributes = {'input': ['attachment'], 'output': ['freetext', 'text']} -moduleinfo = {'version': '0.1', 'author': 'Sascha Rommelfangen', - 'description': 'PDF to freetext-import IOC extractor', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sascha Rommelfangen', + 'description': 'Module to extract freetext from a PDF document.', + 'module-type': ['expansion'], + 'name': 'PDF Enrich', + 'logo': 'pdf.jpg', + 'requirements': ['pdftotext: Python library to extract text from PDF.'], + 'features': 'The module reads the text contained in a PDF document. The result is passed to the freetext import parser so IoCs can be extracted out of it.', + 'references': [], + 'input': 'Attachment attribute containing a PDF document.', + 'output': 'Text and freetext parsed from the document.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/pptx_enrich.py b/misp_modules/modules/expansion/pptx_enrich.py index 816e4391..4a3b2b5f 100644 --- a/misp_modules/modules/expansion/pptx_enrich.py +++ b/misp_modules/modules/expansion/pptx_enrich.py @@ -7,9 +7,19 @@ import io misperrors = {'error': 'Error'} mispattributes = {'input': ['attachment'], 'output': ['freetext', 'text']} -moduleinfo = {'version': '0.1', 'author': 'Sascha Rommelfangen', - 'description': '.pptx to freetext-import IOC extractor', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sascha Rommelfangen', + 'description': 'Module to extract freetext from a .pptx document.', + 'module-type': ['expansion'], + 'name': 'PPTX Enrich', + 'logo': 'pptx.png', + 'requirements': ['pptx: Python library to read PowerPoint files.'], + 'features': 'The module reads the text contained in a .pptx document. The result is passed to the freetext import parser so IoCs can be extracted out of it.', + 'references': [], + 'input': 'Attachment attribute containing a .pptx document.', + 'output': 'Text and freetext parsed from the document.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/qintel_qsentry.py b/misp_modules/modules/expansion/qintel_qsentry.py index 6733b93f..609ed01f 100644 --- a/misp_modules/modules/expansion/qintel_qsentry.py +++ b/misp_modules/modules/expansion/qintel_qsentry.py @@ -12,8 +12,16 @@ logger.setLevel(logging.DEBUG) moduleinfo = { 'version': '1.0', 'author': 'Qintel, LLC', - 'description': 'Query Qintel QSentry for ip intelligence', - 'module-type': ['hover', 'expansion'] + 'description': 'A hover and expansion module which queries Qintel QSentry for ip reputation data', + 'module-type': ['hover', 'expansion'], + 'name': 'Qintel QSentry Lookup', + 'logo': 'qintel.png', + 'requirements': ['A Qintel API token'], + 'features': 'This module takes an ip-address (ip-src or ip-dst) attribute as input, and queries the Qintel QSentry API to retrieve ip reputation data', + 'references': ['https://www.qintel.com/products/qsentry/'], + 'input': 'ip address attribute', + 'output': '', + 'ouput': 'Objects containing the enriched IP, threat tags, last seen attributes and associated Autonomous System information', } moduleconfig = ['token', 'remote'] diff --git a/misp_modules/modules/expansion/qrcode.py b/misp_modules/modules/expansion/qrcode.py index bb3effdb..a44d311f 100644 --- a/misp_modules/modules/expansion/qrcode.py +++ b/misp_modules/modules/expansion/qrcode.py @@ -8,9 +8,19 @@ import np misperrors = {'error': 'Error'} mispattributes = {'input': ['attachment'], 'output': ['url', 'btc']} -moduleinfo = {'version': '0.1', 'author': 'Sascha Rommelfangen', - 'description': 'QR code decoder', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sascha Rommelfangen', + 'description': 'Module to decode QR codes.', + 'module-type': ['expansion', 'hover'], + 'name': 'QR Code Decode', + 'logo': '', + 'requirements': ['cv2: The OpenCV python library.', 'pyzbar: Python library to read QR codes.'], + 'features': 'The module reads the QR code and returns the related address, which can be an URL or a bitcoin address.', + 'references': [], + 'input': 'A QR code stored as attachment attribute.', + 'output': 'The URL or bitcoin address the QR code is pointing to.', +} debug = True debug_prefix = "[DEBUG] QR Code module: " diff --git a/misp_modules/modules/expansion/ransomcoindb.py b/misp_modules/modules/expansion/ransomcoindb.py index 0e058552..20b5ebfd 100644 --- a/misp_modules/modules/expansion/ransomcoindb.py +++ b/misp_modules/modules/expansion/ransomcoindb.py @@ -8,15 +8,26 @@ copyright = """ This file is part of the ransomwarecoindDB project and licensed under the AGPL 3.0 license """ -__version__ = 0.1 - debug = False misperrors = {'error': 'Error'} # mispattributes = {'input': ['sha1', 'sha256', 'md5', 'btc', 'xmr', 'dash' ], 'output': ['btc', 'sha1', 'sha256', 'md5', 'freetext']} mispattributes = {'input': ['sha1', 'sha256', 'md5', 'btc'], 'output': ['btc', 'sha1', 'sha256', 'md5', 'freetext'], 'format': 'misp_standard'} -moduleinfo = {'version': __version__, 'author': 'Aaron Kaplan', 'description': 'Module to access the ransomcoinDB (see https://ransomcoindb.concinnity-risks.com)', 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Aaron Kaplan', + 'description': 'Module to access the ransomcoinDB (see https://ransomcoindb.concinnity-risks.com)', + 'module-type': ['expansion', 'hover'], + 'name': 'RandomcoinDB Lookup', + 'logo': '', + 'requirements': ['A ransomcoinDB API key.'], + 'features': 'The module takes either a hash attribute or a btc attribute as input to query the ransomcoinDB API for some additional data.\n\nIf the input is a btc address, we will get the associated hashes returned in a file MISP object. If we query ransomcoinDB with a hash, the response contains the associated btc addresses returned as single MISP btc attributes.', + 'references': ['https://ransomcoindb.concinnity-risks.com'], + 'input': 'A hash (md5, sha1 or sha256) or btc attribute.', + 'output': 'Hashes associated to a btc address or btc addresses associated to a hash.', + 'descrption': 'Module to access the ransomcoinDB with a hash or btc address attribute and get the associated btc address of hashes.', +} moduleconfig = ['api-key'] diff --git a/misp_modules/modules/expansion/rbl.py b/misp_modules/modules/expansion/rbl.py index d3f661ec..408ca518 100644 --- a/misp_modules/modules/expansion/rbl.py +++ b/misp_modules/modules/expansion/rbl.py @@ -9,9 +9,19 @@ except ImportError: misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-dst'], 'output': ['text']} -moduleinfo = {'version': '0.2', 'author': 'Christian Studer', - 'description': 'Check an IPv4 address against known RBLs.', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.2', + 'author': 'Christian Studer', + 'description': 'Module to check an IPv4 address against known RBLs.', + 'module-type': ['expansion', 'hover'], + 'name': 'Real-time Blackhost Lists Lookup', + 'logo': '', + 'requirements': ['dnspython3: DNS python3 library'], + 'features': 'This module takes an IP address attribute as input and queries multiple know Real-time Blackhost Lists to check if they have already seen this IP address.\n\nWe display then all the information we get from those different sources.', + 'references': ['[RBLs list](https://github.com/MISP/misp-modules/blob/8817de476572a10a9c9d03258ec81ca70f3d926d/misp_modules/modules/expansion/rbl.py#L20)'], + 'input': 'IP address attribute.', + 'output': 'Text with additional data from Real-time Blackhost Lists about the IP address.', +} moduleconfig = ['timeout'] rbls = ( diff --git a/misp_modules/modules/expansion/recordedfuture.py b/misp_modules/modules/expansion/recordedfuture.py index 8056bfa1..ad6e4c6b 100644 --- a/misp_modules/modules/expansion/recordedfuture.py +++ b/misp_modules/modules/expansion/recordedfuture.py @@ -16,10 +16,17 @@ from urllib.parse import quote, urlparse from pymisp import MISPAttribute, MISPEvent, MISPTag, MISPObject moduleinfo = { - "version": "2.0.0", - "author": "Recorded Future", - "description": "Module to retrieve data from Recorded Future", - "module-type": ["expansion", "hover"], + 'version': '2.0.0', + 'author': 'Recorded Future', + 'description': 'Module to enrich attributes with threat intelligence from Recorded Future.', + 'module-type': ['expansion', 'hover'], + 'name': 'Recorded Future Enrich', + 'logo': 'recordedfuture.png', + 'requirements': ['A Recorded Future API token.'], + 'features': "Enrich an attribute to add a custom enrichment object to the event. The object contains a copy of the enriched attribute with added tags presenting risk score and triggered risk rules from Recorded Future. Malware and Threat Actors related to the enriched indicator in Recorded Future is matched against MISP's galaxy clusters and applied as galaxy tags. The custom enrichment object also includes a list of related indicators from Recorded Future (IP's, domains, hashes, URL's and vulnerabilities) added as additional attributes.", + 'references': ['https://www.recordedfuture.com/'], + 'input': 'A MISP attribute of one of the following types: ip, ip-src, ip-dst, domain, hostname, md5, sha1, sha256, uri, url, vulnerability, weakness.', + 'output': 'A MISP object containing a copy of the enriched attribute with added tags from Recorded Future and a list of new attributes related to the enriched attribute.', } moduleconfig = ["token", "proxy_host", "proxy_port", "proxy_username", "proxy_password"] diff --git a/misp_modules/modules/expansion/reversedns.py b/misp_modules/modules/expansion/reversedns.py index 43df562a..5cb795c5 100644 --- a/misp_modules/modules/expansion/reversedns.py +++ b/misp_modules/modules/expansion/reversedns.py @@ -5,9 +5,19 @@ misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-dst', 'domain|ip'], 'output': ['hostname']} # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '0.1', 'author': 'Andreas Muehlemann', - 'description': 'Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Andreas Muehlemann', + 'description': 'Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes.', + 'module-type': ['expansion', 'hover'], + 'name': 'Reverse DNS', + 'logo': '', + 'requirements': ['DNS python library'], + 'features': 'The module takes an IP address as input and tries to find the hostname this IP address is resolved into.\n\nThe address of the DNS resolver to use is also configurable, but if no configuration is set, we use the Google public DNS address (8.8.8.8).\n\nPlease note that composite MISP attributes containing IP addresses are supported as well.', + 'references': [], + 'input': 'An IP address attribute.', + 'output': 'Hostname attribute the input is resolved into.', +} # config fields that your code expects from the site admin moduleconfig = ['nameserver'] diff --git a/misp_modules/modules/expansion/securitytrails.py b/misp_modules/modules/expansion/securitytrails.py index f5750e1b..ae251c57 100644 --- a/misp_modules/modules/expansion/securitytrails.py +++ b/misp_modules/modules/expansion/securitytrails.py @@ -24,9 +24,19 @@ mispattributes = { 'whois-registrar', 'whois-creation-date', 'domain'] } -moduleinfo = {'version': '1', 'author': 'Sebastien Larinier @sebdraven', - 'description': 'Query on securitytrails.com', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '1', + 'author': 'Sebastien Larinier @sebdraven', + 'description': 'An expansion modules for SecurityTrails.', + 'module-type': ['expansion', 'hover'], + 'name': 'SecurityTrails Lookup', + 'logo': 'securitytrails.png', + 'requirements': ['dnstrails python library', 'An access to the SecurityTrails API (apikey)'], + 'features': 'The module takes a domain, hostname or IP address attribute as input and queries the SecurityTrails API with it.\n\nMultiple parsing operations are then processed on the result of the query to extract a much information as possible.\n\nFrom this data extracted are then mapped MISP attributes.', + 'references': ['https://securitytrails.com/'], + 'input': 'A domain, hostname or IP address attribute.', + 'output': 'MISP attributes resulting from the query on SecurityTrails API, included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- dns-soa-email\n- whois-registrant-email\n- whois-registrant-phone\n- whois-registrant-name\n- whois-registrar\n- whois-creation-date\n- domain', +} # config fields that your code expects from the site admin moduleconfig = ['apikey'] diff --git a/misp_modules/modules/expansion/shodan.py b/misp_modules/modules/expansion/shodan.py index 2ea97499..9c3ab4f4 100755 --- a/misp_modules/modules/expansion/shodan.py +++ b/misp_modules/modules/expansion/shodan.py @@ -12,9 +12,19 @@ from pymisp import MISPAttribute, MISPEvent, MISPObject misperrors = {'error': 'Error'} mispattributes = {'input': ['ip-src', 'ip-dst'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.2', 'author': 'Raphaël Vinot', - 'description': 'Query on Shodan', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.2', + 'author': 'Raphaël Vinot', + 'description': 'Module to query on Shodan.', + 'module-type': ['expansion'], + 'name': 'Shodan Lookup', + 'logo': 'shodan.png', + 'requirements': ['shodan python library', 'An access to the Shodan API (apikey)'], + 'features': 'The module takes an IP address as input and queries the Shodan API to get some additional data about it.', + 'references': ['https://www.shodan.io/'], + 'input': 'An IP address MISP attribute.', + 'output': 'Text with additional data about the input, resulting from the query on Shodan.', +} moduleconfig = ['apikey'] diff --git a/misp_modules/modules/expansion/sigma_queries.py b/misp_modules/modules/expansion/sigma_queries.py index d17a1004..41ba9b49 100644 --- a/misp_modules/modules/expansion/sigma_queries.py +++ b/misp_modules/modules/expansion/sigma_queries.py @@ -9,8 +9,19 @@ except ImportError: misperrors = {'error': 'Error'} mispattributes = {'input': ['sigma'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Christian Studer', 'module-type': ['expansion', 'hover'], - 'description': 'An expansion hover module to display the result of sigma queries.'} +moduleinfo = { + 'version': '0.1', + 'author': 'Christian Studer', + 'module-type': ['expansion', 'hover'], + 'name': 'Sigma Rule Converter', + 'description': 'An expansion hover module to display the result of sigma queries.', + 'logo': 'sigma.png', + 'requirements': ['Sigma python library'], + 'features': 'This module takes a Sigma rule attribute as input and tries all the different queries available to convert it into different formats recognized by SIEMs.', + 'references': ['https://github.com/Neo23x0/sigma/wiki'], + 'input': 'A Sigma attribute.', + 'output': 'Text displaying results of queries on the Sigma attribute.', +} moduleconfig = [] sigma_targets = ('es-dsl', 'es-qs', 'graylog', 'kibana', 'xpack-watcher', 'logpoint', 'splunk', 'grep', 'mdatp', 'splunkxml', 'arcsight', 'qualys') diff --git a/misp_modules/modules/expansion/sigma_syntax_validator.py b/misp_modules/modules/expansion/sigma_syntax_validator.py index 658b4d3f..b8739233 100644 --- a/misp_modules/modules/expansion/sigma_syntax_validator.py +++ b/misp_modules/modules/expansion/sigma_syntax_validator.py @@ -8,8 +8,19 @@ except ImportError: misperrors = {'error': 'Error'} mispattributes = {'input': ['sigma'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Christian Studer', 'module-type': ['expansion', 'hover'], - 'description': 'An expansion hover module to perform a syntax check on sigma rules'} +moduleinfo = { + 'version': '0.1', + 'author': 'Christian Studer', + 'module-type': ['expansion', 'hover'], + 'name': 'Sigma Syntax Validator', + 'description': 'An expansion hover module to perform a syntax check on sigma rules.', + 'logo': 'sigma.png', + 'requirements': ['Sigma python library', 'Yaml python library'], + 'features': 'This module takes a Sigma rule attribute as input and performs a syntax check on it.\n\nIt displays then that the rule is valid if it is the case, and the error related to the rule otherwise.', + 'references': ['https://github.com/Neo23x0/sigma/wiki'], + 'input': 'A Sigma attribute.', + 'output': 'Text describing the validity of the Sigma rule.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/sigmf-expand.py b/misp_modules/modules/expansion/sigmf_expand.py similarity index 96% rename from misp_modules/modules/expansion/sigmf-expand.py rename to misp_modules/modules/expansion/sigmf_expand.py index e0030385..b7a55a80 100644 --- a/misp_modules/modules/expansion/sigmf-expand.py +++ b/misp_modules/modules/expansion/sigmf_expand.py @@ -26,9 +26,19 @@ log.addHandler(sh) misperrors = {'error': 'Error'} mispattributes = {'input': ['sigmf-recording', 'sigmf-archive'], 'output': [ 'MISP objects'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.1', 'author': 'Luciano Righetti', - 'description': 'Expands a SigMF Recording object into a SigMF Expanded Recording object, extracts a SigMF archive into a SigMF Recording object.', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Luciano Righetti', + 'description': 'Expands a SigMF Recording object into a SigMF Expanded Recording object, extracts a SigMF archive into a SigMF Recording object.', + 'module-type': ['expansion'], + 'name': 'SigMF Expansion', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} def get_samples(data_bytes, data_type) -> np.ndarray: diff --git a/misp_modules/modules/expansion/socialscan.py b/misp_modules/modules/expansion/socialscan.py index 54f58f6f..8800397b 100644 --- a/misp_modules/modules/expansion/socialscan.py +++ b/misp_modules/modules/expansion/socialscan.py @@ -5,8 +5,15 @@ from socialscan.util import sync_execute_queries moduleinfo = { 'version': '1', 'author': 'Christian Studer', - 'description': 'Module to query several online platforms to look for existing accounts.', - 'module-type': ['hover'] + 'description': 'A hover module to get information on the availability of an email address or username on some online platforms.', + 'module-type': ['hover'], + 'name': 'Socialscan Lookup', + 'logo': '', + 'requirements': ['The socialscan python library'], + 'features': 'The module takes an email address or username as input and check its availability on some online platforms. The results for each platform are then returned to see if the email address or the username is used, available or if there is an issue with it.', + 'references': ['https://github.com/iojw/socialscan'], + 'input': 'An email address or usename attribute.', + 'output': 'Text containing information about the availability of an email address or a username in some online platforms.', } mispattributes = { 'input': [ diff --git a/misp_modules/modules/expansion/sophoslabs_intelix.py b/misp_modules/modules/expansion/sophoslabs_intelix.py index 4d7c4139..1b0bc9ff 100644 --- a/misp_modules/modules/expansion/sophoslabs_intelix.py +++ b/misp_modules/modules/expansion/sophoslabs_intelix.py @@ -5,10 +5,19 @@ from . import check_input_attribute, checking_error, standard_error_message from pymisp import MISPEvent, MISPObject from urllib.parse import quote -moduleinfo = {'version': '1.0', - 'author': 'Ben Verschaeren', - 'description': 'SOPHOSLabs Intelix Integration', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '1.0', + 'author': 'Ben Verschaeren', + 'description': 'An expansion module to query the Sophoslabs intelix API to get additional information about an ip address, url, domain or sha256 attribute.', + 'module-type': ['expansion'], + 'name': 'SophosLabs Intelix Lookup', + 'logo': 'sophoslabs_intelix.svg', + 'requirements': ['A client_id and client_secret pair to authenticate to the SophosLabs Intelix API'], + 'features': 'The module takes an ip address, url, domain or sha256 attribute and queries the SophosLabs Intelix API with the attribute value. The result of this query is a SophosLabs Intelix hash report, or an ip or url lookup, that is then parsed and returned in a MISP object.', + 'references': ['https://aws.amazon.com/marketplace/pp/B07SLZPMCS'], + 'input': 'An ip address, url, domain or sha256 attribute.', + 'output': 'SophosLabs Intelix report and lookup objects', +} moduleconfig = ['client_id', 'client_secret'] diff --git a/misp_modules/modules/expansion/sourcecache.py b/misp_modules/modules/expansion/sourcecache.py index b09068bc..18b38e42 100755 --- a/misp_modules/modules/expansion/sourcecache.py +++ b/misp_modules/modules/expansion/sourcecache.py @@ -3,7 +3,19 @@ from url_archiver import url_archiver misperrors = {'error': 'Error'} mispattributes = {'input': ['link', 'url'], 'output': ['attachment', 'malware-sample']} -moduleinfo = {'version': '0.1', 'author': 'Alexandre Dulaunoy', 'description': 'Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page.', 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Alexandre Dulaunoy', + 'description': 'Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page.', + 'module-type': ['expansion'], + 'name': 'URL Archiver', + 'logo': '', + 'requirements': ['urlarchiver: python library to fetch and archive URL on the file-system'], + 'features': 'This module takes a link or url attribute as input and caches the related web page. It returns then a link of the cached page.', + 'references': ['https://github.com/adulau/url_archiver'], + 'input': 'A link or url attribute.', + 'output': 'A malware-sample attribute describing the cached page.', +} moduleconfig = ['archivepath'] diff --git a/misp_modules/modules/expansion/stairwell.py b/misp_modules/modules/expansion/stairwell.py index c9acfc89..1421240a 100644 --- a/misp_modules/modules/expansion/stairwell.py +++ b/misp_modules/modules/expansion/stairwell.py @@ -19,8 +19,15 @@ mispattributes = { moduleinfo = { 'version': '0.1', 'author': 'goodlandsecurity', - 'description': 'Enrich hash observables with the Stairwell API', - 'module-type': ['expansion'] + 'description': 'Module to query the Stairwell API to get additional information about the input hash attribute', + 'module-type': ['expansion'], + 'name': 'Stairwell Lookup', + 'logo': 'stairwell.png', + 'requirements': ['Access to Stairwell platform (apikey)'], + 'features': "The module takes a hash attribute as input and queries Stariwell's API to fetch additional data about it. The result, if the payload is observed in Stariwell, is a file object describing the file the input hash is related to.", + 'references': ['https://stairwell.com', 'https://docs.stairwell.com'], + 'input': 'A hash attribute (md5, sha1, sha256).', + 'output': 'File object related to the input attribute found on Stairwell platform.', } moduleconfig = ["apikey"] diff --git a/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py b/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py index 842217ab..15e44ee5 100644 --- a/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py +++ b/misp_modules/modules/expansion/stix2_pattern_syntax_validator.py @@ -6,8 +6,19 @@ except ImportError: misperrors = {'error': 'Error'} mispattributes = {'input': ['stix2-pattern'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Christian Studer', 'module-type': ['hover'], - 'description': 'An expansion hover module to perform a syntax check on stix2 patterns.'} +moduleinfo = { + 'version': '0.1', + 'author': 'Christian Studer', + 'module-type': ['hover'], + 'name': 'STIX2 Pattern Syntax Validator', + 'description': 'An expansion hover module to perform a syntax check on stix2 patterns.', + 'logo': 'stix.png', + 'requirements': ['stix2patterns python library'], + 'features': 'This module takes a STIX2 pattern attribute as input and performs a syntax check on it.\n\nIt displays then that the rule is valid if it is the case, and the error related to the rule otherwise.', + 'references': ['[STIX2.0 patterning specifications](http://docs.oasis-open.org/cti/stix/v2.0/cs01/part5-stix-patterning/stix-v2.0-cs01-part5-stix-patterning.html)'], + 'input': 'A STIX2 pattern attribute.', + 'output': 'Text describing the validity of the STIX2 pattern.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/threatcrowd.py b/misp_modules/modules/expansion/threatcrowd.py index 268832fc..4c795161 100644 --- a/misp_modules/modules/expansion/threatcrowd.py +++ b/misp_modules/modules/expansion/threatcrowd.py @@ -8,9 +8,19 @@ mispattributes = {'input': ["hostname", "domain", "ip-src", "ip-dst", "md5", "sh } # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '1', 'author': 'chrisdoman', - 'description': 'Get information from ThreatCrowd', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '1', + 'author': 'chrisdoman', + 'description': 'Module to get information from ThreatCrowd.', + 'module-type': ['expansion'], + 'name': 'ThreatCrowd Lookup', + 'logo': 'threatcrowd.png', + 'requirements': [], + 'features': 'This module takes a MISP attribute as input and queries ThreatCrowd with it.\n\nThe result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute.', + 'references': ['https://www.threatcrowd.org/'], + 'input': 'A MISP attribute included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- md5\n- sha1\n- sha256\n- sha512\n- whois-registrant-email', + 'output': 'MISP attributes mapped from the result of the query on ThreatCrowd, included in the following list:\n- domain\n- ip-src\n- ip-dst\n- text\n- md5\n- sha1\n- sha256\n- sha512\n- hostname\n- whois-registrant-email', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/threatfox.py b/misp_modules/modules/expansion/threatfox.py index 4a899184..ee82e4fd 100644 --- a/misp_modules/modules/expansion/threatfox.py +++ b/misp_modules/modules/expansion/threatfox.py @@ -4,7 +4,19 @@ import json misperrors = {'error': 'Error'} mispattributes = {'input': ['md5', 'sha1', 'sha256', 'domain', 'url', 'email-src', 'ip-dst|port', 'ip-src|port'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Corsin Camichel', 'description': 'Module to search for an IOC on ThreatFox by abuse.ch.', 'module-type': ['hover', 'expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Corsin Camichel', + 'description': 'Module to search for an IOC on ThreatFox by abuse.ch.', + 'module-type': ['hover', 'expansion'], + 'name': 'ThreadFox Lookup', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} moduleconfig = [] API_URL = "https://threatfox-api.abuse.ch/api/v1/" diff --git a/misp_modules/modules/expansion/threatminer.py b/misp_modules/modules/expansion/threatminer.py index 1dd2bd87..090f1fa1 100755 --- a/misp_modules/modules/expansion/threatminer.py +++ b/misp_modules/modules/expansion/threatminer.py @@ -9,9 +9,19 @@ mispattributes = {'input': ['hostname', 'domain', 'ip-src', 'ip-dst', 'md5', 'sh } # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '1', 'author': 'KX499', - 'description': 'Get information from ThreatMiner', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '1', + 'author': 'KX499', + 'description': 'Module to get information from ThreatMiner.', + 'module-type': ['expansion'], + 'name': 'ThreatMiner Lookup', + 'logo': 'threatminer.png', + 'requirements': [], + 'features': 'This module takes a MISP attribute as input and queries ThreatMiner with it.\n\nThe result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute.', + 'references': ['https://www.threatminer.org/'], + 'input': 'A MISP attribute included in the following list:\n- hostname\n- domain\n- ip-src\n- ip-dst\n- md5\n- sha1\n- sha256\n- sha512', + 'output': 'MISP attributes mapped from the result of the query on ThreatMiner, included in the following list:\n- domain\n- ip-src\n- ip-dst\n- text\n- md5\n- sha1\n- sha256\n- sha512\n- ssdeep\n- authentihash\n- filename\n- whois-registrant-email\n- url\n- link', +} class ThreatMiner(): diff --git a/misp_modules/modules/expansion/triage_submit.py b/misp_modules/modules/expansion/triage_submit.py new file mode 100644 index 00000000..97db16c9 --- /dev/null +++ b/misp_modules/modules/expansion/triage_submit.py @@ -0,0 +1,119 @@ +import json +import requests +import base64 +import io +import zipfile + +misperrors = {'error': 'Error'} +mispattributes = {'input': ['attachment', 'malware-sample', 'url'], 'output': ['link']} +moduleinfo = { + 'version': '1', + 'author': 'Karen Yousefi', + 'description': 'Module to submit samples to tria.ge', + 'module-type': ['expansion', 'hover'], + 'name': 'Triage Submit', + 'logo': '', +} + +moduleconfig = ['apikey', 'url_mode'] + + +def handler(q=False): + if q is False: + return False + + request = json.loads(q) + + if request.get('config', {}).get('apikey') is None: + misperrors['error'] = 'tria.ge API key is missing' + return misperrors + + api_key = request['config']['apikey'] + url_mode = request['config'].get('url_mode', 'submit') # 'submit' or 'fetch' + base_url = 'https://tria.ge/api/v0/samples' + headers = {'Authorization': f'Bearer {api_key}'} + + if 'attachment' in request: + data = request['data'] + filename = request['attachment'] + return submit_file(headers, base_url, data, filename) + elif 'malware-sample' in request: + data = request['data'] + filename = request['malware-sample'].split('|')[0] + return submit_file(headers, base_url, data, filename, is_malware_sample=True) + elif 'url' in request: + url = request['url'] + return submit_url(headers, base_url, url, url_mode) + else: + misperrors['error'] = 'Unsupported input type' + return misperrors + + +def submit_file(headers, base_url, data, filename, is_malware_sample=False): + try: + if is_malware_sample: + file_data = base64.b64decode(data) + zip_file = zipfile.ZipFile(io.BytesIO(file_data)) + file_data = zip_file.read(zip_file.namelist()[0], pwd=b'infected') + else: + file_data = base64.b64decode(data) + + files = {'file': (filename, file_data)} + response = requests.post(base_url, headers=headers, files=files) + response.raise_for_status() + result = response.json() + + sample_id = result['id'] + sample_url = f'https://tria.ge/{sample_id}' + + return { + 'results': [ + { + 'types': 'link', + 'values': sample_url, + 'comment': 'Link to tria.ge analysis', + } + ] + } + + except Exception as e: + misperrors['error'] = f'Error submitting to tria.ge: {str(e)}' + return misperrors + + +def submit_url(headers, base_url, url, mode): + try: + if mode == 'fetch': + data = {'kind': 'fetch', 'url': url} + else: # submit + data = {'kind': 'url', 'url': url} + + response = requests.post(base_url, headers=headers, json=data) + response.raise_for_status() + result = response.json() + + sample_id = result['id'] + sample_url = f'https://tria.ge/{sample_id}' + + return { + 'results': [ + { + 'types': 'link', + 'values': sample_url, + 'comment': f'Link to tria.ge analysis ({mode} mode)', + } + ] + } + + except Exception as e: + misperrors['error'] = f'Error submitting to tria.ge: {str(e)}' + return misperrors + + +def introspection(): + return mispattributes + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo diff --git a/misp_modules/modules/expansion/trustar_enrich.py b/misp_modules/modules/expansion/trustar_enrich.py index b7ee2a40..6cbdcb3e 100644 --- a/misp_modules/modules/expansion/trustar_enrich.py +++ b/misp_modules/modules/expansion/trustar_enrich.py @@ -12,9 +12,19 @@ mispattributes = { 'input': ["btc", "domain", "email-src", "filename", "hostname", "ip-src", "ip-dst", "malware-type", "md5", "sha1", "sha256", "url"], 'format': 'misp_standard'} -moduleinfo = {'version': "0.1", 'author': "Jesse Hedden", - 'description': "Enrich data with TruSTAR", - 'module-type': ["hover", "expansion"]} +moduleinfo = { + 'version': '0.1', + 'author': 'Jesse Hedden', + 'description': 'Module to get enrich indicators with TruSTAR.', + 'module-type': ['hover', 'expansion'], + 'name': 'TruSTAR Enrich', + 'logo': 'trustar.png', + 'requirements': [], + 'features': 'This module enriches MISP attributes with scoring and metadata from TruSTAR.\n\nThe TruSTAR indicator summary is appended to the attributes along with links to any associated reports.', + 'references': ['https://docs.trustar.co/api/v13/indicators/get_indicator_summaries.html'], + 'input': 'Any of the following MISP attributes:\n- btc\n- domain\n- email-src\n- filename\n- hostname\n- ip-src\n- ip-dst\n- md5\n- sha1\n- sha256\n- url', + 'output': 'MISP attributes enriched with indicator summary data from the TruSTAR API. Data includes a severity level score and additional source and scoring info.', +} moduleconfig = ["user_api_key", "user_api_secret", "enclave_ids"] diff --git a/misp_modules/modules/expansion/urlhaus.py b/misp_modules/modules/expansion/urlhaus.py index ed13b77a..8c7efa2e 100644 --- a/misp_modules/modules/expansion/urlhaus.py +++ b/misp_modules/modules/expansion/urlhaus.py @@ -8,9 +8,19 @@ misperrors = {'error': 'Error'} mispattributes = {'input': ['domain', 'hostname', 'ip-src', 'ip-dst', 'md5', 'sha256', 'url'], 'output': ['url', 'filename', 'md5', 'sha256'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.1', 'author': 'Christian Studer', - 'description': 'Query of the URLhaus API to get additional information about some attributes.', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Christian Studer', + 'description': 'Query of the URLhaus API to get additional information about the input attribute.', + 'module-type': ['expansion', 'hover'], + 'name': 'URLhaus Lookup', + 'logo': 'urlhaus.png', + 'requirements': [], + 'features': 'Module using the new format of modules able to return attributes and objects.\n\nThe module takes one of the attribute type specified as input, and query the URLhaus API with it. If any result is returned by the API, attributes and objects are created accordingly.', + 'references': ['https://urlhaus.abuse.ch/'], + 'input': 'A domain, hostname, url, ip, md5 or sha256 attribute.', + 'output': 'MISP attributes & objects fetched from the result of the URLhaus API query.', +} moduleconfig = [] file_keys = ('filename', 'response_size', 'response_md5', 'response_sha256') diff --git a/misp_modules/modules/expansion/urlscan.py b/misp_modules/modules/expansion/urlscan.py index e6af7f61..c36dea6c 100644 --- a/misp_modules/modules/expansion/urlscan.py +++ b/misp_modules/modules/expansion/urlscan.py @@ -15,8 +15,15 @@ log.addHandler(ch) moduleinfo = { 'version': '0.1', 'author': 'Dave Johnson', - 'description': 'Module to query urlscan.io', - 'module-type': ['expansion'] + 'description': 'An expansion module to query urlscan.io.', + 'module-type': ['expansion'], + 'name': 'URLScan Lookup', + 'logo': 'urlscan.jpg', + 'requirements': ['An access to the urlscan.io API'], + 'features': 'This module takes a MISP attribute as input and queries urlscan.io with it.\n\nThe result of this query is then parsed and some data is mapped into MISP attributes in order to enrich the input attribute.', + 'references': ['https://urlscan.io/'], + 'input': 'A domain, hostname or url attribute.', + 'output': 'MISP attributes mapped from the result of the query on urlscan.io.', } moduleconfig = ['apikey'] diff --git a/misp_modules/modules/expansion/variotdbs.py b/misp_modules/modules/expansion/variotdbs.py index 6dc8880d..8526949b 100644 --- a/misp_modules/modules/expansion/variotdbs.py +++ b/misp_modules/modules/expansion/variotdbs.py @@ -1,166 +1,83 @@ import json import requests from . import check_input_attribute, standard_error_message -from pymisp import MISPAttribute, MISPEvent, MISPObject +from ._vulnerability_parser.vulnerability_parser import ( + VulnerabilityMapping, VulnerabilityParser) +from pymisp import MISPObject misperrors = {'error': 'Error'} mispattributes = {'input': ['vulnerability'], 'format': 'misp_standard'} -moduleinfo = {'version': '1', 'author': 'Christian Studer', - 'description': 'An expansion module to query variotdbs.pl', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '1', + 'author': 'Christian Studer', + 'description': 'An expansion module to query the VARIoT db API for more information about a vulnerability.', + 'module-type': ['expansion', 'hover'], + 'name': 'VARIoT db Lookup', + 'logo': 'variot.png', + 'requirements': ['A VARIoT db API key (if you do not want to be limited to 100 queries / day)'], + 'features': 'The module takes a vulnerability attribute as input and queries que VARIoT db API to gather additional information.\n\nThe `vuln` endpoint is queried first to look for additional information about the vulnerability itself.\n\nThe `exploits` endpoint is also queried then to look for the information of the potential related exploits, which are parsed and added to the results using the `exploit` object template.', + 'references': ['https://www.variotdbs.pl/'], + 'input': 'Vulnerability attribute.', + 'output': 'Additional information about the vulnerability, as it is stored on the VARIoT db, about the vulnerability itself, and the potential related exploits.', +} moduleconfig = ['API_key'] variotdbs_url = 'https://www.variotdbs.pl/api' -class VariotdbsParser: +class VariotMapping(VulnerabilityMapping): + __exploit_mapping = { + 'credits': 'credit', + 'description': 'description', + 'exploit': 'exploit', + 'title': 'title' + } + __exploit_multiple_mapping = { + 'cve': { + 'feature': 'cve_id', + 'relation': 'cve-id' + }, + 'references': { + 'feature': 'url', + 'relation': 'reference' + } + } + + @classmethod + def exploit_mapping(cls) -> dict: + return cls.__exploit_mapping + + @classmethod + def exploit_multiple_mapping(cls) -> dict: + return cls.__exploit_multiple_mapping + + +class VariotdbsParser(VulnerabilityParser): def __init__(self, attribute): - misp_attribute = MISPAttribute() - misp_attribute.from_dict(**attribute) - misp_event = MISPEvent() - misp_event.add_attribute(**misp_attribute) - self.__misp_attribute = misp_attribute - self.__misp_event = misp_event - self.__exploit_mapping = { - 'credits': 'credit', - 'description': 'description', - 'exploit': 'exploit', - 'title': 'title' - } - self.__exploit_multiple_mapping = { - 'cve': { - 'feature': 'cve_id', - 'relation': 'cve-id' - }, - 'references': { - 'feature': 'url', - 'relation': 'reference' - } - } - self.__vulnerability_data_mapping = { - 'credits': 'credit', - 'description': 'description', - 'title': 'summary' - } - self.__vulnerability_flat_mapping = { - 'cve': 'id', 'id': 'id' - } + super().__init__(attribute) + self.__mapping = VulnerabilityMapping @property - def exploit_mapping(self) -> dict: - return self.__exploit_mapping - - @property - def exploit_multiple_mapping(self) -> dict: - return self.__exploit_multiple_mapping - - @property - def misp_attribute(self) -> MISPAttribute: - return self.__misp_attribute - - @property - def misp_event(self) -> MISPEvent: - return self.__misp_event - - @property - def vulnerability_data_mapping(self) -> dict: - return self.__vulnerability_data_mapping - - @property - def vulnerability_flat_mapping(self) -> dict: - return self.__vulnerability_flat_mapping - - def get_results(self): - event = json.loads(self.misp_event.to_json()) - results = {key: event[key] for key in ('Attribute', 'Object') if event.get(key)} - return {'results': results} + def mapping(self) -> VulnerabilityMapping: + return self.__mapping def parse_exploit_information(self, query_results): for exploit in query_results: exploit_object = MISPObject('exploit') exploit_object.add_attribute('exploitdb-id', exploit['edb_id']) - for feature, relation in self.exploit_mapping.items(): - if exploit.get(feature): + for field, relation in self.mapping.exploit_mapping().items(): + if exploit.get(field): exploit_object.add_attribute( - relation, - exploit[feature]['data'] + relation, exploit[field]['data'] ) - for feature, relation in self.exploit_multiple_mapping.items(): - if exploit.get(feature): - for value in exploit[feature]['data']: + for field, relation in self.mapping.exploit_multiple_mapping().items(): + if exploit.get(field): + for value in exploit[field]['data']: exploit_object.add_attribute( - relation['relation'], - value[relation['feature']] + relation['relation'], value[relation['feature']] ) exploit_object.add_reference(self.misp_attribute.uuid, 'related-to') self.misp_event.add_object(exploit_object) - def parse_vulnerability_information(self, query_results): - vulnerability_object = MISPObject('vulnerability') - for feature, relation in self.vulnerability_flat_mapping.items(): - if query_results.get(feature): - vulnerability_object.add_attribute( - relation, - query_results[feature] - ) - for feature, relation in self.vulnerability_data_mapping.items(): - if query_results.get(feature, {}).get('data'): - vulnerability_object.add_attribute( - relation, - query_results[feature]['data'] - ) - if query_results.get('configurations', {}).get('data'): - for configuration in query_results['configurations']['data']: - for node in configuration['nodes']: - for cpe_match in node['cpe_match']: - if cpe_match['vulnerable']: - vulnerability_object.add_attribute( - 'vulnerable-configuration', - cpe_match['cpe23Uri'] - ) - if query_results.get('cvss', {}).get('data'): - cvss = {} - for cvss_data in query_results['cvss']['data']: - for cvss_v3 in cvss_data['cvssV3']: - cvss[float(cvss_v3['trust'])] = cvss_v3 - if cvss: - cvss = cvss[max(cvss)] - vulnerability_object.add_attribute( - 'cvss-score', - cvss['baseScore'] - ) - vulnerability_object.add_attribute( - 'cvss-string', - cvss['vectorString'] - ) - if query_results.get('references', {}).get('data'): - for reference in query_results['references']['data']: - vulnerability_object.add_attribute( - 'references', - reference['url'] - ) - if query_results.get('sources_release_date', {}).get('data'): - for release_date in query_results['sources_release_date']['data']: - if release_date['db'] != 'NVD': - continue - if release_date['id'] == self.misp_attribute.value: - vulnerability_object.add_attribute( - 'published', - release_date['date'] - ) - break - if query_results.get('sources_update_date', {}).get('data'): - for update_date in query_results['sources_update_date']['data']: - if update_date['db'] != 'NVD': - continue - if update_date['id'] == self.misp_attribute.value: - vulnerability_object.add_attribute( - 'modified', - update_date['date'] - ) - break - vulnerability_object.add_reference(self.misp_attribute.uuid, 'related-to') - self.misp_event.add_object(vulnerability_object) - def handler(q=False): if q is False: @@ -180,7 +97,7 @@ def handler(q=False): if r.status_code == 200: vulnerability_results = r.json() if vulnerability_results: - parser.parse_vulnerability_information(vulnerability_results) + parser._parse_variot_description(vulnerability_results) empty = False else: if r.reason != 'Not Found': diff --git a/misp_modules/modules/expansion/virustotal.py b/misp_modules/modules/expansion/virustotal.py index 985b6892..828efb60 100644 --- a/misp_modules/modules/expansion/virustotal.py +++ b/misp_modules/modules/expansion/virustotal.py @@ -8,9 +8,19 @@ mispattributes = {'input': ['hostname', 'domain', "ip-src", "ip-dst", "md5", "sh 'format': 'misp_standard'} # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '6', 'author': 'Hannah Ward', - 'description': 'Enrich observables with the VirusTotal v3 API', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '6', + 'author': 'Hannah Ward', + 'description': 'Enrich observables with the VirusTotal v3 API', + 'module-type': ['expansion'], + 'name': 'VirusTotal v3 Lookup', + 'logo': 'virustotal.png', + 'requirements': ['An access to the VirusTotal API (apikey), with a high request rate limit.'], + 'features': 'New format of modules able to return attributes and objects.\n\nA module to take a MISP attribute as input and query the VirusTotal API to get additional data about it.\n\nCompared to the [standard VirusTotal expansion module](https://github.com/MISP/misp-modules/blob/main/misp_modules/modules/expansion/virustotal_public.py), this module is made for advanced parsing of VirusTotal report, with a recursive analysis of the elements found after the first request.\n\nThus, it requires a higher request rate limit to avoid the API to return a 204 error (Request rate limit exceeded), and the data parsed from the different requests are returned as MISP attributes and objects, with the corresponding relations between each one of them.', + 'references': ['https://www.virustotal.com/', 'https://docs.virustotal.com/reference/overview'], + 'input': 'A domain, hash (md5, sha1, sha256 or sha512), hostname or IP address attribute.', + 'output': 'MISP attributes and objects resulting from the parsing of the VirusTotal report concerning the input attribute.', +} # config fields that your code expects from the site admin moduleconfig = ["apikey", "event_limit", 'proxy_host', 'proxy_port', 'proxy_username', 'proxy_password'] @@ -84,7 +94,7 @@ class VirusTotalParser: misp_object.add_attribute('ip', type='ip-dst', value=report.id) elif report.type == 'url': misp_object = MISPObject('url') - misp_object.add_attribute('url', type='url', value=report.url) + misp_object.add_attribute('url', type='url', value=report.id) misp_object.add_reference(vt_uuid, 'analyzed-with') return misp_object diff --git a/misp_modules/modules/expansion/virustotal_public.py b/misp_modules/modules/expansion/virustotal_public.py index dba60fae..d8de2863 100644 --- a/misp_modules/modules/expansion/virustotal_public.py +++ b/misp_modules/modules/expansion/virustotal_public.py @@ -8,9 +8,19 @@ from pymisp import MISPAttribute, MISPEvent, MISPObject misperrors = {'error': 'Error'} mispattributes = {'input': ['hostname', 'domain', "ip-src", "ip-dst", "md5", "sha1", "sha256", "url"], 'format': 'misp_standard'} -moduleinfo = {'version': '2', 'author': 'Christian Studer', - 'description': 'Enrich observables with the VirusTotal v3 public API', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '2', + 'author': 'Christian Studer', + 'description': 'Enrich observables with the VirusTotal v3 public API', + 'module-type': ['expansion', 'hover'], + 'name': 'VirusTotal Public API Lookup', + 'logo': 'virustotal.png', + 'requirements': ['An access to the VirusTotal API (apikey)'], + 'features': 'New format of modules able to return attributes and objects.\n\nA module to take a MISP attribute as input and query the VirusTotal API to get additional data about it.\n\nCompared to the [more advanced VirusTotal expansion module](https://github.com/MISP/misp-modules/blob/main/misp_modules/modules/expansion/virustotal.py), this module is made for VirusTotal users who have a low request rate limit.\n\nThus, it only queries the API once and returns the results that is parsed into MISP attributes and objects.', + 'references': ['https://www.virustotal.com', 'https://docs.virustotal.com/reference/overview'], + 'input': 'A domain, hostname, ip, url or hash (md5, sha1, sha256 or sha512) attribute.', + 'output': 'MISP attributes and objects resulting from the parsing of the VirusTotal report concerning the input attribute.', +} moduleconfig = ['apikey', 'proxy_host', 'proxy_port', 'proxy_username', 'proxy_password'] @@ -80,7 +90,7 @@ class VirusTotalParser: misp_object.add_attribute('ip', type='ip-dst', value=report.id) elif report.type == 'url': misp_object = MISPObject('url') - misp_object.add_attribute('url', type='url', value=report.url) + misp_object.add_attribute('url', type='url', value=report.id) misp_object.add_reference(vt_uuid, 'analyzed-with') return misp_object diff --git a/misp_modules/modules/expansion/virustotal_upload.py b/misp_modules/modules/expansion/virustotal_upload.py new file mode 100644 index 00000000..e0ae1499 --- /dev/null +++ b/misp_modules/modules/expansion/virustotal_upload.py @@ -0,0 +1,91 @@ +import json +import sys +import base64 +import io +import zipfile +import requests +import hashlib + +misperrors = {'error': 'Error'} +mispattributes = {'input': ['attachment', 'malware-sample'], 'output': ['link']} +moduleinfo = { + 'version': '1', + 'author': 'Karen Yousefi', + 'description': 'Module to push malware samples to VirusTotal', + 'module-type': ['expansion'], + 'name': 'VirusTotal Upload', + 'requirements': ['requests library'], + 'logo': 'virustotal.png', +} + +moduleconfig = ['virustotal_apikey'] + + +def handler(q=False): + if q is False: + return False + request = json.loads(q) + + try: + data = request.get("data") + if 'malware-sample' in request: + sample_filename = request.get("malware-sample").split("|", 1)[0] + data = base64.b64decode(data) + fl = io.BytesIO(data) + zf = zipfile.ZipFile(fl) + sample_hashname = zf.namelist()[0] + data = zf.read(sample_hashname, b"infected") + zf.close() + elif 'attachment' in request: + sample_filename = request.get("attachment") + data = base64.b64decode(data) + else: + misperrors['error'] = "No malware sample or attachment supplied" + return misperrors + except Exception: + misperrors['error'] = "Unable to process submitted sample data" + return misperrors + + if request["config"].get("virustotal_apikey") is None: + misperrors["error"] = "Missing VirusTotal API key" + return misperrors + + virustotal_apikey = request["config"].get("virustotal_apikey") + + try: + url = "https://www.virustotal.com/api/v3/files" + headers = { + "accept": "application/json", + "x-apikey": virustotal_apikey, + } + files = {"file": (sample_filename, data)} + response = requests.post(url, headers=headers, files=files) + response.raise_for_status() + + # Calculate SHA256 of the file + sha256 = hashlib.sha256(data).hexdigest() + + virustotal_link = f"https://www.virustotal.com/gui/file/{sha256}" + except Exception as e: + misperrors['error'] = f"Unable to send sample to VirusTotal: {str(e)}" + return misperrors + + r = { + 'results': [ + { + 'types': 'link', + 'values': virustotal_link, + 'comment': 'Link to VirusTotal analysis', + } + ] + } + return r + + +def introspection(): + return mispattributes + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo diff --git a/misp_modules/modules/expansion/vmray_submit.py b/misp_modules/modules/expansion/vmray_submit.py index fa0a073f..78d7de53 100644 --- a/misp_modules/modules/expansion/vmray_submit.py +++ b/misp_modules/modules/expansion/vmray_submit.py @@ -23,9 +23,19 @@ from _vmray.rest_api import VMRayRESTAPI misperrors = {'error': 'Error'} mispattributes = {'input': ['attachment', 'malware-sample'], 'output': ['text', 'sha1', 'sha256', 'md5', 'link']} -moduleinfo = {'version': '0.3', 'author': 'Koen Van Impe', - 'description': 'Submit a sample to VMRay', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.3', + 'author': 'Koen Van Impe', + 'description': 'Module to submit a sample to VMRay.', + 'module-type': ['expansion'], + 'name': 'VMRay Submit', + 'logo': 'vmray.png', + 'requirements': ['An access to the VMRay API (apikey & url)'], + 'features': 'This module takes an attachment or malware-sample attribute as input to query the VMRay API.\n\nThe sample contained within the attribute in then enriched with data from VMRay mapped into MISP attributes.', + 'references': ['https://www.vmray.com/'], + 'input': 'An attachment or malware-sample attribute.', + 'output': 'MISP attributes mapped from the result of the query on VMRay API, included in the following list:\n- text\n- sha1\n- sha256\n- md5\n- link', +} moduleconfig = ['apikey', 'url', 'shareable', 'do_not_reanalyze', 'do_not_include_vmrayjobids'] diff --git a/misp_modules/modules/expansion/vmware_nsx.py b/misp_modules/modules/expansion/vmware_nsx.py index 44962683..45adcbbe 100644 --- a/misp_modules/modules/expansion/vmware_nsx.py +++ b/misp_modules/modules/expansion/vmware_nsx.py @@ -43,10 +43,17 @@ mispattributes = { } moduleinfo = { - "version": "0.2", - "author": "Jason Zhang, Stefano Ortolani", - "description": "Enrich a file or URL with VMware NSX Defender", - "module-type": ["expansion", "hover"], + 'version': '0.2', + 'author': 'Jason Zhang, Stefano Ortolani', + 'description': 'Module to enrich a file or URL with VMware NSX Defender.', + 'module-type': ['expansion', 'hover'], + 'name': 'VMware NSX Defender Enrich', + 'logo': 'vmware_nsx.png', + 'requirements': ['The module requires a VMware NSX Defender Analysis `api_token` and `key`.'], + 'features': 'This module takes an IoC such as file hash, file attachment, malware-sample or url as input to query VMware NSX Defender.\n\nThe IoC is then enriched with data from VMware NSX Defender.', + 'references': ['https://www.vmware.com'], + 'input': 'File hash, attachment or URL to be enriched with VMware NSX Defender.', + 'output': 'Objects and tags generated by VMware NSX Defender.', } moduleconfig = [ diff --git a/misp_modules/modules/expansion/vulndb.py b/misp_modules/modules/expansion/vulndb.py index db6c4619..f467cafc 100644 --- a/misp_modules/modules/expansion/vulndb.py +++ b/misp_modules/modules/expansion/vulndb.py @@ -26,9 +26,19 @@ misperrors = {'error': 'Error'} mispattributes = { 'input': ['vulnerability'], 'output': ['text', 'link', 'cpe']} -moduleinfo = {'version': '0.1', 'author': 'Koen Van Impe', - 'description': 'Query VulnDB - RiskBasedSecurity.com', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Koen Van Impe', + 'description': 'Module to query VulnDB (RiskBasedSecurity.com).', + 'module-type': ['expansion', 'hover'], + 'name': 'VulnDB Lookup', + 'logo': 'vulndb.png', + 'requirements': ['An access to the VulnDB API (apikey, apisecret)'], + 'features': 'This module takes a vulnerability attribute as input and queries VulnDB in order to get some additional data about it.\n\nThe API gives the result of the query which can be displayed in the screen, and/or mapped into MISP attributes to add in the event.', + 'references': ['https://vulndb.cyberriskanalytics.com/'], + 'input': 'A vulnerability attribute.', + 'output': 'Additional data enriching the CVE input, fetched from VulnDB.', +} moduleconfig = ['apikey', 'apisecret', 'discard_dates', 'discard_external_references', 'discard_cvss', 'discard_productinformation', 'discard_classification', 'discard_cpe'] diff --git a/misp_modules/modules/expansion/vulnerability_lookup.py b/misp_modules/modules/expansion/vulnerability_lookup.py new file mode 100644 index 00000000..811b43f5 --- /dev/null +++ b/misp_modules/modules/expansion/vulnerability_lookup.py @@ -0,0 +1,324 @@ +import json +import requests +from . import check_input_attribute, standard_error_message +from ._vulnerability_parser.vulnerability_parser import ( + VulnerabilityMapping, VulnerabilityParser) +from pymisp import MISPObject +from typing import Iterator + +misperrors = {'error': 'Error'} +mispattributes = {'input': ['vulnerability'], 'format': 'misp_standard'} +moduleinfo = { + 'version': '1', + 'author': 'Christian Studer', + 'description': 'An expansion module to query Vulnerability Lookup', + 'module-type': ['expansion', 'hover'], + 'name': 'Vulnerability Lookup', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} +api_url = 'https://vulnerability.circl.lu' + + +class VulnerabilityLookupMapping(VulnerabilityMapping): + __csaf_mapping = { + 'id': 'id', + 'initial_release_date': 'published', + 'current_release_date': 'modified' + } + __cve_mapping = { + 'cveId': 'id', + 'datePublished': 'published', + 'dateUpdated': 'modified', + 'state': 'state' + } + __gsd_mapping = { + 'id': 'id', + 'details': 'description', + 'modified': 'modified' + } + __nvd_mapping = { + 'id': 'id', + 'published': 'published', + 'lastModified': 'modified' + } + __ossf_mapping = { + 'id': 'id', + 'summary': 'summary', + 'details': 'description', + 'published': 'published', + 'modified': 'modified' + } + __related_vuln_mapping = { + 'cve': 'id', + 'title': 'summary', + 'discovery_date': 'published' + } + __source_mapping = { + 'cve': '_parse_cve_description', + 'ghsa': '_parse_standard_description', + 'gsd': '_parse_gsd_description', + 'mal': '_parse_ossf_description', + 'pysec': '_parse_standard_description', + 'var': '_parse_variot_description' + } + __source_mapping.update( + dict.fromkeys( + ( + 'cisco', 'icsa', 'icsma', 'nn', 'oxas', + 'rhba', 'rhea', 'rhsa', 'sca', 'ssa', 'wid' + ), + '_parse_csaf_description' + ) + ) + __standard_mapping = { + 'id': 'id', + 'details': 'description', + 'published': 'published', + 'modified': 'modified' + } + + @classmethod + def csaf_mapping(cls) -> dict: + return cls.__csaf_mapping + + @classmethod + def cve_mapping(cls) -> dict: + return cls.__cve_mapping + + @classmethod + def gsd_mapping(cls) -> dict: + return cls.__gsd_mapping + + @classmethod + def nvd_mapping(cls) -> dict: + return cls.__nvd_mapping + + @classmethod + def ossf_mapping(cls) -> dict: + return cls.__ossf_mapping + + @classmethod + def related_vuln_mapping(cls) -> dict: + return cls.__related_vuln_mapping + + @classmethod + def source_mapping(cls, field: str) -> str: + return cls.__source_mapping.get(field) + + @classmethod + def standard_mapping(cls) -> dict: + return cls.__standard_mapping + + +class VulnerabilityLookupParser(VulnerabilityParser): + def __init__(self, attribute: dict): + super().__init__(attribute) + self.__mapping = VulnerabilityLookupMapping + self.__errors = [] + + @property + def errors(self) -> list: + return self.__errors + + @property + def mapping(self) -> VulnerabilityLookupMapping: + return self.__mapping + + def parse_lookup_result(self, lookup_result: dict): + feature = self.mapping.source_mapping( + self.misp_attribute.value.split('-')[0].lower() + ) + getattr(self, feature)(lookup_result) + + def _parse_aliases(self, aliases: list) -> Iterator[str]: + for alias in aliases: + query = requests.get(f"{api_url}/vulnerability/{alias}") + if query.status_code != 200: + self.errors.append( + f'Unable to query related vulnerability id {alias}' + ) + continue + vulnerability = query.json() + if not vulnerability: + self.errors.append( + f'No results for related vulnerability id{alias}' + ) + continue + feature = self.mapping.source_mapping(alias.split('-')[0].lower()) + yield getattr(self, feature)(vulnerability) + + def _parse_csaf_description(self, lookup_result: dict) -> str: + description = lookup_result['document'] + + tracking = description['tracking'] + misp_object = MISPObject('vulnerability') + for field, relation in self.mapping.csaf_mapping().items(): + misp_object.add_attribute(relation, tracking[field]) + misp_object.add_attribute('summary', description['title']) + for reference in description.get('references', []): + misp_object.add_attribute('references', reference['url']) + misp_object.add_attribute('credit', description['publisher']['name']) + misp_object.add_reference(self.misp_attribute.uuid, 'describes') + vulnerability_object = self.misp_event.add_object(misp_object) + + for vulnerability in lookup_result['vulnerabilities']: + related = MISPObject('vulnerability') + for field, relation in self.mapping.related_vuln_mapping().items(): + if vulnerability.get(field): + related.add_attribute(relation, vulnerability[field]) + for score in vulnerability.get('scores', []): + cvss_v3 = score['cvss_v3'] + related.add_attribute('cvss-score', cvss_v3['baseScore']) + related.add_attribute('cvss-string', cvss_v3['vectorString']) + for reference in vulnerability.get('references', []): + related.add_attribute('references', reference['url']) + related.add_reference(vulnerability_object.uuid, 'related-to') + related_vulnerability = self.misp_event.add_object(related) + if vulnerability.get('cwe'): + cwe = vulnerability['cwe'] + weakness = MISPObject('weakness') + for field, value in cwe.items(): + weakness.add_attribute(field, value) + weakness.add_reference(related_vulnerability.uuid, 'leads-to') + self.misp_event.add_object(weakness) + + return vulnerability_object.uuid + + def _parse_cve_description(self, lookup_result: dict) -> str: + misp_object = MISPObject('vulnerability') + cveMetaData = lookup_result['cveMetadata'] + for field, relation in self.mapping.cve_mapping().items(): + misp_object.add_attribute(relation, cveMetaData[field]) + for reference in lookup_result['containers']['cna']['references']: + misp_object.add_attribute('references', reference['url']) + misp_object.add_reference(self.misp_attribute.uuid, 'related-to') + vulnerability_object = self.misp_event.add_object(misp_object) + return vulnerability_object.uuid + + def _parse_cve_related_description(self, cve_description: dict) -> str: + misp_object = MISPObject('vulnerability') + misp_object.add_attribute( + 'id', cve_description['CVE_data_meta']['ID'] + ) + misp_object.add_attribute( + 'description', + cve_description['description']['description_data'][0]['value'] + ) + for cvss in cve_description.get('impact', {}).get('cvss', []): + misp_object.add_attribute('cvss-score', cvss['baseScore']) + misp_object.add_attribute('cvss-string', cvss['vectorString']) + for reference in misp_object.get('references', {}).get('reference_data', []): + misp_object.add_attribute('references', reference['url']) + return self.misp_event.add_object(misp_object).uuid + + def _parse_gsd_description(self, lookup_result: dict) -> str: + misp_object = MISPObject('vulnerability') + gsd_details = lookup_result['gsd']['osvSchema'] + for field, relation in self.mapping.gsd_mapping().items(): + misp_object.add_attribute(relation, gsd_details[field]) + misp_object.add_reference(self.misp_attribute.uuid, 'related-to') + vulnerability_object = self.misp_event.add_object(misp_object) + + for field, values in lookup_result['namespaces'].items(): + if field == 'cve.org': + vulnerability_object.add_reference( + self._parse_cve_related_description(values), 'related-to' + ) + continue + if field == 'nvd.nist.gov' and values.get('cve'): + vulnerability_object.add_reference( + self._parse_nvd_related_description(values['cve']), + 'related-to' + ) + + return vulnerability_object.uuid + + def _parse_nvd_related_description(self, nvd_description: dict) -> str: + misp_object = MISPObject('vulnerability') + for field, relation in self.mapping.nvd_mapping().items(): + misp_object.add_attribute(relation, nvd_description[field]) + misp_object.add_attribute( + 'description', nvd_description['descriptions'][0]['value'] + ) + for cvss in nvd_description.get('metrics', {}).get('cvssMetricV31', []): + misp_object.add_attribute( + 'cvss-score', cvss['cvssData']['baseScore'] + ) + misp_object.add_attribute( + 'cvss-string', cvss['cvssData']['vectorString'] + ) + for reference in nvd_description.get('references', []): + misp_object.add_attribute('references', reference['url']) + return self.misp_event.add_object(misp_object).uuid + + def _parse_ossf_description(self, lookup_result: dict) -> str: + misp_object = MISPObject('vulnerability') + for field, relation in self.mapping.ossf_mapping().items(): + misp_object.add_attribute(relation, lookup_result[field]) + for reference in lookup_result['references']: + misp_object.add_attribute('references', reference['url']) + misp_object.add_reference(self.misp_attribute.uuid, 'related-to') + vulnerability_object = self.misp_event.add_object(misp_object) + + if lookup_result.get('aliases'): + for vuln_uuid in self._parse_aliases(lookup_result['aliases']): + vulnerability_object.add_reference(vuln_uuid, 'related-to') + + return vulnerability_object.uuid + + def _parse_standard_description(self, lookup_result: dict) -> str: + misp_object = MISPObject('vulnerability') + for field, relation in self.mapping.standard_mapping().items(): + misp_object.add_attribute(relation, lookup_result[field]) + for cvss in lookup_result.get('severity', []): + misp_object.add_attribute('cvss-string', cvss['score']) + for reference in lookup_result['references']: + misp_object.add_attribute('references', reference['url']) + misp_object.add_reference(self.misp_attribute.uuid, 'related-to') + vulnerability_object = self.misp_event.add_object(misp_object) + + if lookup_result.get('aliases'): + for vuln_uuid in self._parse_aliases(lookup_result['aliases']): + vulnerability_object.add_reference(vuln_uuid, 'related-to') + + return vulnerability_object.uuid + + +def handler(q=False): + if q is False: + return q + request = json.loads(q) + if not check_input_attribute(request.get('attribute', {})): + return { + 'error': f'{standard_error_message}, which should contain ' + 'at least a type, a value and an UUID.' + } + attribute = request['attribute'] + if attribute.get('type') != 'vulnerability': + misperrors['error'] = 'Vulnerability ID missing' + return misperrors + lookup = requests.get(f"{api_url}/vulnerability/{attribute['value']}") + if lookup.status_code == 200: + vulnerability = lookup.json() + if not vulnerability: + misperrors['error'] = 'Non existing Vulnerability ID.' + return misperrors + else: + misperrors['error'] = 'Vulnerability Lookup API not accessible.' + return misperrors + parser = VulnerabilityLookupParser(attribute) + parser.parse_lookup_result(vulnerability) + return parser.get_results() + + +def introspection(): + return mispattributes + + +def version(): + return moduleinfo diff --git a/misp_modules/modules/expansion/vulners.py b/misp_modules/modules/expansion/vulners.py index 1b8cdcc3..5c10575d 100644 --- a/misp_modules/modules/expansion/vulners.py +++ b/misp_modules/modules/expansion/vulners.py @@ -3,7 +3,19 @@ import vulners misperrors = {'error': 'Error'} mispattributes = {'input': ['vulnerability'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Igor Ivanov', 'description': 'An expansion hover module to expand information about CVE id using Vulners API.', 'module-type': ['hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Igor Ivanov', + 'description': 'An expansion hover module to expand information about CVE id using Vulners API.', + 'module-type': ['hover'], + 'name': 'Vulners Lookup', + 'logo': 'vulners.png', + 'requirements': ['Vulners python library', 'An access to the Vulners API'], + 'features': 'This module takes a vulnerability attribute as input and queries the Vulners API in order to get some additional data about it.\n\nThe API then returns details about the vulnerability.', + 'references': ['https://vulners.com/'], + 'input': 'A vulnerability attribute.', + 'output': 'Text giving additional information about the CVE in input.', +} # Get API key from https://vulners.com/userinfo moduleconfig = ["apikey"] diff --git a/misp_modules/modules/expansion/vysion.py b/misp_modules/modules/expansion/vysion.py index bf1a6a15..35fc56cc 100644 --- a/misp_modules/modules/expansion/vysion.py +++ b/misp_modules/modules/expansion/vysion.py @@ -8,6 +8,7 @@ import vysion.client as vysion import vysion.dto as dto from vysion.dto.util import MISPProcessor +from . import standard_error_message misperrors = {"error": "Error"} mispattributes = { @@ -20,16 +21,25 @@ mispattributes = { "btc", "phone-number", "target-org", + "xmr", + "dash", ], "format": "misp_standard", } # possible module-types: 'expansion', 'hover' or both moduleinfo = { - "version": "1", - "author": "Byron Labs", - "description": "Enrich observables with the Vysion API", - "module-type": ["expansion"], + 'version': '1', + 'author': 'Byron Labs', + 'description': 'Module to enrich the information by making use of the Vysion API.', + 'module-type': ['expansion'], + 'name': 'Vysion Enrich', + 'logo': 'vysion.png', + 'requirements': ['Vysion python library', 'Vysion API Key'], + 'features': "This module gets correlated information from Byron Labs' dark web intelligence database. With this you will get several objects containing information related to, for example, an organization victim of a ransomware attack.", + 'references': ['https://vysion.ai/', 'https://developers.vysion.ai/', 'https://github.com/ByronLabs/vysion-cti/tree/main'], + 'input': 'company(target-org), country, info, BTC, XMR and DASH address.', + 'output': 'MISP objects containing title, link to our webapp and TOR, i2p or clearnet URLs.', } # config fields that your code expects from the site admin @@ -44,7 +54,7 @@ moduleconfig = [ LOGGER = logging.getLogger("vysion") LOGGER.setLevel(logging.INFO) -LOGGER.info("Starting Vysion") +LOGGER.debug("Starting Vysion") DEFAULT_RESULTS_LIMIT = 10 @@ -114,7 +124,7 @@ def handler(q=False): if not request.get("attribute"): return { - "error": "The request is missing required attribute information, which should contain at least a type, a value, and a UUID." + "error": f"{standard_error_message}, which should contain at least a type, a value and an uuid." } if request["attribute"]["type"] not in mispattributes["input"]: @@ -151,25 +161,24 @@ def handler(q=False): if attribute_type == "email": result = client.find_email(attribute_value) elif attribute_type == "domain": - result = client.search(attribute_value) + result = client.find_url(attribute_value) elif attribute_type == "url": - result = client.search( - attribute_value - ) # TODO result = client.find_url(attribute_value) + result = client.find_url(attribute_value) elif attribute_type == "text": result = client.search(attribute_value) elif attribute_type == "target-org": - result = client.search(attribute_value, exact=True) - elif attribute_type == "btc": - result = client.search(attribute_value) # TODO + result = client.search(attribute_value) elif attribute_type == "phone-number": - result = client.search(attribute_value) # TODO + result = client.search(attribute_value) + elif attribute_type == "btc": + result = client.find_wallet("BTC",attribute_value) + elif attribute_type == "xmr": + result = client.find_wallet("XMR",attribute_value) + elif attribute_type == "dash": + result = client.find_wallet("DASH",attribute_value) if result is None: return {"results": {}} - elif isinstance(result, dto.VysionError): - LOGGER.error(str(result)) - return {"results": {}} p = MISPProcessor() misp_event: MISPEvent = p.process(result, ref_attribute=misp_attribute) @@ -186,7 +195,7 @@ def handler(q=False): "Attribute": [ json.loads(attribute.to_json()) for attribute in misp_event.attributes - ], + ], "Tag": [ json.loads(tag.to_json()) for tag in misp_event.tags diff --git a/misp_modules/modules/expansion/whois.py b/misp_modules/modules/expansion/whois.py old mode 100755 new mode 100644 index 22c4850b..acec4aef --- a/misp_modules/modules/expansion/whois.py +++ b/misp_modules/modules/expansion/whois.py @@ -1,16 +1,23 @@ # -*- coding: utf-8 -*- import json -try: - from uwhois import Uwhois -except ImportError: - print("uwhois module not installed.") +import socket misperrors = {'error': 'Error'} mispattributes = {'input': ['domain', 'ip-src', 'ip-dst'], 'output': ['freetext']} -moduleinfo = {'version': '0.1', 'author': 'Raphaël Vinot', - 'description': 'Query a local instance of uwhois (https://github.com/rafiot/uwhoisd)', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Raphaël Vinot', + 'description': 'Module to query a local instance of uwhois (https://github.com/rafiot/uwhoisd).', + 'module-type': ['expansion'], + 'name': 'Whois Lookup', + 'logo': '', + 'requirements': ['uwhois: A whois python library'], + 'features': "This module takes a domain or IP address attribute as input and queries a 'Univseral Whois proxy server' to get the correct details of the Whois query on the input value (check the references for more details about this whois server).", + 'references': ['https://github.com/Lookyloo/uwhoisd'], + 'input': 'A domain or IP address attribute.', + 'output': 'Text describing the result of a whois request for the input value.', +} moduleconfig = ['server', 'port'] @@ -29,18 +36,31 @@ def handler(q=False): misperrors['error'] = "Unsupported attributes type" return misperrors - if not request.get('config') or (not request['config'].get('server') and not request['config'].get('port')): + if not request.get('config') or ( + not request['config'].get('server') and not request['config'].get('port') + ): misperrors['error'] = 'Whois local instance address is missing' return misperrors - uwhois = Uwhois(request['config']['server'], int(request['config']['port'])) - if 'event_id' in request: - return handle_expansion(uwhois, toquery) + return handle_expansion( + request['config']['server'], int(request['config']['port']), toquery + ) -def handle_expansion(w, domain): - return {'results': [{'types': mispattributes['output'], 'values': w.query(domain)}]} +def handle_expansion(server, port, query): + bytes_whois = b'' + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.connect((server, port)) + sock.sendall(f'{query}\n'.encode()) + while True: + data = sock.recv(2048) + if not data: + break + bytes_whois += data + return { + 'results': [{'types': mispattributes['output'], 'values': bytes_whois.decode()}] + } def introspection(): diff --git a/misp_modules/modules/expansion/whoisfreaks.py b/misp_modules/modules/expansion/whoisfreaks.py index 5ea52570..d64e2194 100644 --- a/misp_modules/modules/expansion/whoisfreaks.py +++ b/misp_modules/modules/expansion/whoisfreaks.py @@ -10,9 +10,19 @@ mispattributes = { 'whois-registrant-name', 'whois-registrar', 'whois-creation-date', 'domain'] } -moduleinfo = {'version': '1', 'author': 'WhoisFreaks', - 'description': 'Query on whoisfreaks.com', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '1', + 'author': 'WhoisFreaks', + 'description': 'An expansion module for https://whoisfreaks.com/ that will provide an enriched analysis of the provided domain, including WHOIS and DNS information.', + 'module-type': ['expansion', 'hover'], + 'name': 'WhoisFreaks Lookup', + 'logo': 'whoisfreaks.png', + 'requirements': ['An access to the Whoisfreaks API_KEY'], + 'features': 'The module takes a domain as input and queries the Whoisfreaks API with it.\n\nSome parsing operations are then processed on the result of the query to extract as much information as possible.\n\nAfter this we map the extracted data to MISP attributes.', + 'references': ['https://whoisfreaks.com/'], + 'input': 'A domain whose Data is required', + 'output': 'MISP attributes resulting from the query on Whoisfreaks API, included in the following list:\n- domain\n- dns-soa-email\n- whois-registrant-email\n- whois-registrant-phone\n- whois-registrant-name\n- whois-registrar\n- whois-creation-date\n- domain', +} # config fields that your code expects from the site admin moduleconfig = ['apikey'] @@ -50,7 +60,7 @@ def handle_domain(apiKey, domain, errors): if status_ok: if r: result_filtered['results'].extend(r) - + return result_filtered @@ -156,7 +166,7 @@ def expand_dns(apiKey, domain): servers_mx.append(record['target']) elif record['dnsType'] == 'SOA': soa_hostnames.append(record['host']) - + if list_ipv4: r.append({'types': ['domain|ip'], 'values': ['%s|%s' % (domain, ipv4) for ipv4 in diff --git a/misp_modules/modules/expansion/wiki.py b/misp_modules/modules/expansion/wiki.py index 110e8f8e..ebbf8228 100755 --- a/misp_modules/modules/expansion/wiki.py +++ b/misp_modules/modules/expansion/wiki.py @@ -3,7 +3,19 @@ from SPARQLWrapper import SPARQLWrapper, JSON misperrors = {'error': 'Error'} mispattributes = {'input': ['text'], 'output': ['text']} -moduleinfo = {'version': '0.2', 'author': 'Roman Graf', 'description': 'An expansion hover module to extract information from Wikidata to have additional information about particular term for analysis.', 'module-type': ['hover']} +moduleinfo = { + 'version': '0.2', + 'author': 'Roman Graf', + 'description': 'An expansion hover module to extract information from Wikidata to have additional information about particular term for analysis.', + 'module-type': ['hover'], + 'name': 'Wikidata Lookup', + 'logo': 'wikidata.png', + 'requirements': ['SPARQLWrapper python library'], + 'features': 'This module takes a text attribute as input and queries the Wikidata API. If the text attribute is clear enough to define a specific term, the API returns a wikidata link in response.', + 'references': ['https://www.wikidata.org'], + 'input': 'Text attribute.', + 'output': 'Text attribute.', +} moduleconfig = [] # sample query text 'Microsoft' should provide Wikidata link https://www.wikidata.org/wiki/Q2283 in response wiki_api_url = 'https://query.wikidata.org/bigdata/namespace/wdq/sparql' diff --git a/misp_modules/modules/expansion/xforceexchange.py b/misp_modules/modules/expansion/xforceexchange.py index 936917fb..865e72f7 100644 --- a/misp_modules/modules/expansion/xforceexchange.py +++ b/misp_modules/modules/expansion/xforceexchange.py @@ -14,9 +14,19 @@ mispattributes = {'input': ['ip-src', 'ip-dst', 'vulnerability', 'md5', 'sha1', 'format': 'misp_standard'} # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '2', 'author': 'Joerg Stephan (@johest)', - 'description': 'IBM X-Force Exchange expansion module', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '2', + 'author': 'Joerg Stephan (@johest)', + 'description': 'An expansion module for IBM X-Force Exchange.', + 'module-type': ['expansion', 'hover'], + 'name': 'IBM X-Force Exchange Lookup', + 'logo': 'xforce.png', + 'requirements': ['An access to the X-Force API (apikey)'], + 'features': 'This module takes a MISP attribute as input to query the X-Force API. The API returns then additional information known in their threats data, that is mapped into MISP attributes.', + 'references': ['https://exchange.xforce.ibmcloud.com/'], + 'input': 'A MISP attribute included in the following list:\n- ip-src\n- ip-dst\n- vulnerability\n- md5\n- sha1\n- sha256', + 'output': 'MISP attributes mapped from the result of the query on X-Force Exchange.', +} # config fields that your code expects from the site admin moduleconfig = ["apikey", "apipassword"] diff --git a/misp_modules/modules/expansion/xlsx_enrich.py b/misp_modules/modules/expansion/xlsx_enrich.py index 6e0ee739..3d71beeb 100644 --- a/misp_modules/modules/expansion/xlsx_enrich.py +++ b/misp_modules/modules/expansion/xlsx_enrich.py @@ -7,9 +7,19 @@ import io misperrors = {'error': 'Error'} mispattributes = {'input': ['attachment'], 'output': ['freetext', 'text']} -moduleinfo = {'version': '0.1', 'author': 'Sascha Rommelfangen', - 'description': '.xlsx to freetext-import IOC extractor', - 'module-type': ['expansion']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sascha Rommelfangen', + 'description': 'Module to extract freetext from a .xlsx document.', + 'module-type': ['expansion'], + 'name': 'XLXS Enrich', + 'logo': 'xlsx.png', + 'requirements': ['pandas: Python library to perform data analysis, time series and statistics.'], + 'features': 'The module reads the text contained in a .xlsx document. The result is passed to the freetext import parser so IoCs can be extracted out of it.', + 'references': [], + 'input': 'Attachment attribute containing a .xlsx document.', + 'output': 'Text and freetext parsed from the document.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/yara_query.py b/misp_modules/modules/expansion/yara_query.py index e905de50..1851d68b 100644 --- a/misp_modules/modules/expansion/yara_query.py +++ b/misp_modules/modules/expansion/yara_query.py @@ -6,10 +6,20 @@ except (OSError, ImportError): print("yara is missing, use 'pip3 install -I -r REQUIREMENTS' from the root of this repository to install it.") misperrors = {'error': 'Error'} -moduleinfo = {'version': '1', 'author': 'Christian STUDER', - 'description': 'Yara export for hashes.', - 'module-type': ['expansion', 'hover'], - 'require_standard_format': True} +moduleinfo = { + 'version': '1', + 'author': 'Christian STUDER', + 'description': 'jj', + 'module-type': ['expansion', 'hover'], + 'name': 'YARA Rule Generator', + 'require_standard_format': True, + 'logo': 'yara.png', + 'requirements': ['yara-python python library'], + 'features': "The module takes a hash attribute (md5, sha1, sha256, imphash) as input, and is returning a YARA rule from it. This YARA rule is also validated using the same method as in 'yara_syntax_validator' module.\nBoth hover and expansion functionalities are supported with this module, where the hover part is displaying the resulting YARA rule and the expansion part allows you to add the rule as a new attribute, as usual with expansion modules.", + 'references': ['https://virustotal.github.io/yara/', 'https://github.com/virustotal/yara-python'], + 'input': 'MISP Hash attribute (md5, sha1, sha256, imphash, or any of the composite attribute with filename and one of the previous hash type).', + 'output': 'YARA rule.', +} moduleconfig = [] mispattributes = {'input': ['md5', 'sha1', 'sha256', 'filename|md5', 'filename|sha1', 'filename|sha256', 'imphash'], 'output': ['yara']} diff --git a/misp_modules/modules/expansion/yara_syntax_validator.py b/misp_modules/modules/expansion/yara_syntax_validator.py index cad533fc..ce2b1366 100644 --- a/misp_modules/modules/expansion/yara_syntax_validator.py +++ b/misp_modules/modules/expansion/yara_syntax_validator.py @@ -6,7 +6,19 @@ except (OSError, ImportError): misperrors = {'error': 'Error'} mispattributes = {'input': ['yara'], 'output': ['text']} -moduleinfo = {'version': '0.1', 'author': 'Dennis Rand', 'description': 'An expansion hover module to perform a syntax check on if yara rules are valid or not.', 'module-type': ['hover']} +moduleinfo = { + 'version': '0.1', + 'author': 'Dennis Rand', + 'description': 'An expansion hover module to perform a syntax check on if yara rules are valid or not.', + 'module-type': ['hover'], + 'name': 'YARA Syntax Validator', + 'logo': 'yara.png', + 'requirements': ['yara_python python library'], + 'features': 'This modules simply takes a YARA rule as input, and checks its syntax. It returns then a confirmation if the syntax is valid, otherwise the syntax error is displayed.', + 'references': ['http://virustotal.github.io/yara/'], + 'input': 'YARA rule attribute.', + 'output': 'Text to inform users if their rule is valid.', +} moduleconfig = [] diff --git a/misp_modules/modules/expansion/yeti.py b/misp_modules/modules/expansion/yeti.py index 3eeea958..5bee5c96 100644 --- a/misp_modules/modules/expansion/yeti.py +++ b/misp_modules/modules/expansion/yeti.py @@ -14,9 +14,19 @@ mispattributes = {'input': ['AS', 'ip-src', 'ip-dst', 'hostname', 'domain', 'sha 'format': 'misp_standard' } # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '1', 'author': 'Sebastien Larinier @sebdraven', - 'description': 'Query on yeti', - 'module-type': ['expansion', 'hover']} +moduleinfo = { + 'version': '1', + 'author': 'Sebastien Larinier @sebdraven', + 'description': 'Module to process a query on Yeti.', + 'module-type': ['expansion', 'hover'], + 'name': 'Yeti Lookup', + 'logo': 'yeti.png', + 'requirements': ['pyeti', 'API key '], + 'features': 'This module add context and links between observables using yeti', + 'references': ['https://github.com/yeti-platform/yeti', 'https://github.com/sebdraven/pyeti'], + 'input': 'A domain, hostname,IP, sha256,sha1, md5, url of MISP attribute.', + 'output': 'MISP attributes and objects fetched from the Yeti instances.', +} moduleconfig = ['apikey', 'url'] diff --git a/misp_modules/modules/export_mod/__init__.py b/misp_modules/modules/export_mod/__init__.py index ea90d197..d865527d 100644 --- a/misp_modules/modules/export_mod/__init__.py +++ b/misp_modules/modules/export_mod/__init__.py @@ -1,3 +1,3 @@ __all__ = ['cef_export', 'mass_eql_export', 'liteexport', 'goamlexport', 'threat_connect_export', 'pdfexport', 'threatStream_misp_export', 'osqueryexport', 'nexthinkexport', 'vt_graph', 'defender_endpoint_export', - 'virustotal_collections'] + 'virustotal_collections', 'yara_export', 'cisco_firesight_manager_ACL_rule_export'] diff --git a/misp_modules/modules/export_mod/cef_export.py b/misp_modules/modules/export_mod/cef_export.py index 0aa82f03..2e57e773 100755 --- a/misp_modules/modules/export_mod/cef_export.py +++ b/misp_modules/modules/export_mod/cef_export.py @@ -5,9 +5,19 @@ import datetime misperrors = {'error': 'Error'} # possible module-types: 'expansion', 'hover' or both -moduleinfo = {'version': '1', 'author': 'Hannah Ward', - 'description': 'Export a module in CEF format', - 'module-type': ['export']} +moduleinfo = { + 'version': '1', + 'author': 'Hannah Ward', + 'description': 'Module to export a MISP event in CEF format.', + 'module-type': ['export'], + 'name': 'CEF Export', + 'logo': '', + 'requirements': [], + 'features': 'The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in Common Event Format.\nThus, there is no particular feature concerning MISP Events since any event can be exported. However, 4 configuration parameters recognized by CEF format are required and should be provided by users before exporting data: the device vendor, product and version, as well as the default severity of data.', + 'references': ['https://community.softwaregrp.com/t5/ArcSight-Connectors/ArcSight-Common-Event-Format-CEF-Guide/ta-p/1589306?attachment-id=65537'], + 'input': 'MISP Event attributes', + 'output': 'Common Event Format file', +} # config fields that your code expects from the site admin moduleconfig = ["Default_Severity", "Device_Vendor", "Device_Product", "Device_Version"] diff --git a/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py b/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py index ab79692d..fcc7e4da 100644 --- a/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py +++ b/misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py @@ -15,9 +15,19 @@ from urllib.parse import quote misperrors = {'error': 'Error'} -moduleinfo = {'version': '1', 'author': 'Stanislav Klevtsov', - 'description': 'Export malicious network activity attributes of the MISP event to Cisco firesight manager block rules', - 'module-type': ['export']} +moduleinfo = { + 'version': '1', + 'author': 'Stanislav Klevtsov', + 'description': 'Module to export malicious network activity attributes to Cisco fireSIGHT manager block rules.', + 'module-type': ['export'], + 'name': 'Cisco fireSIGHT blockrule Export', + 'logo': 'cisco.png', + 'requirements': ['Firesight manager console credentials'], + 'features': 'The module goes through the attributes to find all the network activity ones in order to create block rules for the Cisco fireSIGHT manager.', + 'references': [], + 'input': 'Network activity attributes (IPs, URLs).', + 'output': 'Cisco fireSIGHT manager block rules.', +} moduleconfig = ['fmc_ip_addr', 'fmc_login', 'fmc_pass', 'domain_id', 'acpolicy_id'] diff --git a/misp_modules/modules/export_mod/defender_endpoint_export.py b/misp_modules/modules/export_mod/defender_endpoint_export.py index 2a5d39a8..c283cb43 100755 --- a/misp_modules/modules/export_mod/defender_endpoint_export.py +++ b/misp_modules/modules/export_mod/defender_endpoint_export.py @@ -1,131 +1,141 @@ -""" -Export module for coverting MISP events into Defender for Endpoint KQL queries. -Config['Period'] : allows to define period over witch to look for IOC from now -""" - -import base64 -import json - -misperrors = {"error": "Error"} - -types_to_use = ['sha256', 'sha1', 'md5', 'domain', 'ip-src', 'ip-dst', 'url'] - -userConfig = { - -} - -moduleconfig = ["Period"] -inputSource = ['event'] - -outputFileExtension = 'kql' -responseType = 'application/txt' - -moduleinfo = {'version': '1.1', 'author': 'Julien Bachmann, Hacknowledge, Maik Wuerth', - 'description': 'Defender for Endpoint KQL hunting query export module', - 'module-type': ['export']} - - -def handle_sha256(value, period): - query = f"""find in (DeviceEvents, DeviceAlertEvents,AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents) - where (SHA256 == '{value}' or InitiatingProcessSHA1 == '{value}') and - Timestamp between(ago({period}) .. now())""" - return query.replace('\n', ' ') - - -def handle_sha1(value, period): - query = f"""find in (DeviceEvents, DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents) - where (SHA1 == '{value}' or InitiatingProcessSHA1 == '{value}') and - Timestamp between(ago({period}) .. now())""" - return query.replace('\n', ' ') - - -def handle_md5(value, period): - query = f"""find in (DeviceEvents, DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents) - where (MD5 == '{value}' or InitiatingProcessMD5 == '{value}') and - Timestamp between(ago({period}) .. now())""" - return query.replace('\n', ' ') - - -def handle_domain(value, period): - query = f"""find in (DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceNetworkEvents) - where RemoteUrl contains '{value}' and - Timestamp between(ago({period}) .. now())""" - return query.replace('\n', ' ') - - -def handle_ip(value, period): - query = f"""find in (DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceNetworkEvents) - where RemoteIP == '{value}' and - Timestamp between(ago({period}) .. now())""" - return query.replace('\n', ' ') - - -def handle_url(value, period): - query = f"""let url = '{value}'; - search in (EmailUrlInfo,UrlClickEvents,DeviceNetworkEvents,DeviceFileEvents,DeviceEvents,BehaviorEntities, AlertInfo, AlertEvidence, DeviceAlertEvents) - Timestamp between(ago({period}) .. now()) and - RemoteUrl has url - or FileOriginUrl has url - or FileOriginReferrerUrl has url - or Url has url""" - return query.replace('\n', ' ') - - -handlers = { - 'sha256': handle_sha256, - 'sha1': handle_sha1, - 'md5': handle_md5, - 'domain': handle_url, - 'ip-src': handle_ip, - 'ip-dst': handle_ip, - 'url': handle_url -} - - -def handler(q=False): - if q is False: - return False - request = json.loads(q) - config = request.get("config", {"Period": ""}) - output = '' - - for event in request["data"]: - for attribute in event["Attribute"]: - if attribute['type'] in types_to_use: - output = output + handlers[attribute['type']](attribute['value'], config['Period']) + '\n' - for obj in event["Object"]: - for attribute in obj["Attribute"]: - if attribute['type'] in types_to_use: - output = output + handlers[attribute['type']](attribute['value'], config['Period']) + '\n' - r = {"response": [], "data": str(base64.b64encode(bytes(output, 'utf-8')), 'utf-8')} - return r - - -def introspection(): - modulesetup = {} - try: - responseType - modulesetup['responseType'] = responseType - except NameError: - pass - try: - userConfig - modulesetup['userConfig'] = userConfig - except NameError: - pass - try: - outputFileExtension - modulesetup['outputFileExtension'] = outputFileExtension - except NameError: - pass - try: - inputSource - modulesetup['inputSource'] = inputSource - except NameError: - pass - return modulesetup - - -def version(): - moduleinfo['config'] = moduleconfig - return moduleinfo +""" +Export module for coverting MISP events into Defender for Endpoint KQL queries. +Config['Period'] : allows to define period over witch to look for IOC from now +""" + +import base64 +import json + +misperrors = {"error": "Error"} + +types_to_use = ['sha256', 'sha1', 'md5', 'domain', 'ip-src', 'ip-dst', 'url'] + +userConfig = { + +} + +moduleconfig = ["Period"] +inputSource = ['event'] + +outputFileExtension = 'kql' +responseType = 'application/txt' + +moduleinfo = { + 'version': '1.1', + 'author': 'Julien Bachmann, Hacknowledge, Maik Wuerth', + 'description': 'Defender for Endpoint KQL hunting query export module', + 'module-type': ['export'], + 'name': 'Microsoft Defender for Endpoint KQL Export', + 'logo': 'defender_endpoint.png', + 'requirements': [], + 'features': 'This module export an event as Defender for Endpoint KQL queries that can then be used in your own python3 or Powershell tool. If you are using Microsoft Sentinel, you can directly connect your MISP instance to Sentinel and then create queries using the `ThreatIntelligenceIndicator` table to match events against imported IOC.', + 'references': ['https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/advanced-hunting-schema-reference'], + 'input': 'MISP Event attributes', + 'output': 'Defender for Endpoint KQL queries', +} + + +def handle_sha256(value, period): + query = f"""find in (DeviceEvents, DeviceAlertEvents,AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents) + where (SHA256 == '{value}' or InitiatingProcessSHA1 == '{value}') and + Timestamp between(ago({period}) .. now())""" + return query.replace('\n', ' ') + + +def handle_sha1(value, period): + query = f"""find in (DeviceEvents, DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents) + where (SHA1 == '{value}' or InitiatingProcessSHA1 == '{value}') and + Timestamp between(ago({period}) .. now())""" + return query.replace('\n', ' ') + + +def handle_md5(value, period): + query = f"""find in (DeviceEvents, DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceFileEvents, DeviceImageLoadEvents, DeviceProcessEvents) + where (MD5 == '{value}' or InitiatingProcessMD5 == '{value}') and + Timestamp between(ago({period}) .. now())""" + return query.replace('\n', ' ') + + +def handle_domain(value, period): + query = f"""find in (DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceNetworkEvents) + where RemoteUrl contains '{value}' and + Timestamp between(ago({period}) .. now())""" + return query.replace('\n', ' ') + + +def handle_ip(value, period): + query = f"""find in (DeviceAlertEvents, AlertInfo, AlertEvidence, DeviceNetworkEvents) + where RemoteIP == '{value}' and + Timestamp between(ago({period}) .. now())""" + return query.replace('\n', ' ') + + +def handle_url(value, period): + query = f"""let url = '{value}'; + search in (EmailUrlInfo,UrlClickEvents,DeviceNetworkEvents,DeviceFileEvents,DeviceEvents,BehaviorEntities, AlertInfo, AlertEvidence, DeviceAlertEvents) + Timestamp between(ago({period}) .. now()) and + RemoteUrl has url + or FileOriginUrl has url + or FileOriginReferrerUrl has url + or Url has url""" + return query.replace('\n', ' ') + + +handlers = { + 'sha256': handle_sha256, + 'sha1': handle_sha1, + 'md5': handle_md5, + 'domain': handle_url, + 'ip-src': handle_ip, + 'ip-dst': handle_ip, + 'url': handle_url +} + + +def handler(q=False): + if q is False: + return False + request = json.loads(q) + config = request.get("config", {"Period": ""}) + output = '' + + for event in request["data"]: + for attribute in event["Attribute"]: + if attribute['type'] in types_to_use: + output = output + handlers[attribute['type']](attribute['value'], config['Period']) + '\n' + for obj in event["Object"]: + for attribute in obj["Attribute"]: + if attribute['type'] in types_to_use: + output = output + handlers[attribute['type']](attribute['value'], config['Period']) + '\n' + r = {"response": [], "data": str(base64.b64encode(bytes(output, 'utf-8')), 'utf-8')} + return r + + +def introspection(): + modulesetup = {} + try: + responseType + modulesetup['responseType'] = responseType + except NameError: + pass + try: + userConfig + modulesetup['userConfig'] = userConfig + except NameError: + pass + try: + outputFileExtension + modulesetup['outputFileExtension'] = outputFileExtension + except NameError: + pass + try: + inputSource + modulesetup['inputSource'] = inputSource + except NameError: + pass + return modulesetup + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo diff --git a/misp_modules/modules/export_mod/goamlexport.py b/misp_modules/modules/export_mod/goamlexport.py index b9ce086f..a1ffaf91 100644 --- a/misp_modules/modules/export_mod/goamlexport.py +++ b/misp_modules/modules/export_mod/goamlexport.py @@ -4,10 +4,20 @@ from pymisp import MISPEvent from collections import defaultdict, Counter misperrors = {'error': 'Error'} -moduleinfo = {'version': '1', 'author': 'Christian Studer', - 'description': 'Export to GoAML', - 'module-type': ['export'], - 'require_standard_format': True} +moduleinfo = { + 'version': '1', + 'author': 'Christian Studer', + 'description': 'This module is used to export MISP events containing transaction objects into GoAML format.', + 'module-type': ['export'], + 'name': 'GoAML Export', + 'require_standard_format': True, + 'logo': 'goAML.jpg', + 'requirements': ['PyMISP', 'MISP objects'], + 'features': "The module works as long as there is at least one transaction object in the Event.\n\nThen in order to have a valid GoAML document, please follow these guidelines:\n- For each transaction object, use either a bank-account, person, or legal-entity object to describe the origin of the transaction, and again one of them to describe the target of the transaction.\n- Create an object reference for both origin and target objects of the transaction.\n- A bank-account object needs a signatory, which is a person object, put as object reference of the bank-account.\n- A person can have an address, which is a geolocation object, put as object reference of the person.\n\nSupported relation types for object references that are recommended for each object are the folowing:\n- transaction:\n\t- 'from', 'from_my_client': Origin of the transaction - at least one of them is required.\n\t- 'to', 'to_my_client': Target of the transaction - at least one of them is required.\n\t- 'address': Location of the transaction - optional.\n- bank-account:\n\t- 'signatory': Signatory of a bank-account - the reference from bank-account to a signatory is required, but the relation-type is optional at the moment since this reference will always describe a signatory.\n\t- 'entity': Entity owning the bank account - optional.\n- person:\n\t- 'address': Address of a person - optional.", + 'references': ['http://goaml.unodc.org/'], + 'input': 'MISP objects (transaction, bank-account, person, legal-entity, geolocation), with references, describing financial transactions and their origin and target.', + 'output': 'GoAML format file, describing financial transactions, with their origin and target (bank accounts, persons or entities).', +} moduleconfig = ['rentity_id'] mispattributes = {'input': ['MISPEvent'], 'output': ['xml file']} outputFileExtension = "xml" diff --git a/misp_modules/modules/export_mod/liteexport.py b/misp_modules/modules/export_mod/liteexport.py index 870f52a2..d980c9f9 100755 --- a/misp_modules/modules/export_mod/liteexport.py +++ b/misp_modules/modules/export_mod/liteexport.py @@ -3,10 +3,19 @@ import base64 misperrors = {'error': 'Error'} -moduleinfo = {'version': '1', - 'author': 'TM', - 'description': 'export lite', - 'module-type': ['export']} +moduleinfo = { + 'version': '1', + 'author': 'TM', + 'description': 'Lite export of a MISP event.', + 'module-type': ['export'], + 'name': 'Lite Export', + 'logo': '', + 'requirements': [], + 'features': 'This module is simply producing a json MISP event format file, but exporting only Attributes from the Event. Thus, MISP Events exported with this module should have attributes that are not internal references, otherwise the resulting event would be empty.', + 'references': [], + 'input': 'MISP Event attributes', + 'output': 'Lite MISP Event', +} moduleconfig = ["indent_json_export"] diff --git a/misp_modules/modules/export_mod/mass_eql_export.py b/misp_modules/modules/export_mod/mass_eql_export.py index f42874d4..d6ed1ea3 100644 --- a/misp_modules/modules/export_mod/mass_eql_export.py +++ b/misp_modules/modules/export_mod/mass_eql_export.py @@ -9,10 +9,17 @@ import logging misperrors = {"error": "Error"} moduleinfo = { - "version": "0.1", - "author": "92 COS DOM", - "description": "Export MISP event in Event Query Language", - "module-type": ["export"] + 'version': '0.1', + 'author': '92 COS DOM', + 'description': 'Export MISP event in Event Query Language', + 'module-type': ['export'], + 'name': 'EQL Query Export', + 'logo': 'eql.png', + 'requirements': [], + 'features': 'This module produces EQL queries for all relevant attributes in a MISP event.', + 'references': ['https://eql.readthedocs.io/en/latest/'], + 'input': 'MISP Event attributes', + 'output': 'Text file containing one or more EQL queries', } # Map of MISP fields => Endgame fields diff --git a/misp_modules/modules/export_mod/nexthinkexport.py b/misp_modules/modules/export_mod/nexthinkexport.py index c87b3fbc..f0c7f3e7 100755 --- a/misp_modules/modules/export_mod/nexthinkexport.py +++ b/misp_modules/modules/export_mod/nexthinkexport.py @@ -1,121 +1,131 @@ -""" -Export module for coverting MISP events into Nexthink NXQL queries. -Source: https://github.com/HacknowledgeCH/misp-modules/blob/master/misp_modules/modules/export_mod/nexthinkexport.py -Config['Period'] : allows to define period over witch to look for IOC from now (15m, 1d, 2w, 30d, ...), see Nexthink data model documentation -""" - -import base64 -import json - -misperrors = {"error": "Error"} - -types_to_use = ['sha1', 'sha256', 'md5', 'domain'] - -userConfig = { - -} - -moduleconfig = ["Period"] -inputSource = ['event'] - -outputFileExtension = 'nxql' -responseType = 'application/txt' - -moduleinfo = {'version': '1.0', 'author': 'Julien Bachmann, Hacknowledge', - 'description': 'Nexthink NXQL query export module', - 'module-type': ['export']} - - -def handle_sha1(value, period): - query = '''select ((binary (executable_name version)) (user (name)) (device (name last_ip_address)) (execution (binary_path start_time))) -(from (binary user device execution) -(where binary (eq sha1 (sha1 %s))) -(between now-%s now)) -(limit 1000) - ''' % (value, period) - return query.replace('\n', ' ') - - -def handle_sha256(value, period): - query = '''select ((binary (executable_name version)) (user (name)) (device (name last_ip_address)) (execution (binary_path start_time))) -(from (binary user device execution) -(where binary (eq sha256 (sha256 %s))) -(between now-%s now)) -(limit 1000) - ''' % (value, period) - return query.replace('\n', ' ') - - -def handle_md5(value, period): - query = '''select ((binary (executable_name version)) (user (name)) (device (name last_ip_address)) (execution (binary_path start_time))) -(from (binary user device execution) -(where binary (eq hash (md5 %s))) -(between now-%s now)) -(limit 1000) - ''' % (value, period) - return query.replace('\n', ' ') - - -def handle_domain(value, period): - query = '''select ((device name) (device (name last_ip_address)) (user name)(user department) (binary executable_name)(binary application_name)(binary description)(binary application_category)(binary (executable_name version)) (binary #"Suspicious binary")(binary first_seen)(binary last_seen)(binary threat_level)(binary hash) (binary paths) -(destination name)(domain name) (domain domain_category)(domain hosting_country)(domain protocol)(domain threat_level) (port port_number)(web_request incoming_traffic)(web_request outgoing_traffic)) -(from (web_request device user binary executable destination domain port) -(where domain (eq name(string %s))) -(between now-%s now)) -(limit 1000) - ''' % (value, period) - return query.replace('\n', ' ') - - -handlers = { - 'sha1': handle_sha1, - 'sha256': handle_sha256, - 'md5': handle_md5, - 'domain': handle_domain -} - - -def handler(q=False): - if q is False: - return False - r = {'results': []} - request = json.loads(q) - config = request.get("config", {"Period": ""}) - output = '' - - for event in request["data"]: - for attribute in event["Attribute"]: - if attribute['type'] in types_to_use: - output = output + handlers[attribute['type']](attribute['value'], config['Period']) + '\n' - r = {"response": [], "data": str(base64.b64encode(bytes(output, 'utf-8')), 'utf-8')} - return r - - -def introspection(): - modulesetup = {} - try: - responseType - modulesetup['responseType'] = responseType - except NameError: - pass - try: - userConfig - modulesetup['userConfig'] = userConfig - except NameError: - pass - try: - outputFileExtension - modulesetup['outputFileExtension'] = outputFileExtension - except NameError: - pass - try: - inputSource - modulesetup['inputSource'] = inputSource - except NameError: - pass - return modulesetup - - -def version(): - moduleinfo['config'] = moduleconfig - return moduleinfo +""" +Export module for coverting MISP events into Nexthink NXQL queries. +Source: https://github.com/HacknowledgeCH/misp-modules/blob/master/misp_modules/modules/export_mod/nexthinkexport.py +Config['Period'] : allows to define period over witch to look for IOC from now (15m, 1d, 2w, 30d, ...), see Nexthink data model documentation +""" + +import base64 +import json + +misperrors = {"error": "Error"} + +types_to_use = ['sha1', 'sha256', 'md5', 'domain'] + +userConfig = { + +} + +moduleconfig = ["Period"] +inputSource = ['event'] + +outputFileExtension = 'nxql' +responseType = 'application/txt' + +moduleinfo = { + 'version': '1.0', + 'author': 'Julien Bachmann, Hacknowledge', + 'description': 'Nexthink NXQL query export module', + 'module-type': ['export'], + 'name': 'Nexthink NXQL Export', + 'logo': 'nexthink.svg', + 'requirements': [], + 'features': 'This module export an event as Nexthink NXQL queries that can then be used in your own python3 tool or from wget/powershell', + 'references': ['https://doc.nexthink.com/Documentation/Nexthink/latest/APIAndIntegrations/IntroducingtheWebAPIV2'], + 'input': 'MISP Event attributes', + 'output': 'Nexthink NXQL queries', +} + + +def handle_sha1(value, period): + query = '''select ((binary (executable_name version)) (user (name)) (device (name last_ip_address)) (execution (binary_path start_time))) +(from (binary user device execution) +(where binary (eq sha1 (sha1 %s))) +(between now-%s now)) +(limit 1000) + ''' % (value, period) + return query.replace('\n', ' ') + + +def handle_sha256(value, period): + query = '''select ((binary (executable_name version)) (user (name)) (device (name last_ip_address)) (execution (binary_path start_time))) +(from (binary user device execution) +(where binary (eq sha256 (sha256 %s))) +(between now-%s now)) +(limit 1000) + ''' % (value, period) + return query.replace('\n', ' ') + + +def handle_md5(value, period): + query = '''select ((binary (executable_name version)) (user (name)) (device (name last_ip_address)) (execution (binary_path start_time))) +(from (binary user device execution) +(where binary (eq hash (md5 %s))) +(between now-%s now)) +(limit 1000) + ''' % (value, period) + return query.replace('\n', ' ') + + +def handle_domain(value, period): + query = '''select ((device name) (device (name last_ip_address)) (user name)(user department) (binary executable_name)(binary application_name)(binary description)(binary application_category)(binary (executable_name version)) (binary #"Suspicious binary")(binary first_seen)(binary last_seen)(binary threat_level)(binary hash) (binary paths) +(destination name)(domain name) (domain domain_category)(domain hosting_country)(domain protocol)(domain threat_level) (port port_number)(web_request incoming_traffic)(web_request outgoing_traffic)) +(from (web_request device user binary executable destination domain port) +(where domain (eq name(string %s))) +(between now-%s now)) +(limit 1000) + ''' % (value, period) + return query.replace('\n', ' ') + + +handlers = { + 'sha1': handle_sha1, + 'sha256': handle_sha256, + 'md5': handle_md5, + 'domain': handle_domain +} + + +def handler(q=False): + if q is False: + return False + r = {'results': []} + request = json.loads(q) + config = request.get("config", {"Period": ""}) + output = '' + + for event in request["data"]: + for attribute in event["Attribute"]: + if attribute['type'] in types_to_use: + output = output + handlers[attribute['type']](attribute['value'], config['Period']) + '\n' + r = {"response": [], "data": str(base64.b64encode(bytes(output, 'utf-8')), 'utf-8')} + return r + + +def introspection(): + modulesetup = {} + try: + responseType + modulesetup['responseType'] = responseType + except NameError: + pass + try: + userConfig + modulesetup['userConfig'] = userConfig + except NameError: + pass + try: + outputFileExtension + modulesetup['outputFileExtension'] = outputFileExtension + except NameError: + pass + try: + inputSource + modulesetup['inputSource'] = inputSource + except NameError: + pass + return modulesetup + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo diff --git a/misp_modules/modules/export_mod/osqueryexport.py b/misp_modules/modules/export_mod/osqueryexport.py index 6368875c..3022a563 100755 --- a/misp_modules/modules/export_mod/osqueryexport.py +++ b/misp_modules/modules/export_mod/osqueryexport.py @@ -1,115 +1,125 @@ -""" -Export module for coverting MISP events into OSQuery queries. -Source: https://github.com/0xmilkmix/misp-modules/blob/master/misp_modules/modules/export_mod/osqueryexport.py -""" - -import base64 -import json -import re - -misperrors = {"error": "Error"} - -types_to_use = ['regkey', 'regkey|value', 'mutex', 'windows-service-displayname', 'windows-scheduled-task', 'yara'] - -userConfig = { - -} - -moduleconfig = [] -inputSource = ['event'] - -outputFileExtension = 'conf' -responseType = 'application/txt' - - -moduleinfo = {'version': '1.0', 'author': 'Julien Bachmann, Hacknowledge', - 'description': 'OSQuery query export module', - 'module-type': ['export']} - - -def handle_regkey(value): - rep = {'HKCU': 'HKEY_USERS\\%', 'HKLM': 'HKEY_LOCAL_MACHINE'} - rep = dict((re.escape(k), v) for k, v in rep.items()) - pattern = re.compile("|".join(rep.keys())) - value = pattern.sub(lambda m: rep[re.escape(m.group(0))], value) - return 'SELECT * FROM registry WHERE path LIKE \'%s\';' % value - - -def handle_regkeyvalue(value): - key, value = value.split('|') - rep = {'HKCU': 'HKEY_USERS\\%', 'HKLM': 'HKEY_LOCAL_MACHINE'} - rep = dict((re.escape(k), v) for k, v in rep.items()) - pattern = re.compile("|".join(rep.keys())) - key = pattern.sub(lambda m: rep[re.escape(m.group(0))], key) - return 'SELECT * FROM registry WHERE path LIKE \'%s\' AND data LIKE \'%s\';' % (key, value) - - -def handle_mutex(value): - return 'SELECT * FROM winbaseobj WHERE object_name LIKE \'%s\';' % value - - -def handle_service(value): - return 'SELECT * FROM services WHERE display_name LIKE \'%s\' OR name like \'%s\';' % (value, value) - - -def handle_yara(value): - return 'not implemented yet, not sure it\'s easily feasible w/o dropping the sig on the hosts first' - - -def handle_scheduledtask(value): - return 'SELECT * FROM scheduled_tasks WHERE name LIKE \'%s\';' % value - - -handlers = { - 'regkey': handle_regkey, - 'regkey|value': handle_regkeyvalue, - 'mutex': handle_mutex, - 'windows-service-displayname': handle_service, - 'windows-scheduled-task': handle_scheduledtask, - 'yara': handle_yara -} - - -def handler(q=False): - if q is False: - return False - r = {'results': []} - request = json.loads(q) - output = '' - - for event in request["data"]: - for attribute in event["Attribute"]: - if attribute['type'] in types_to_use: - output = output + handlers[attribute['type']](attribute['value']) + '\n' - r = {"response": [], "data": str(base64.b64encode(bytes(output, 'utf-8')), 'utf-8')} - return r - - -def introspection(): - modulesetup = {} - try: - responseType - modulesetup['responseType'] = responseType - except NameError: - pass - try: - userConfig - modulesetup['userConfig'] = userConfig - except NameError: - pass - try: - outputFileExtension - modulesetup['outputFileExtension'] = outputFileExtension - except NameError: - pass - try: - inputSource - modulesetup['inputSource'] = inputSource - except NameError: - pass - return modulesetup - - -def version(): - moduleinfo['config'] = moduleconfig - return moduleinfo +""" +Export module for coverting MISP events into OSQuery queries. +Source: https://github.com/0xmilkmix/misp-modules/blob/master/misp_modules/modules/export_mod/osqueryexport.py +""" + +import base64 +import json +import re + +misperrors = {"error": "Error"} + +types_to_use = ['regkey', 'regkey|value', 'mutex', 'windows-service-displayname', 'windows-scheduled-task', 'yara'] + +userConfig = { + +} + +moduleconfig = [] +inputSource = ['event'] + +outputFileExtension = 'conf' +responseType = 'application/txt' + + +moduleinfo = { + 'version': '1.0', + 'author': 'Julien Bachmann, Hacknowledge', + 'description': 'OSQuery export of a MISP event.', + 'module-type': ['export'], + 'name': 'OSQuery Export', + 'logo': 'osquery.png', + 'requirements': [], + 'features': 'This module export an event as osquery queries that can be used in packs or in fleet management solution like Kolide.', + 'references': [], + 'input': 'MISP Event attributes', + 'output': 'osquery SQL queries', +} + + +def handle_regkey(value): + rep = {'HKCU': 'HKEY_USERS\\%', 'HKLM': 'HKEY_LOCAL_MACHINE'} + rep = dict((re.escape(k), v) for k, v in rep.items()) + pattern = re.compile("|".join(rep.keys())) + value = pattern.sub(lambda m: rep[re.escape(m.group(0))], value) + return 'SELECT * FROM registry WHERE path LIKE \'%s\';' % value + + +def handle_regkeyvalue(value): + key, value = value.split('|') + rep = {'HKCU': 'HKEY_USERS\\%', 'HKLM': 'HKEY_LOCAL_MACHINE'} + rep = dict((re.escape(k), v) for k, v in rep.items()) + pattern = re.compile("|".join(rep.keys())) + key = pattern.sub(lambda m: rep[re.escape(m.group(0))], key) + return 'SELECT * FROM registry WHERE path LIKE \'%s\' AND data LIKE \'%s\';' % (key, value) + + +def handle_mutex(value): + return 'SELECT * FROM winbaseobj WHERE object_name LIKE \'%s\';' % value + + +def handle_service(value): + return 'SELECT * FROM services WHERE display_name LIKE \'%s\' OR name like \'%s\';' % (value, value) + + +def handle_yara(value): + return 'not implemented yet, not sure it\'s easily feasible w/o dropping the sig on the hosts first' + + +def handle_scheduledtask(value): + return 'SELECT * FROM scheduled_tasks WHERE name LIKE \'%s\';' % value + + +handlers = { + 'regkey': handle_regkey, + 'regkey|value': handle_regkeyvalue, + 'mutex': handle_mutex, + 'windows-service-displayname': handle_service, + 'windows-scheduled-task': handle_scheduledtask, + 'yara': handle_yara +} + + +def handler(q=False): + if q is False: + return False + r = {'results': []} + request = json.loads(q) + output = '' + + for event in request["data"]: + for attribute in event["Attribute"]: + if attribute['type'] in types_to_use: + output = output + handlers[attribute['type']](attribute['value']) + '\n' + r = {"response": [], "data": str(base64.b64encode(bytes(output, 'utf-8')), 'utf-8')} + return r + + +def introspection(): + modulesetup = {} + try: + responseType + modulesetup['responseType'] = responseType + except NameError: + pass + try: + userConfig + modulesetup['userConfig'] = userConfig + except NameError: + pass + try: + outputFileExtension + modulesetup['outputFileExtension'] = outputFileExtension + except NameError: + pass + try: + inputSource + modulesetup['inputSource'] = inputSource + except NameError: + pass + return modulesetup + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo diff --git a/misp_modules/modules/export_mod/pdfexport.py b/misp_modules/modules/export_mod/pdfexport.py index 44b3bc9e..53ea17d7 100755 --- a/misp_modules/modules/export_mod/pdfexport.py +++ b/misp_modules/modules/export_mod/pdfexport.py @@ -8,11 +8,20 @@ from pymisp.tools import reportlab_generator misperrors = {'error': 'Error'} -moduleinfo = {'version': '2', - 'author': 'Vincent Falconieri (prev. Raphaël Vinot)', - 'description': 'Simple export to PDF', - 'module-type': ['export'], - 'require_standard_format': True} +moduleinfo = { + 'version': '2', + 'author': 'Vincent Falconieri (prev. Raphaël Vinot)', + 'description': 'Simple export of a MISP event to PDF.', + 'module-type': ['export'], + 'name': 'Event to PDF Export', + 'require_standard_format': True, + 'logo': '', + 'requirements': ['PyMISP', 'reportlab'], + 'features': "The module takes care of the PDF file building, and work with any MISP Event. Except the requirement of reportlab, used to create the file, there is no special feature concerning the Event. Some parameters can be given through the config dict. 'MISP_base_url_for_dynamic_link' is your MISP URL, to attach an hyperlink to your event on your MISP instance from the PDF. Keep it clear to avoid hyperlinks in the generated pdf.\n 'MISP_name_for_metadata' is your CERT or MISP instance name. Used as text in the PDF' metadata\n 'Activate_textual_description' is a boolean (True or void) to activate the textual description/header abstract of an event\n 'Activate_galaxy_description' is a boolean (True or void) to activate the description of event related galaxies.\n 'Activate_related_events' is a boolean (True or void) to activate the description of related event. Be aware this might leak information on confidential events linked to the current event !\n 'Activate_internationalization_fonts' is a boolean (True or void) to activate Noto fonts instead of default fonts (Helvetica). This allows the support of CJK alphabet. Be sure to have followed the procedure to download Noto fonts (~70Mo) in the right place (/tools/pdf_fonts/Noto_TTF), to allow PyMisp to find and use them during PDF generation.\n 'Custom_fonts_path' is a text (path or void) to the TTF file of your choice, to create the PDF with it. Be aware the PDF won't support bold/italic/special style anymore with this option ", + 'references': ['https://acrobat.adobe.com/us/en/acrobat/about-adobe-pdf.html'], + 'input': 'MISP Event', + 'output': 'MISP Event in a PDF file.', +} # config fields that your code expects from the site admin moduleconfig = ["MISP_base_url_for_dynamic_link", "MISP_name_for_metadata", "Activate_textual_description", "Activate_galaxy_description", "Activate_related_events", "Activate_internationalization_fonts", "Custom_fonts_path"] diff --git a/misp_modules/modules/export_mod/testexport.py b/misp_modules/modules/export_mod/testexport.py index 1fc7ff7d..e1fb6ff5 100755 --- a/misp_modules/modules/export_mod/testexport.py +++ b/misp_modules/modules/export_mod/testexport.py @@ -18,9 +18,19 @@ outputFileExtension = 'txt' responseType = 'application/txt' -moduleinfo = {'version': '0.1', 'author': 'Andras Iklody', - 'description': 'Skeleton export module', - 'module-type': ['export']} +moduleinfo = { + 'version': '0.1', + 'author': 'Andras Iklody', + 'description': 'Skeleton export module.', + 'name': 'Test Export', + 'module-type': ['export'], + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} def handler(q=False): diff --git a/misp_modules/modules/export_mod/threatStream_misp_export.py b/misp_modules/modules/export_mod/threatStream_misp_export.py index a9f7f06e..68c710f3 100755 --- a/misp_modules/modules/export_mod/threatStream_misp_export.py +++ b/misp_modules/modules/export_mod/threatStream_misp_export.py @@ -1,107 +1,114 @@ -""" -Export module for coverting MISP events into ThreatStream Structured Import files. Based of work by the CenturyLink CIRT. -Source: https://github.com/MISP/misp-modules/blob/master/misp_modules/modules/export_mod/threat_connect_export.py -""" - -import base64 -import csv -import io -import json -import logging - - -misperrors = {"error": "Error"} - -moduleinfo = { - "version": "1.0", - "author": "Robert Nixon, based off of the ThreatConnect MISP Module written by the CenturyLink CIRT", - "description": "Export a structured CSV file for uploading to ThreatStream", - "module-type": ["export"] -} - - -moduleconfig = [] - - -# Map of MISP fields => ThreatStream itypes, you can modify this to your liking -fieldmap = { - "domain": "mal_domain", - "hostname": "mal_domain", - "ip-src": "mal_ip", - "ip-dst": "mal_ip", - "email-src": "phish_email", - "url": "mal_url", - "md5": "mal_md5", -} - -# combine all the MISP fields from fieldmap into one big list -mispattributes = { - "input": list(fieldmap.keys()) -} - - -def handler(q=False): - """ - Convert a MISP query into a CSV file matching the ThreatStream Structured Import file format. - Input - q: Query dictionary - """ - if q is False or not q: - return False - - request = json.loads(q) - - response = io.StringIO() - writer = csv.DictWriter(response, fieldnames=["value", "itype", "tags"]) - writer.writeheader() - - # start parsing MISP data - for event in request["data"]: - for attribute in event["Attribute"]: - if attribute["type"] in mispattributes["input"]: - logging.debug("Adding %s to structured CSV export of ThreatStream Export", attribute["value"]) - if "|" in attribute["type"]: - # if the attribute type has multiple values, line it up with the corresponding ThreatStream values in fieldmap - indicators = tuple(attribute["value"].split("|")) - ts_types = tuple(fieldmap[attribute["type"]].split("|")) - for i, indicator in enumerate(indicators): - writer.writerow({ - "value": indicator, - "itype": ts_types[i], - "tags": attribute["comment"] - }) - else: - writer.writerow({ - "itype": fieldmap[attribute["type"]], - "value": attribute["value"], - "tags": attribute["comment"] - }) - - return {"response": [], "data": str(base64.b64encode(bytes(response.getvalue(), 'utf-8')), 'utf-8')} - - -def introspection(): - """ - Relay the supported attributes to MISP. - No Input - Output - Dictionary of supported MISP attributes - """ - modulesetup = { - "responseType": "application/txt", - "outputFileExtension": "csv", - "userConfig": {}, - "inputSource": [] - } - return modulesetup - - -def version(): - """ - Relay module version and associated metadata to MISP. - No Input - Output - moduleinfo: metadata output containing all potential configuration values - """ - moduleinfo["config"] = moduleconfig - return moduleinfo +""" +Export module for coverting MISP events into ThreatStream Structured Import files. Based of work by the CenturyLink CIRT. +Source: https://github.com/MISP/misp-modules/blob/master/misp_modules/modules/export_mod/threat_connect_export.py +""" + +import base64 +import csv +import io +import json +import logging + + +misperrors = {"error": "Error"} + +moduleinfo = { + 'version': '1.0', + 'author': 'Robert Nixon, based off of the ThreatConnect MISP Module written by the CenturyLink CIRT', + 'description': 'Module to export a structured CSV file for uploading to threatStream.', + 'module-type': ['export'], + 'name': 'ThreatStream Export', + 'logo': 'threatstream.png', + 'requirements': ['csv'], + 'features': 'The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in a CSV format recognized by ThreatStream.', + 'references': ['https://www.anomali.com/platform/threatstream', 'https://github.com/threatstream'], + 'input': 'MISP Event attributes', + 'output': 'ThreatStream CSV format file', +} + + +moduleconfig = [] + + +# Map of MISP fields => ThreatStream itypes, you can modify this to your liking +fieldmap = { + "domain": "mal_domain", + "hostname": "mal_domain", + "ip-src": "mal_ip", + "ip-dst": "mal_ip", + "email-src": "phish_email", + "url": "mal_url", + "md5": "mal_md5", +} + +# combine all the MISP fields from fieldmap into one big list +mispattributes = { + "input": list(fieldmap.keys()) +} + + +def handler(q=False): + """ + Convert a MISP query into a CSV file matching the ThreatStream Structured Import file format. + Input + q: Query dictionary + """ + if q is False or not q: + return False + + request = json.loads(q) + + response = io.StringIO() + writer = csv.DictWriter(response, fieldnames=["value", "itype", "tags"]) + writer.writeheader() + + # start parsing MISP data + for event in request["data"]: + for attribute in event["Attribute"]: + if attribute["type"] in mispattributes["input"]: + logging.debug("Adding %s to structured CSV export of ThreatStream Export", attribute["value"]) + if "|" in attribute["type"]: + # if the attribute type has multiple values, line it up with the corresponding ThreatStream values in fieldmap + indicators = tuple(attribute["value"].split("|")) + ts_types = tuple(fieldmap[attribute["type"]].split("|")) + for i, indicator in enumerate(indicators): + writer.writerow({ + "value": indicator, + "itype": ts_types[i], + "tags": attribute["comment"] + }) + else: + writer.writerow({ + "itype": fieldmap[attribute["type"]], + "value": attribute["value"], + "tags": attribute["comment"] + }) + + return {"response": [], "data": str(base64.b64encode(bytes(response.getvalue(), 'utf-8')), 'utf-8')} + + +def introspection(): + """ + Relay the supported attributes to MISP. + No Input + Output + Dictionary of supported MISP attributes + """ + modulesetup = { + "responseType": "application/txt", + "outputFileExtension": "csv", + "userConfig": {}, + "inputSource": [] + } + return modulesetup + + +def version(): + """ + Relay module version and associated metadata to MISP. + No Input + Output + moduleinfo: metadata output containing all potential configuration values + """ + moduleinfo["config"] = moduleconfig + return moduleinfo diff --git a/misp_modules/modules/export_mod/threat_connect_export.py b/misp_modules/modules/export_mod/threat_connect_export.py index 0b51fb78..a86240c0 100644 --- a/misp_modules/modules/export_mod/threat_connect_export.py +++ b/misp_modules/modules/export_mod/threat_connect_export.py @@ -13,10 +13,17 @@ import logging misperrors = {"error": "Error"} moduleinfo = { - "version": "0.1", - "author": "CenturyLink CIRT", - "description": "Export a structured CSV file for uploading to ThreatConnect", - "module-type": ["export"] + 'version': '0.1', + 'author': 'CenturyLink CIRT', + 'description': 'Module to export a structured CSV file for uploading to ThreatConnect.', + 'module-type': ['export'], + 'name': 'ThreadConnect Export', + 'logo': 'threatconnect.png', + 'requirements': ['csv'], + 'features': 'The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in a CSV format recognized by ThreatConnect.\nUsers should then provide, as module configuration, the source of data they export, because it is required by the output format.', + 'references': ['https://www.threatconnect.com'], + 'input': 'MISP Event attributes', + 'output': 'ThreatConnect CSV format file', } # config fields expected from the MISP administrator diff --git a/misp_modules/modules/export_mod/virustotal_collections.py b/misp_modules/modules/export_mod/virustotal_collections.py index 28a79ef2..9da3bb5d 100644 --- a/misp_modules/modules/export_mod/virustotal_collections.py +++ b/misp_modules/modules/export_mod/virustotal_collections.py @@ -43,7 +43,14 @@ moduleinfo = { 'version': '1.0', 'author': 'VirusTotal', 'description': 'Creates a VT Collection from an event iocs.', - 'module-type': ['export'] + 'module-type': ['export'], + 'name': 'VirusTotal Collections Export', + 'logo': 'virustotal.png', + 'requirements': ['An access to the VirusTotal API (apikey).'], + 'features': 'This export module which takes advantage of a new endpoint in VT APIv3 to create VT Collections from IOCs contained in a MISP event. With this module users will be able to create a collection just using the Download as... button.', + 'references': ['https://www.virustotal.com/', 'https://blog.virustotal.com/2021/11/introducing-virustotal-collections.html'], + 'input': 'A domain, hash (md5, sha1, sha256 or sha512), hostname, url or IP address attribute.', + 'output': 'A VirusTotal collection in VT.', } moduleconfig = [ diff --git a/misp_modules/modules/export_mod/vt_graph.py b/misp_modules/modules/export_mod/vt_graph.py index 70c1952c..7f2125c2 100644 --- a/misp_modules/modules/export_mod/vt_graph.py +++ b/misp_modules/modules/export_mod/vt_graph.py @@ -12,8 +12,15 @@ misperrors = { moduleinfo = { 'version': '0.1', 'author': 'VirusTotal', - 'description': 'Send event to VirusTotal Graph', - 'module-type': ['export'] + 'description': 'This module is used to create a VirusTotal Graph from a MISP event.', + 'module-type': ['export'], + 'name': 'VirusTotal Graph Export', + 'logo': 'virustotal.png', + 'requirements': ['vt_graph_api, the python library to query the VirusTotal graph API'], + 'features': 'The module takes the MISP event as input and queries the VirusTotal Graph API to create a new graph out of the event.\n\nOnce the graph is ready, we get the url of it, which is returned so we can view it on VirusTotal.', + 'references': ['https://www.virustotal.com/gui/graph-overview'], + 'input': 'A MISP event.', + 'output': 'Link of the VirusTotal Graph created for the event.', } mispattributes = { 'input': [ diff --git a/misp_modules/modules/export_mod/yara_export.py b/misp_modules/modules/export_mod/yara_export.py new file mode 100644 index 00000000..ebcbfcde --- /dev/null +++ b/misp_modules/modules/export_mod/yara_export.py @@ -0,0 +1,290 @@ +import json +import base64 +import re +try: + import yara +except (OSError, ImportError): + print("yara is missing, use 'pip3 install -I -r REQUIREMENTS' from the root of this repository to install it.") + + +misperrors = {'error': 'Error'} + + +userConfig = { + +} + +moduleconfig = [] + +# fixed for now, options in the future: +# event, attribute, event-collection, attribute-collection +inputSource = ['event'] + +outputFileExtension = 'yara' +responseType = 'text/plain' + + +moduleinfo = { + 'version': '0.1', + 'author': 'Christophe Vandeplas', + 'description': 'This module is used to export MISP events to YARA.', + 'module-type': ['export'], + 'name': 'YARA Rule Export', + 'logo': 'yara.png', + 'requirements': ['yara-python python library'], + 'features': 'The module will dynamically generate YARA rules for attributes that are marked as to IDS. Basic metadata about the event is added to the rule.\nAttributes that are already YARA rules are also exported, with a rewritten rule name.', + 'references': ['https://virustotal.github.io/yara/'], + 'input': 'Attributes and Objects.', + 'output': 'A YARA file that can be used with the YARA scanning tool.', +} + + +class YaraRule(): + def __init__(self, name): + self.name = name + self.strings = {} + self.conditions = [] + self.meta = {} + + def add_string(self, type_: str, s: str): + type_clean = ''.join(c if c.isalnum() or c == '_' else '_' for c in type_) + if type_clean not in self.strings: + self.strings[type_clean] = [] + self.strings[type_clean].append(s) + + def add_condition(self, condition: str): + self.conditions.append(condition) + + def add_meta(self, key: str, value: str): + if key not in self.meta: + self.meta[key] = [] + self.meta[key].append(value) + + def __str__(self): + if len(self.strings) == 0 and len(self.conditions) == 0: + return "\n" # no strings, so no rule + + result = [] + result.append(f"rule {self.name} {{") + + result.append(" meta:") + for key, values in self.meta.items(): + i = 0 + if len(values) == 1: + result.append(f" {key} = \"{values[0]}\"") + continue + for value in values: + result.append(f" {key}_{i} = \"{value}\"") + i += 1 + + result.append(" strings:") + for key, values in self.strings.items(): + i = 0 + for value in values: + result.append(f" ${key}_{i} = \"{value}\"") + i += 1 + + result.append(" condition:") + if len(self.conditions) == 0: + result.append(" any of them") + for condition in self.conditions: + result.append(f" {condition}") + + result.append("}") + result.append("") + return '\n'.join(result) + + +def handle_string(yara_rules: list, yr: YaraRule, attribute: dict): + if not attribute['to_ids']: # skip non IDS attributes + return + yr.add_string(attribute['type'], attribute['value']) + return + + +def handle_combined(yara_rules: list, yr: YaraRule, attribute: dict): + if not attribute['to_ids']: # skip non IDS attributes + return + type_1, type_2 = attribute['type'].split('|') + value_1, value_2 = attribute['value'].split('|') + try: + handlers[type_1](yara_rules, yr, type_1, value_1) + except KeyError: + # ignore unsupported types + pass + try: + handlers[type_2](yara_rules, yr, type_2, value_2) + except KeyError: + # ignore unsupported types + pass + + +def handle_yara(yara_rules: list, yr: YaraRule, attribute: dict): + # do not check for to_ids, as we want to always export the Yara rule + # split out as a separate rule, and rewrite the rule name + value = re.sub('^[ \t]*rule ', 'rule MISP_e{}_'.format(attribute['event_id']), attribute['value'], flags=re.MULTILINE) + # cleanup dirty stuff from people + substitutions = (('”', '"'), + ('“', '"'), + ('″', '"'), + ('`', "'"), + ('\r', ''), + ('Rule ', 'rule ') # some people write this with the wrong case + # ('$ ', '$'), # this breaks rules + # ('\t\t', '\n'), # this breaks rules + ) + for substitution in substitutions: + if substitution[0] in value: + value = value.replace(substitution[0], substitution[1]) + + # we may ignore any global rules as they might disable everything + # on the other hand we're only processing one event... + # if 'global rule' in value: + # return + + # private rules need some more rewriting + if 'private rule' in value: + priv_rules = re.findall(r'private rule (\w+)', value, flags=re.MULTILINE) + for priv_rule in priv_rules: + value = re.sub(priv_rule, 'MISP_e{}_{}'.format(attribute['event_id'], priv_rule), value, flags=re.MULTILINE) + + # compile the yara rule to confirm it's validity + try: + yara.compile(source=value) + except Exception: + # skip rules that do not compile + return + + # all checks done, add the rule + yara_rules.append(value) + return + + +def handle_malware_sample(yara_rules: list, yr: YaraRule, attribute: dict): + if not attribute['to_ids']: # skip non IDS attributes + return + handle_combined(yara_rules, yr, 'filename|md5', attribute['value']) + + +def handle_meta(yara_rules: list, yr: YaraRule, attribute: dict): + yr.add_meta(attribute['type'], attribute['value']) + return + + +handlers = { + 'yara': handle_yara, + 'hostname': handle_string, + 'hostname|port': handle_combined, + 'domain': handle_string, + 'domain|ip': handle_combined, + 'ip': handle_string, + 'ip-src': handle_string, + 'ip-dst': handle_string, + 'ip-dst|port': handle_combined, # we could also handle_string, which would be more specific. Less false positives, but less true positives too... + 'ip-src|port': handle_combined, + 'url': handle_string, + 'email': handle_string, + 'email-src': handle_string, + 'email-dst': handle_string, + 'email-subject': handle_string, + 'email-attachment': handle_string, + 'email-header': handle_string, + 'email-reply-to': handle_string, + 'email-x-mailer': handle_string, + 'email-mime-boundary': handle_string, + 'email-thread-index': handle_string, + 'email-message-id': handle_string, + 'filename': handle_string, + 'filename|md5': handle_combined, + 'filename|sha1': handle_combined, + 'filename|sha256': handle_combined, + 'filename|authentihash': handle_combined, + 'filename|vhash': handle_combined, + 'filename|ssdeep': handle_combined, + 'filename|imphash': handle_combined, + 'filename|impfuzzy': handle_combined, + 'filename|pehash': handle_combined, + 'filename|sha224': handle_combined, + 'filename|sha384': handle_combined, + 'filename|sha512': handle_combined, + 'filename|sha512/224': handle_combined, + 'filename|sha512/256': handle_combined, + 'filename|sha3-224': handle_combined, + 'filename|sha3-256': handle_combined, + 'filename|sha3-384': handle_combined, + 'filename|sha3-512': handle_combined, + 'filename|tlsh': handle_combined, + 'malware-sample': handle_malware_sample, + 'pattern-in-file': handle_string, + 'pattern-in-traffic': handle_string, + 'pattern-in-memory': handle_string, + 'link': handle_meta +} + +# auto-generate the list of types to use +types_to_use = handlers.keys() + + +def handler(q=False): + if q is False: + return False + request = json.loads(q) + + yara_rules = [] + for event in request["data"]: + event_info_clean = ''.join(c if c.isalnum() or c == '_' else '_' for c in event['Event']['info']) + yr = YaraRule(f"MISP_e{event['Event']['id']}_{event_info_clean}") + + yr.add_meta('description', event['Event']['info']) + yr.add_meta('author', f"MISP - {event['Orgc']['name']}") + yr.add_meta('misp_event_date', event['Event']['date']) + yr.add_meta('misp_event_id', event['Event']['id']) + yr.add_meta('misp_event_uuid', event['Event']['uuid']) + + for attribute in event.get("Attribute", []): + try: + handlers[attribute['type']](yara_rules, yr, attribute) + except KeyError: + # ignore unsupported types + pass + for obj in event.get("Object", []): + for attribute in obj["Attribute"]: + try: + handlers[attribute['type']](yara_rules, yr, attribute) + except KeyError: + # ignore unsupported types + pass + yara_rules.append(str(yr)) + r = {"response": [], "data": str(base64.b64encode(bytes('\n'.join(yara_rules), 'utf-8')), 'utf-8')} + + return r + + +def introspection(): + modulesetup = {} + try: + responseType + modulesetup['responseType'] = responseType + except NameError: + pass + try: + userConfig + modulesetup['userConfig'] = userConfig + except NameError: + pass + try: + outputFileExtension + modulesetup['outputFileExtension'] = outputFileExtension + except NameError: + pass + try: + inputSource + modulesetup['inputSource'] = inputSource + except NameError: + pass + return modulesetup + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo diff --git a/misp_modules/modules/import_mod/__init__.py b/misp_modules/modules/import_mod/__init__.py index 2b3e7550..9ae118d2 100644 --- a/misp_modules/modules/import_mod/__init__.py +++ b/misp_modules/modules/import_mod/__init__.py @@ -16,5 +16,7 @@ __all__ = [ 'cof2misp', 'joe_import', 'taxii21', - 'url_import' + 'url_import', + 'vmray_summary_json_import', + 'import_blueprint' ] diff --git a/misp_modules/modules/import_mod/cof2misp.py b/misp_modules/modules/import_mod/cof2misp.py index 841da09d..79426544 100755 --- a/misp_modules/modules/import_mod/cof2misp.py +++ b/misp_modules/modules/import_mod/cof2misp.py @@ -37,9 +37,19 @@ mispattributes = {'inputSource': ['file'], 'output': ['MISP objects'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.3', 'author': 'Aaron Kaplan', - 'description': 'Module to import the passive DNS Common Output Format (COF) and merge as a MISP objet into a MISP event.', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.3', + 'author': 'Aaron Kaplan', + 'description': 'Passive DNS Common Output Format (COF) MISP importer', + 'module-type': ['import'], + 'name': 'PDNS COF Importer', + 'requirements': ['PyMISP'], + 'features': 'Takes as input a valid COF file or the output of the dnsdbflex utility and creates MISP objects for the input.', + 'references': ['https://tools.ietf.org/id/draft-dulaunoy-dnsop-passive-dns-cof-08.html'], + 'input': 'Passive DNS output in Common Output Format (COF)', + 'output': 'MISP objects', + 'logo': '', +} moduleconfig = [] diff --git a/misp_modules/modules/import_mod/csvimport.py b/misp_modules/modules/import_mod/csvimport.py index 8f4a643d..52d3cff6 100644 --- a/misp_modules/modules/import_mod/csvimport.py +++ b/misp_modules/modules/import_mod/csvimport.py @@ -4,9 +4,19 @@ import io import base64 misperrors = {'error': 'Error'} -moduleinfo = {'version': '0.2', 'author': 'Christian Studer', - 'description': 'Import Attributes from a csv file.', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.2', + 'author': 'Christian Studer', + 'module-type': ['import'], + 'name': 'CSV Import', + 'description': 'Module to import MISP attributes from a csv file.', + 'requirements': ['PyMISP'], + 'features': "In order to parse data from a csv file, a header is required to let the module know which column is matching with known attribute fields / MISP types.\n\nThis header either comes from the csv file itself or is part of the configuration of the module and should be filled out in MISP plugin settings, each field separated by COMMAS. Fields that do not match with any type known in MISP or are not MISP attribute fields should be ignored in import, using a space or simply nothing between two separators (example: 'ip-src, , comment, ').\n\nIf the csv file already contains a header that does not start by a '#', you should tick the checkbox 'has_header' to avoid importing it and have potential issues. You can also redefine the header even if it is already contained in the file, by following the rules for headers explained earlier. One reason why you would redefine a header is for instance when you want to skip some fields, or some fields are not valid types.", + 'references': ['https://tools.ietf.org/html/rfc4180', 'https://tools.ietf.org/html/rfc7111'], + 'input': 'CSV format file.', + 'output': 'MISP Event attributes', + 'logo': '', +} moduleconfig = [] userConfig = { 'header': { diff --git a/misp_modules/modules/import_mod/cuckooimport.py b/misp_modules/modules/import_mod/cuckooimport.py index 3ed52bda..626f1cbc 100755 --- a/misp_modules/modules/import_mod/cuckooimport.py +++ b/misp_modules/modules/import_mod/cuckooimport.py @@ -17,10 +17,15 @@ misperrors = {'error': 'Error'} moduleinfo = { 'version': '1.1', 'author': 'Pierre-Jean Grenier', - 'description': "Import a Cuckoo archive (zipfile or bzip2 tarball), " - "either downloaded manually or exported from the " - "API (/tasks/report/{task_id}/all).", 'module-type': ['import'], + 'name': 'Cuckoo Sandbox Import', + 'description': 'Module to import Cuckoo JSON.', + 'logo': 'cuckoo.png', + 'requirements': [], + 'features': 'Import a Cuckoo archive (zipfile or bzip2 tarball), either downloaded manually or exported from the API (/tasks/report//all).', + 'references': ['https://cuckoosandbox.org/', 'https://github.com/cuckoosandbox/cuckoo'], + 'input': 'Cuckoo JSON file', + 'output': 'MISP Event attributes', } moduleconfig = [] diff --git a/misp_modules/modules/import_mod/email_import.py b/misp_modules/modules/import_mod/email_import.py index bad4f6a6..9ad65cc8 100644 --- a/misp_modules/modules/import_mod/email_import.py +++ b/misp_modules/modules/import_mod/email_import.py @@ -18,10 +18,19 @@ misperrors = {'error': 'Error'} mispattributes = {'inputSource': ['file'], 'output': ['MISP objects'], 'format': 'misp_standard'} -moduleinfo = {'version': '0.2', - 'author': 'Seamus Tuohy, Raphaël Vinot', - 'description': 'Email import module for MISP', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.2', + 'author': 'Seamus Tuohy, Raphaël Vinot', + 'description': 'Email import module for MISP', + 'module-type': ['import'], + 'name': 'Email Import', + 'requirements': [], + 'features': 'This module can be used to import e-mail text as well as attachments and urls.\n3 configuration parameters are then used to unzip attachments, guess zip attachment passwords, and extract urls: set each one of them to True or False to process or not the respective corresponding actions.', + 'references': [], + 'input': 'E-mail file', + 'output': 'MISP Event attributes', + 'logo': '', +} # unzip_attachments : Unzip all zip files that are not password protected # guess_zip_attachment_passwords : This attempts to unzip all password protected zip files using all the strings found in the email body and subject diff --git a/misp_modules/modules/import_mod/goamlimport.py b/misp_modules/modules/import_mod/goamlimport.py index 79b4cfe8..afb02668 100644 --- a/misp_modules/modules/import_mod/goamlimport.py +++ b/misp_modules/modules/import_mod/goamlimport.py @@ -5,9 +5,19 @@ import xml.etree.ElementTree as ET from pymisp import MISPEvent, MISPObject misperrors = {'error': 'Error'} -moduleinfo = {'version': 1, 'author': 'Christian Studer', - 'description': 'Import from GoAML', - 'module-type': ['import']} +moduleinfo = { + 'version': 1, + 'author': 'Christian Studer', + 'description': 'Module to import MISP objects about financial transactions from GoAML files.', + 'module-type': ['import'], + 'name': 'GoAML Import', + 'logo': 'goAML.jpg', + 'requirements': ['PyMISP'], + 'features': 'Unlike the GoAML export module, there is here no special feature to import data from GoAML external files, since the module will import MISP Objects with their References on its own, as it is required for the export module to rebuild a valid GoAML document.', + 'references': 'http://goaml.unodc.org/', + 'input': 'GoAML format file, describing financial transactions, with their origin and target (bank accounts, persons or entities).', + 'output': 'MISP objects (transaction, bank-account, person, legal-entity, geolocation), with references, describing financial transactions and their origin and target.', +} moduleconfig = [] mispattributes = {'inputSource': ['file'], 'output': ['MISP objects'], 'format': 'misp_standard'} diff --git a/misp_modules/modules/import_mod/import_blueprint.py b/misp_modules/modules/import_mod/import_blueprint.py index 2758f834..30a72106 100755 --- a/misp_modules/modules/import_mod/import_blueprint.py +++ b/misp_modules/modules/import_mod/import_blueprint.py @@ -31,14 +31,23 @@ mispattributes = { } -moduleinfo = {'version': '0.1', 'author': 'Sami Mokaddem', - 'description': 'Generic blueprint to be copy-pasted to quickly boostrap creation of import module.', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sami Mokaddem', + 'description': 'Generic blueprint to be copy-pasted to quickly boostrap creation of import module.', + 'module-type': ['import'], + 'name': 'Import Blueprint', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} moduleconfig = [] - def generateData(event, data, config): # attr = MISPAttribute() # attr.from_dict(**{ diff --git a/misp_modules/modules/import_mod/joe_import.py b/misp_modules/modules/import_mod/joe_import.py index ce566983..68b41ee0 100644 --- a/misp_modules/modules/import_mod/joe_import.py +++ b/misp_modules/modules/import_mod/joe_import.py @@ -17,9 +17,19 @@ userConfig = { inputSource = ['file'] -moduleinfo = {'version': '0.2', 'author': 'Christian Studer', - 'description': 'Import for Joe Sandbox JSON reports', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.2', + 'author': 'Christian Studer', + 'description': 'A module to import data from a Joe Sandbox analysis json report.', + 'module-type': ['import'], + 'name': 'Joe Sandbox Import', + 'logo': 'joesandbox.png', + 'requirements': [], + 'features': 'Module using the new format of modules able to return attributes and objects.\n\nThe module returns the same results as the expansion module [joesandbox_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_query.py) using the submission link of the analysis to get the json report.', + 'references': ['https://www.joesecurity.org', 'https://www.joesandbox.com/'], + 'input': 'Json report of a Joe Sandbox analysis.', + 'output': 'MISP attributes & objects parsed from the analysis report.', +} moduleconfig = [] diff --git a/misp_modules/modules/import_mod/lastline_import.py b/misp_modules/modules/import_mod/lastline_import.py index 3307852f..7acd4f8a 100644 --- a/misp_modules/modules/import_mod/lastline_import.py +++ b/misp_modules/modules/import_mod/lastline_import.py @@ -24,10 +24,17 @@ userConfig = { inputSource = [] moduleinfo = { - "version": "0.1", - "author": "Stefano Ortolani", - "description": "Import a Lastline report from an analysis link.", - "module-type": ["import"] + 'version': '0.1', + 'author': 'Stefano Ortolani', + 'description': 'Deprecation notice: this module will be deprecated by December 2021, please use vmware_nsx module.\n\nModule to import and parse reports from Lastline analysis links.', + 'module-type': ['import'], + 'name': 'Lastline Import', + 'logo': 'lastline.png', + 'requirements': [], + 'features': 'The module requires a Lastline Portal `username` and `password`.\nThe module uses the new format and it is able to return MISP attributes and objects.\nThe module returns the same results as the [lastline_query](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/lastline_query.py) expansion module.', + 'references': ['https://www.lastline.com'], + 'input': 'Link to a Lastline analysis.', + 'output': 'MISP attributes and objects parsed from the analysis report.', } moduleconfig = [ diff --git a/misp_modules/modules/import_mod/mispjson.py b/misp_modules/modules/import_mod/mispjson.py index a9c22267..e42a95c3 100755 --- a/misp_modules/modules/import_mod/mispjson.py +++ b/misp_modules/modules/import_mod/mispjson.py @@ -6,9 +6,19 @@ userConfig = {} inputSource = ['file'] -moduleinfo = {'version': '0.1', 'author': 'Richard van den Berg', - 'description': 'MISP JSON format import module for merging MISP events', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.1', + 'author': 'Richard van den Berg', + 'description': 'Module to import MISP JSON format for merging MISP events.', + 'module-type': ['import'], + 'name': 'MISP JSON Import', + 'logo': '', + 'requirements': [], + 'features': 'The module simply imports MISP Attributes from an other MISP Event in order to merge events together. There is thus no special feature to make it work.', + 'references': [], + 'input': 'MISP Event', + 'output': 'MISP Event attributes', +} moduleconfig = [] diff --git a/misp_modules/modules/import_mod/ocr.py b/misp_modules/modules/import_mod/ocr.py index 2e82cd2f..68c7e6b4 100755 --- a/misp_modules/modules/import_mod/ocr.py +++ b/misp_modules/modules/import_mod/ocr.py @@ -18,9 +18,19 @@ userConfig = {} inputSource = ['file'] -moduleinfo = {'version': '0.2', 'author': 'Alexandre Dulaunoy', - 'description': 'Optical Character Recognition (OCR) module for MISP', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.2', + 'author': 'Alexandre Dulaunoy', + 'description': 'Optical Character Recognition (OCR) module for MISP.', + 'module-type': ['import'], + 'name': 'OCR Import', + 'logo': '', + 'requirements': [], + 'features': 'The module tries to recognize some text from an image and import the result as a freetext attribute, there is then no special feature asked to users to make it work.', + 'references': [], + 'input': 'Image', + 'output': 'freetext MISP attribute', +} moduleconfig = [] diff --git a/misp_modules/modules/import_mod/openiocimport.py b/misp_modules/modules/import_mod/openiocimport.py index 074a4649..f1946bd5 100755 --- a/misp_modules/modules/import_mod/openiocimport.py +++ b/misp_modules/modules/import_mod/openiocimport.py @@ -15,9 +15,19 @@ userConfig = {'not save ioc': {'type': 'Boolean', inputSource = ['file'] -moduleinfo = {'version': '0.1', 'author': 'Raphaël Vinot', - 'description': 'Import OpenIOC package', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.1', + 'author': 'Raphaël Vinot', + 'description': 'Module to import OpenIOC packages.', + 'module-type': ['import'], + 'name': 'OpenIOC Import', + 'logo': '', + 'requirements': ['PyMISP'], + 'features': 'The module imports MISP Attributes from OpenIOC packages, there is then no special feature for users to make it work.', + 'references': ['https://www.fireeye.com/blog/threat-research/2013/10/openioc-basics.html'], + 'input': 'OpenIOC packages', + 'output': 'MISP Event attributes', +} moduleconfig = [] diff --git a/misp_modules/modules/import_mod/stiximport.py b/misp_modules/modules/import_mod/stiximport.py deleted file mode 100755 index 238a4eba..00000000 --- a/misp_modules/modules/import_mod/stiximport.py +++ /dev/null @@ -1,59 +0,0 @@ -import json -import base64 - -from pymisp.tools import stix - -misperrors = {'error': 'Error'} -userConfig = {} -inputSource = ['file'] - -moduleinfo = {'version': '0.2', 'author': 'Hannah Ward', - 'description': 'Import some stix stuff', - 'module-type': ['import']} - -moduleconfig = [] - - -def handler(q=False): - # Just in case we have no data - if q is False: - return False - - # The return value - r = {'results': []} - - # Load up that JSON - q = json.loads(q) - - # It's b64 encoded, so decode that stuff - package = base64.b64decode(q.get("data")).decode('utf-8') - - # If something really weird happened - if not package: - return json.dumps({"success": 0}) - - pkg = stix.load_stix(package) - for attrib in pkg.attributes: - r["results"].append({"values": [attrib.value], "types": [attrib.type], "categories": [attrib.category]}) - - return r - - -def introspection(): - modulesetup = {} - try: - userConfig - modulesetup['userConfig'] = userConfig - except NameError: - pass - try: - inputSource - modulesetup['inputSource'] = inputSource - except NameError: - pass - return modulesetup - - -def version(): - moduleinfo['config'] = moduleconfig - return moduleinfo diff --git a/misp_modules/modules/import_mod/taxii21.py b/misp_modules/modules/import_mod/taxii21.py index d03b85cb..2991497a 100644 --- a/misp_modules/modules/import_mod/taxii21.py +++ b/misp_modules/modules/import_mod/taxii21.py @@ -23,9 +23,19 @@ class ConfigError(Exception): misperrors = {'error': 'Error'} -moduleinfo = {'version': '0.1', 'author': 'Abc', - 'description': 'Import content from a TAXII 2.1 server', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.1', + 'author': 'Abc', + 'description': 'Import content from a TAXII 2.1 server', + 'module-type': ['import'], + 'name': 'TAXII 2.1 Import', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} mispattributes = { 'inputSource': [], diff --git a/misp_modules/modules/import_mod/testimport.py b/misp_modules/modules/import_mod/testimport.py index 891b3a68..818d7217 100755 --- a/misp_modules/modules/import_mod/testimport.py +++ b/misp_modules/modules/import_mod/testimport.py @@ -25,9 +25,19 @@ userConfig = { inputSource = ['file', 'paste'] -moduleinfo = {'version': '0.2', 'author': 'Andras Iklody', - 'description': 'Simple CSV import tool with mapable columns', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.2', + 'author': 'Andras Iklody', + 'description': 'Simple CSV import tool with mapable columns', + 'module-type': ['import'], + 'name': 'CSV Test Import', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} moduleconfig = [] diff --git a/misp_modules/modules/import_mod/threatanalyzer_import.py b/misp_modules/modules/import_mod/threatanalyzer_import.py index cbb9fefe..0d764320 100755 --- a/misp_modules/modules/import_mod/threatanalyzer_import.py +++ b/misp_modules/modules/import_mod/threatanalyzer_import.py @@ -15,9 +15,19 @@ misperrors = {'error': 'Error'} userConfig = {} inputSource = ['file'] -moduleinfo = {'version': '0.10', 'author': 'Christophe Vandeplas', - 'description': 'Import for ThreatAnalyzer archive.zip/analysis.json files', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.10', + 'author': 'Christophe Vandeplas', + 'description': 'Module to import ThreatAnalyzer archive.zip / analysis.json files.', + 'module-type': ['import'], + 'name': 'ThreadAnalyzer Sandbox Import', + 'logo': '', + 'requirements': [], + 'features': 'The module imports MISP Attributes from a ThreatAnalyzer format file. This file can be either ZIP, or JSON format.\nThere is by the way no special feature for users to make the module work.', + 'references': ['https://www.threattrack.com/malware-analysis.aspx'], + 'input': 'ThreatAnalyzer format file', + 'output': 'MISP Event attributes', +} moduleconfig = [] log = logging.getLogger('misp-modules') diff --git a/misp_modules/modules/import_mod/url_import.py b/misp_modules/modules/import_mod/url_import.py index 35b1f5eb..1405f7e1 100755 --- a/misp_modules/modules/import_mod/url_import.py +++ b/misp_modules/modules/import_mod/url_import.py @@ -18,14 +18,25 @@ mispattributes = { } -moduleinfo = {'version': '0.1', 'author': 'Sami Mokaddem', - 'description': 'Generic blueprint to be copy-pasted to quickly boostrap creation of import module.', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.1', + 'author': 'Sami Mokaddem', + 'description': 'Simple URL import tool with Faup', + 'module-type': ['import'], + 'name': 'URL Import', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', +} moduleconfig = [] fp = Faup() + def generateData(event, data, config): for url in data.splitlines(): fp.decode(url) diff --git a/misp_modules/modules/import_mod/vmray_import.py b/misp_modules/modules/import_mod/vmray_import.py index 8385634e..72d58a8a 100644 --- a/misp_modules/modules/import_mod/vmray_import.py +++ b/misp_modules/modules/import_mod/vmray_import.py @@ -20,9 +20,19 @@ from _vmray.parser import VMRayParser, VMRayParseError misperrors = {'error': 'Error'} -moduleinfo = {'version': '0.4', 'author': 'Jens Thom (VMRay), Koen van Impe', - 'description': 'Import VMRay analysis results from a server', - 'module-type': ['import']} +moduleinfo = { + 'version': '0.4', + 'author': 'Jens Thom (VMRay), Koen van Impe', + 'description': 'Module to import VMRay (VTI) results.', + 'module-type': ['import'], + 'name': 'VMRay API Import', + 'logo': 'vmray.png', + 'requirements': ['vmray_rest_api'], + 'features': 'The module imports MISP Attributes from VMRay format, using the VMRay api.\nUsers should then provide as the module configuration the API Key as well as the server url in order to fetch their data to import.', + 'references': ['https://www.vmray.com/'], + 'input': 'VMRay format', + 'output': 'MISP Event attributes', +} mispattributes = { 'inputSource': [], diff --git a/misp_modules/modules/import_mod/vmray_summary_json_import.py b/misp_modules/modules/import_mod/vmray_summary_json_import.py index e7f4985f..f0e96d5b 100644 --- a/misp_modules/modules/import_mod/vmray_summary_json_import.py +++ b/misp_modules/modules/import_mod/vmray_summary_json_import.py @@ -8,10 +8,17 @@ misperrors = {'error': 'Error'} moduleconfig = ["disable_tags"] moduleinfo = { - "version": "0.1", - "author": "VMRay", - "description": "Import a VMRay Summary JSON report.", - "module-type": ["import"], + 'version': '0.1', + 'author': 'VMRay', + 'description': 'Import a VMRay Summary JSON report.', + 'module-type': ['import'], + 'name': 'VMRay Summary JSON Import', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '', } mispattributes = { diff --git a/mkdocs.yml b/mkdocs.yml index b1dac326..b683ea24 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -16,7 +16,7 @@ edit_uri: edit/main/docs/ use_directory_urls: true # Copyright -copyright: "Copyright © 2019-2023 MISP Project" +copyright: "Copyright © 2019-2024 MISP Project" # Options extra: @@ -82,8 +82,9 @@ markdown_extensions: - pymdownx.tilde nav: - - Home: 'index.md' + - Home: index.md - Modules: + - Action Modules: action_mod.md - Expansion Modules: expansion.md - Export Modules: export_mod.md - Import Modules: import_mod.md diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 00000000..7aa31f43 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,6087 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "aiohappyeyeballs" +version = "2.4.0" +description = "Happy Eyeballs for asyncio" +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiohappyeyeballs-2.4.0-py3-none-any.whl", hash = "sha256:7ce92076e249169a13c2f49320d1967425eaf1f407522d707d59cac7628d62bd"}, + {file = "aiohappyeyeballs-2.4.0.tar.gz", hash = "sha256:55a1714f084e63d49639800f95716da97a1f173d46a16dfcfda0016abb93b6b2"}, +] + +[[package]] +name = "aiohttp" +version = "3.10.5" +description = "Async http client/server framework (asyncio)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3"}, + {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6"}, + {file = "aiohttp-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699"}, + {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6"}, + {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1"}, + {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f"}, + {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb"}, + {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91"}, + {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f"}, + {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c"}, + {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69"}, + {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3"}, + {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683"}, + {file = "aiohttp-3.10.5-cp310-cp310-win32.whl", hash = "sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef"}, + {file = "aiohttp-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088"}, + {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2"}, + {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf"}, + {file = "aiohttp-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e"}, + {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77"}, + {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061"}, + {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697"}, + {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7"}, + {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0"}, + {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5"}, + {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e"}, + {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1"}, + {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277"}, + {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058"}, + {file = "aiohttp-3.10.5-cp311-cp311-win32.whl", hash = "sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072"}, + {file = "aiohttp-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff"}, + {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487"}, + {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a"}, + {file = "aiohttp-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d"}, + {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75"}, + {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178"}, + {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e"}, + {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f"}, + {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73"}, + {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf"}, + {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820"}, + {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca"}, + {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91"}, + {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6"}, + {file = "aiohttp-3.10.5-cp312-cp312-win32.whl", hash = "sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12"}, + {file = "aiohttp-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc"}, + {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092"}, + {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77"}, + {file = "aiohttp-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385"}, + {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972"}, + {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16"}, + {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6"}, + {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa"}, + {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689"}, + {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57"}, + {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f"}, + {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599"}, + {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5"}, + {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987"}, + {file = "aiohttp-3.10.5-cp313-cp313-win32.whl", hash = "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04"}, + {file = "aiohttp-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022"}, + {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f6f18898ace4bcd2d41a122916475344a87f1dfdec626ecde9ee802a711bc569"}, + {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5ede29d91a40ba22ac1b922ef510aab871652f6c88ef60b9dcdf773c6d32ad7a"}, + {file = "aiohttp-3.10.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:673f988370f5954df96cc31fd99c7312a3af0a97f09e407399f61583f30da9bc"}, + {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58718e181c56a3c02d25b09d4115eb02aafe1a732ce5714ab70326d9776457c3"}, + {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b38b1570242fbab8d86a84128fb5b5234a2f70c2e32f3070143a6d94bc854cf"}, + {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:074d1bff0163e107e97bd48cad9f928fa5a3eb4b9d33366137ffce08a63e37fe"}, + {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd31f176429cecbc1ba499d4aba31aaccfea488f418d60376b911269d3b883c5"}, + {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7384d0b87d4635ec38db9263e6a3f1eb609e2e06087f0aa7f63b76833737b471"}, + {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8989f46f3d7ef79585e98fa991e6ded55d2f48ae56d2c9fa5e491a6e4effb589"}, + {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c83f7a107abb89a227d6c454c613e7606c12a42b9a4ca9c5d7dad25d47c776ae"}, + {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cde98f323d6bf161041e7627a5fd763f9fd829bcfcd089804a5fdce7bb6e1b7d"}, + {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:676f94c5480d8eefd97c0c7e3953315e4d8c2b71f3b49539beb2aa676c58272f"}, + {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2d21ac12dc943c68135ff858c3a989f2194a709e6e10b4c8977d7fcd67dfd511"}, + {file = "aiohttp-3.10.5-cp38-cp38-win32.whl", hash = "sha256:17e997105bd1a260850272bfb50e2a328e029c941c2708170d9d978d5a30ad9a"}, + {file = "aiohttp-3.10.5-cp38-cp38-win_amd64.whl", hash = "sha256:1c19de68896747a2aa6257ae4cf6ef59d73917a36a35ee9d0a6f48cff0f94db8"}, + {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7e2fe37ac654032db1f3499fe56e77190282534810e2a8e833141a021faaab0e"}, + {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5bf3ead3cb66ab990ee2561373b009db5bc0e857549b6c9ba84b20bc462e172"}, + {file = "aiohttp-3.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b2c16a919d936ca87a3c5f0e43af12a89a3ce7ccbce59a2d6784caba945b68b"}, + {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad146dae5977c4dd435eb31373b3fe9b0b1bf26858c6fc452bf6af394067e10b"}, + {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c5c6fa16412b35999320f5c9690c0f554392dc222c04e559217e0f9ae244b92"}, + {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95c4dc6f61d610bc0ee1edc6f29d993f10febfe5b76bb470b486d90bbece6b22"}, + {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da452c2c322e9ce0cfef392e469a26d63d42860f829026a63374fde6b5c5876f"}, + {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:898715cf566ec2869d5cb4d5fb4be408964704c46c96b4be267442d265390f32"}, + {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:391cc3a9c1527e424c6865e087897e766a917f15dddb360174a70467572ac6ce"}, + {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:380f926b51b92d02a34119d072f178d80bbda334d1a7e10fa22d467a66e494db"}, + {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce91db90dbf37bb6fa0997f26574107e1b9d5ff939315247b7e615baa8ec313b"}, + {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9093a81e18c45227eebe4c16124ebf3e0d893830c6aca7cc310bfca8fe59d857"}, + {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ee40b40aa753d844162dcc80d0fe256b87cba48ca0054f64e68000453caead11"}, + {file = "aiohttp-3.10.5-cp39-cp39-win32.whl", hash = "sha256:03f2645adbe17f274444953bdea69f8327e9d278d961d85657cb0d06864814c1"}, + {file = "aiohttp-3.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:d17920f18e6ee090bdd3d0bfffd769d9f2cb4c8ffde3eb203777a3895c128862"}, + {file = "aiohttp-3.10.5.tar.gz", hash = "sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691"}, +] + +[package.dependencies] +aiohappyeyeballs = ">=2.3.0" +aiosignal = ">=1.1.2" +async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""} +attrs = ">=17.3.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +yarl = ">=1.0,<2.0" + +[package.extras] +speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] + +[[package]] +name = "aiosignal" +version = "1.3.1" +description = "aiosignal: a list of registered asynchronous callbacks" +optional = false +python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} + +[[package]] +name = "ansimarkup" +version = "2.1.0" +description = "Produce colored terminal text with an xml-like markup" +optional = false +python-versions = ">=3.6" +files = [ + {file = "ansimarkup-2.1.0-py3-none-any.whl", hash = "sha256:51ab9f3157125c53e93d8fd2e92df37dfa1757c9f2371ed48554e111c7d4401a"}, + {file = "ansimarkup-2.1.0.tar.gz", hash = "sha256:7b3e3d93fecc5b64d23a6e8eb96dbc8b0b576a211829d948afb397d241a8c51b"}, +] + +[package.dependencies] +colorama = "*" + +[package.extras] +benchmark = ["colr", "pastel", "plumbum", "rich", "termcolor"] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "antlr4-python3-runtime" +version = "4.9.3" +description = "ANTLR 4.9.3 runtime for Python 3.7" +optional = false +python-versions = "*" +files = [ + {file = "antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b"}, +] + +[[package]] +name = "anyio" +version = "4.4.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.8" +files = [ + {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, + {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} + +[package.extras] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] + +[[package]] +name = "apiosintds" +version = "2.0.3" +description = "On demand query API for OSINT.digitalside.it project. You can query for souspicious domains, urls, IPv4 and file hashes." +optional = false +python-versions = ">3.5.2" +files = [ + {file = "apiosintDS-2.0.3-py3-none-any.whl", hash = "sha256:e80163a69f8ca0f9fc01bd37b4c6f5937bdc828be8754a79da1da2958dac7493"}, +] + +[package.dependencies] +pytz = "*" +requests = "*" +stix2 = "*" +urllib3 = "*" + +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = "*" +files = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] + +[[package]] +name = "assemblyline-client" +version = "4.9.3" +description = "Assemblyline v4 client library" +optional = false +python-versions = "*" +files = [ + {file = "assemblyline_client-4.9.3-py2.py3-none-any.whl", hash = "sha256:f14de17f9a5cd922ea78c02cbb8ab616de39b569bc61c2210321948c17870d83"}, +] + +[package.dependencies] +pycryptodome = "*" +python-baseconv = "*" +python-socketio = {version = "*", extras = ["client"]} +requests = [ + {version = "*"}, + {version = "*", extras = ["security"]}, +] +socketio-client = "0.5.7.4" + +[package.extras] +test = ["assemblyline", "cart", "pytest"] + +[[package]] +name = "async-timeout" +version = "4.0.3" +description = "Timeout context manager for asyncio programs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] + +[[package]] +name = "attrs" +version = "24.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + +[[package]] +name = "babel" +version = "2.16.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.8" +files = [ + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, +] + +[package.dependencies] +pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "backoff" +version = "1.11.1" +description = "Function decoration for backoff and retry" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "backoff-1.11.1-py2.py3-none-any.whl", hash = "sha256:61928f8fa48d52e4faa81875eecf308eccfb1016b018bb6bd21e05b5d90a96c5"}, + {file = "backoff-1.11.1.tar.gz", hash = "sha256:ccb962a2378418c667b3c979b504fdeb7d9e0d29c0579e3b13b86467177728cb"}, +] + +[[package]] +name = "backports-tarfile" +version = "1.2.0" +description = "Backport of CPython tarfile module" +optional = false +python-versions = ">=3.8" +files = [ + {file = "backports.tarfile-1.2.0-py3-none-any.whl", hash = "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34"}, + {file = "backports_tarfile-1.2.0.tar.gz", hash = "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["jaraco.test", "pytest (!=8.0.*)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)"] + +[[package]] +name = "backports-zoneinfo" +version = "0.2.1" +description = "Backport of the standard library zoneinfo module" +optional = false +python-versions = ">=3.6" +files = [ + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, + {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, +] + +[package.extras] +tzdata = ["tzdata"] + +[[package]] +name = "backscatter" +version = "0.2.4" +description = "Client to interact with Backscatter.io services." +optional = false +python-versions = "*" +files = [ + {file = "backscatter-0.2.4-py3-none-any.whl", hash = "sha256:afb0efcf5d2551dac953ec4c38fb710b274b8e811775650e02c1ef42cafb14c8"}, + {file = "backscatter-0.2.4.tar.gz", hash = "sha256:7a0d1aa3661635de81e2a09b15d53e35cbe399a111cc58a70925f80e6874abd3"}, +] + +[package.dependencies] +requests = "*" +tabulate = "*" + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "bidict" +version = "0.23.1" +description = "The bidirectional mapping library for Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bidict-0.23.1-py3-none-any.whl", hash = "sha256:5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5"}, + {file = "bidict-0.23.1.tar.gz", hash = "sha256:03069d763bc387bbd20e7d49914e75fc4132a41937fa3405417e1a5a2d006d71"}, +] + +[[package]] +name = "blockchain" +version = "1.4.4" +description = "Blockchain API library (v1)" +optional = false +python-versions = "*" +files = [ + {file = "blockchain-1.4.4.tar.gz", hash = "sha256:dbaa3eebb6f81b4245005739da802c571b09f98d97eb66520afd95d9ccafebe2"}, +] + +[package.dependencies] +enum-compat = "*" +future = "*" + +[[package]] +name = "cachetools" +version = "5.5.0" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, +] + +[[package]] +name = "cattrs" +version = "23.2.3" +description = "Composable complex class support for attrs and dataclasses." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, + {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, +] + +[package.dependencies] +attrs = ">=23.1.0" +exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} + +[package.extras] +bson = ["pymongo (>=4.4.0)"] +cbor2 = ["cbor2 (>=5.4.6)"] +msgpack = ["msgpack (>=1.0.5)"] +orjson = ["orjson (>=3.9.2)"] +pyyaml = ["pyyaml (>=6.0)"] +tomlkit = ["tomlkit (>=0.11.8)"] +ujson = ["ujson (>=5.7.0)"] + +[[package]] +name = "censys" +version = "2.0.9" +description = "An easy-to-use and lightweight API wrapper for Censys APIs (censys.io)." +optional = false +python-versions = ">=3.6.2,<4.0" +files = [ + {file = "censys-2.0.9-py3-none-any.whl", hash = "sha256:ffda72c7b3172bf781660838d5f65a8babd9b083afd0aff862a7e335c90fb79a"}, + {file = "censys-2.0.9.tar.gz", hash = "sha256:5a062f2b97f806879896c6a2a350fd36cae5724ae240abf0c2de40895b043a61"}, +] + +[package.dependencies] +backoff = ">=1.11.1,<2.0.0" +requests = ">=2.26.0" +rich = ">=10.6.0,<11.0.0" + +[[package]] +name = "certifi" +version = "2024.7.4" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, +] + +[[package]] +name = "cffi" +version = "1.17.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, + {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, + {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, + {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, + {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, + {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, + {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, + {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, + {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, + {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, + {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, + {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, + {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, + {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, + {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, + {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, + {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, + {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, + {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, + {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, + {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"}, + {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"}, + {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"}, + {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, + {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, + {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, + {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, + {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "chardet" +version = "5.2.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "clamd" +version = "1.0.2" +description = "Clamd is a python interface to Clamd (Clamav daemon)." +optional = false +python-versions = "*" +files = [ + {file = "clamd-1.0.2-py2.py3-none-any.whl", hash = "sha256:5c32546b7d1eb00fd6be00a889d79e00fbf980ed082826ccfa369bce3dcff5e7"}, + {file = "clamd-1.0.2.tar.gz", hash = "sha256:d82a2fd814684a35a1b31feadafb2e69c8ebde9403613f6bdaa5d877c0f29560"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "click-default-group" +version = "1.2.4" +description = "click_default_group" +optional = false +python-versions = ">=2.7" +files = [ + {file = "click_default_group-1.2.4-py2.py3-none-any.whl", hash = "sha256:9b60486923720e7fc61731bdb32b617039aba820e22e1c88766b1125592eaa5f"}, + {file = "click_default_group-1.2.4.tar.gz", hash = "sha256:eb3f3c99ec0d456ca6cd2a7f08f7d4e91771bef51b01bdd9580cc6450fe1251e"}, +] + +[package.dependencies] +click = "*" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "click-plugins" +version = "1.1.1" +description = "An extension module for click to enable registering CLI commands via setuptools entry-points." +optional = false +python-versions = "*" +files = [ + {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, + {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, +] + +[package.dependencies] +click = ">=4.0" + +[package.extras] +dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] + +[[package]] +name = "click-repl" +version = "0.3.0" +description = "REPL plugin for Click" +optional = false +python-versions = ">=3.6" +files = [ + {file = "click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9"}, + {file = "click_repl-0.3.0-py3-none-any.whl", hash = "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812"}, +] + +[package.dependencies] +click = ">=7.0" +prompt-toolkit = ">=3.0.36" + +[package.extras] +testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] + +[[package]] +name = "codecov" +version = "2.1.13" +description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "codecov-2.1.13-py2.py3-none-any.whl", hash = "sha256:c2ca5e51bba9ebb43644c43d0690148a55086f7f5e6fd36170858fa4206744d5"}, + {file = "codecov-2.1.13.tar.gz", hash = "sha256:2362b685633caeaf45b9951a9b76ce359cd3581dd515b430c6c3f5dfb4d92a8c"}, +] + +[package.dependencies] +coverage = "*" +requests = ">=2.7.9" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "colorclass" +version = "2.2.2" +description = "Colorful worry-free console applications for Linux, Mac OS X, and Windows." +optional = false +python-versions = ">=2.6" +files = [ + {file = "colorclass-2.2.2-py2.py3-none-any.whl", hash = "sha256:6f10c273a0ef7a1150b1120b6095cbdd68e5cf36dfd5d0fc957a2500bbf99a55"}, + {file = "colorclass-2.2.2.tar.gz", hash = "sha256:6d4fe287766166a98ca7bc6f6312daf04a0481b1eda43e7173484051c0ab4366"}, +] + +[[package]] +name = "commonmark" +version = "0.9.1" +description = "Python parser for the CommonMark Markdown spec" +optional = false +python-versions = "*" +files = [ + {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, + {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, +] + +[package.extras] +test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] + +[[package]] +name = "compressed-rtf" +version = "1.0.6" +description = "Compressed Rich Text Format (RTF) compression and decompression package" +optional = false +python-versions = "*" +files = [ + {file = "compressed_rtf-1.0.6.tar.gz", hash = "sha256:c1c827f1d124d24608981a56e8b8691eb1f2a69a78ccad6440e7d92fde1781dd"}, +] + +[[package]] +name = "configparser" +version = "7.1.0" +description = "Updated configparser from stdlib for earlier Pythons." +optional = false +python-versions = ">=3.8" +files = [ + {file = "configparser-7.1.0-py3-none-any.whl", hash = "sha256:98e374573c4e10e92399651e3ba1c47a438526d633c44ee96143dec26dad4299"}, + {file = "configparser-7.1.0.tar.gz", hash = "sha256:eb82646c892dbdf773dae19c633044d163c3129971ae09b49410a303b8e0a5f7"}, +] + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "types-backports"] + +[[package]] +name = "contourpy" +version = "1.1.1" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.8" +files = [ + {file = "contourpy-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:46e24f5412c948d81736509377e255f6040e94216bf1a9b5ea1eaa9d29f6ec1b"}, + {file = "contourpy-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e48694d6a9c5a26ee85b10130c77a011a4fedf50a7279fa0bdaf44bafb4299d"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66045af6cf00e19d02191ab578a50cb93b2028c3eefed999793698e9ea768ae"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ebf42695f75ee1a952f98ce9775c873e4971732a87334b099dde90b6af6a916"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6aec19457617ef468ff091669cca01fa7ea557b12b59a7908b9474bb9674cf0"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:462c59914dc6d81e0b11f37e560b8a7c2dbab6aca4f38be31519d442d6cde1a1"}, + {file = "contourpy-1.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6d0a8efc258659edc5299f9ef32d8d81de8b53b45d67bf4bfa3067f31366764d"}, + {file = "contourpy-1.1.1-cp310-cp310-win32.whl", hash = "sha256:d6ab42f223e58b7dac1bb0af32194a7b9311065583cc75ff59dcf301afd8a431"}, + {file = "contourpy-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:549174b0713d49871c6dee90a4b499d3f12f5e5f69641cd23c50a4542e2ca1eb"}, + {file = "contourpy-1.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:407d864db716a067cc696d61fa1ef6637fedf03606e8417fe2aeed20a061e6b2"}, + {file = "contourpy-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe80c017973e6a4c367e037cb31601044dd55e6bfacd57370674867d15a899b"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e30aaf2b8a2bac57eb7e1650df1b3a4130e8d0c66fc2f861039d507a11760e1b"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3de23ca4f381c3770dee6d10ead6fff524d540c0f662e763ad1530bde5112532"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:566f0e41df06dfef2431defcfaa155f0acfa1ca4acbf8fd80895b1e7e2ada40e"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b04c2f0adaf255bf756cf08ebef1be132d3c7a06fe6f9877d55640c5e60c72c5"}, + {file = "contourpy-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d0c188ae66b772d9d61d43c6030500344c13e3f73a00d1dc241da896f379bb62"}, + {file = "contourpy-1.1.1-cp311-cp311-win32.whl", hash = "sha256:0683e1ae20dc038075d92e0e0148f09ffcefab120e57f6b4c9c0f477ec171f33"}, + {file = "contourpy-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:8636cd2fc5da0fb102a2504fa2c4bea3cbc149533b345d72cdf0e7a924decc45"}, + {file = "contourpy-1.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:560f1d68a33e89c62da5da4077ba98137a5e4d3a271b29f2f195d0fba2adcb6a"}, + {file = "contourpy-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24216552104ae8f3b34120ef84825400b16eb6133af2e27a190fdc13529f023e"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56de98a2fb23025882a18b60c7f0ea2d2d70bbbcfcf878f9067234b1c4818442"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:07d6f11dfaf80a84c97f1a5ba50d129d9303c5b4206f776e94037332e298dda8"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1eaac5257a8f8a047248d60e8f9315c6cff58f7803971170d952555ef6344a7"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19557fa407e70f20bfaba7d55b4d97b14f9480856c4fb65812e8a05fe1c6f9bf"}, + {file = "contourpy-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:081f3c0880712e40effc5f4c3b08feca6d064cb8cfbb372ca548105b86fd6c3d"}, + {file = "contourpy-1.1.1-cp312-cp312-win32.whl", hash = "sha256:059c3d2a94b930f4dafe8105bcdc1b21de99b30b51b5bce74c753686de858cb6"}, + {file = "contourpy-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f44d78b61740e4e8c71db1cf1fd56d9050a4747681c59ec1094750a658ceb970"}, + {file = "contourpy-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:70e5a10f8093d228bb2b552beeb318b8928b8a94763ef03b858ef3612b29395d"}, + {file = "contourpy-1.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8394e652925a18ef0091115e3cc191fef350ab6dc3cc417f06da66bf98071ae9"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bd5680f844c3ff0008523a71949a3ff5e4953eb7701b28760805bc9bcff217"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66544f853bfa85c0d07a68f6c648b2ec81dafd30f272565c37ab47a33b220684"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0c02b75acfea5cab07585d25069207e478d12309557f90a61b5a3b4f77f46ce"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41339b24471c58dc1499e56783fedc1afa4bb018bcd035cfb0ee2ad2a7501ef8"}, + {file = "contourpy-1.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f29fb0b3f1217dfe9362ec55440d0743fe868497359f2cf93293f4b2701b8251"}, + {file = "contourpy-1.1.1-cp38-cp38-win32.whl", hash = "sha256:f9dc7f933975367251c1b34da882c4f0e0b2e24bb35dc906d2f598a40b72bfc7"}, + {file = "contourpy-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:498e53573e8b94b1caeb9e62d7c2d053c263ebb6aa259c81050766beb50ff8d9"}, + {file = "contourpy-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ba42e3810999a0ddd0439e6e5dbf6d034055cdc72b7c5c839f37a7c274cb4eba"}, + {file = "contourpy-1.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c06e4c6e234fcc65435223c7b2a90f286b7f1b2733058bdf1345d218cc59e34"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca6fab080484e419528e98624fb5c4282148b847e3602dc8dbe0cb0669469887"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93df44ab351119d14cd1e6b52a5063d3336f0754b72736cc63db59307dabb718"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eafbef886566dc1047d7b3d4b14db0d5b7deb99638d8e1be4e23a7c7ac59ff0f"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efe0fab26d598e1ec07d72cf03eaeeba8e42b4ecf6b9ccb5a356fde60ff08b85"}, + {file = "contourpy-1.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f08e469821a5e4751c97fcd34bcb586bc243c39c2e39321822060ba902eac49e"}, + {file = "contourpy-1.1.1-cp39-cp39-win32.whl", hash = "sha256:bfc8a5e9238232a45ebc5cb3bfee71f1167064c8d382cadd6076f0d51cff1da0"}, + {file = "contourpy-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:c84fdf3da00c2827d634de4fcf17e3e067490c4aea82833625c4c8e6cdea0887"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:229a25f68046c5cf8067d6d6351c8b99e40da11b04d8416bf8d2b1d75922521e"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10dab5ea1bd4401c9483450b5b0ba5416be799bbd50fc7a6cc5e2a15e03e8a3"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f9147051cb8fdb29a51dc2482d792b3b23e50f8f57e3720ca2e3d438b7adf23"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a75cc163a5f4531a256f2c523bd80db509a49fc23721b36dd1ef2f60ff41c3cb"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b53d5769aa1f2d4ea407c65f2d1d08002952fac1d9e9d307aa2e1023554a163"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11b836b7dbfb74e049c302bbf74b4b8f6cb9d0b6ca1bf86cfa8ba144aedadd9c"}, + {file = "contourpy-1.1.1.tar.gz", hash = "sha256:96ba37c2e24b7212a77da85004c38e7c4d155d3e72a45eeaf22c1f03f607e8ab"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.16,<2.0", markers = "python_version <= \"3.11\""}, + {version = ">=1.26.0rc1,<2.0", markers = "python_version >= \"3.12\""}, +] + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.4.1)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "wurlitzer"] + +[[package]] +name = "coverage" +version = "7.6.1" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, + {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, + {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, +] + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "crowdstrike-falconpy" +version = "1.4.5" +description = "The CrowdStrike Falcon SDK for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "crowdstrike_falconpy-1.4.5-py3-none-any.whl", hash = "sha256:854b3d0d2aa97411ceba6503dc11368edab26f5536988200b2c4ad88f57c87bb"}, + {file = "crowdstrike_falconpy-1.4.5.tar.gz", hash = "sha256:b33be3667d82c9a05c8b99c9d765f9d1510856275561c8eee581f3b6131ef2f6"}, +] + +[package.dependencies] +requests = "*" +urllib3 = "*" + +[package.extras] +dev = ["bandit", "coverage", "flake8", "pydocstyle", "pylint", "pytest", "pytest-cov", "setuptools (>=70.3.0,<70.4.0)"] + +[[package]] +name = "cryptography" +version = "43.0.0" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf"}, + {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55"}, + {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431"}, + {file = "cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc"}, + {file = "cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778"}, + {file = "cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f"}, + {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"}, + {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b"}, + {file = "cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf"}, + {file = "cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1"}, + {file = "cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] +nox = ["nox"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi", "cryptography-vectors (==43.0.0)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "deprecated" +version = "1.2.14" +description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, +] + +[package.dependencies] +wrapt = ">=1.10,<2" + +[package.extras] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] + +[[package]] +name = "dict2xml" +version = "1.7.6" +description = "Small utility to convert a python dictionary into an XML string" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dict2xml-1.7.6-py3-none-any.whl", hash = "sha256:841a0c1720e4bfa121e958b805f1062fccf5af2970e7a1f81d7fa056f49e5065"}, + {file = "dict2xml-1.7.6.tar.gz", hash = "sha256:3e4811f4ef7fca86dede6acf382268ff9bc5735a4aa0e21b465f6eb0c4e81732"}, +] + +[package.extras] +tests = ["noseofyeti[black] (==2.4.9)", "pytest (==8.3.2)"] + +[[package]] +name = "dnsdb2" +version = "1.1.4" +description = "Client for DNSDB API version 2 with Flexible Search" +optional = false +python-versions = "*" +files = [ + {file = "dnsdb2-1.1.4.tar.gz", hash = "sha256:428e9808f5e3fcdaeacc40edc9d5d14837a20fa7f11b87543348ef285b87af5a"}, +] + +[package.dependencies] +requests = "*" + +[package.extras] +test = ["requests-mock"] + +[[package]] +name = "dnspython" +version = "2.6.1" +description = "DNS toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50"}, + {file = "dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc"}, +] + +[package.extras] +dev = ["black (>=23.1.0)", "coverage (>=7.0)", "flake8 (>=7)", "mypy (>=1.8)", "pylint (>=3)", "pytest (>=7.4)", "pytest-cov (>=4.1.0)", "sphinx (>=7.2.0)", "twine (>=4.0.0)", "wheel (>=0.42.0)"] +dnssec = ["cryptography (>=41)"] +doh = ["h2 (>=4.1.0)", "httpcore (>=1.0.0)", "httpx (>=0.26.0)"] +doq = ["aioquic (>=0.9.25)"] +idna = ["idna (>=3.6)"] +trio = ["trio (>=0.23)"] +wmi = ["wmi (>=1.5.1)"] + +[[package]] +name = "domaintools-api" +version = "2.0.0" +description = "DomainTools Official Python API" +optional = false +python-versions = ">=3.6" +files = [ + {file = "domaintools_api-2.0.0-py2.py3-none-any.whl", hash = "sha256:5dd0174529b22399fe6d2c034bb76a17e078b56ff64961c2340863355641e241"}, + {file = "domaintools_api-2.0.0.tar.gz", hash = "sha256:f0d1c59af17c6bc74525ba0e660f22239a823d9901aa87f4887317efbeb0aa31"}, +] + +[package.dependencies] +httpx = "*" +rich = "*" +typer = "*" + +[package.extras] +test = ["mock", "pytest"] + +[[package]] +name = "easygui" +version = "0.98.3" +description = "EasyGUI is a module for very simple, very easy GUI programming in Python. EasyGUI is different from other GUI generators in that EasyGUI is NOT event-driven. Instead, all GUI interactions are invoked by simple function calls." +optional = false +python-versions = "*" +files = [ + {file = "easygui-0.98.3-py2.py3-none-any.whl", hash = "sha256:33498710c68b5376b459cd3fc48d1d1f33822139eb3ed01defbc0528326da3ba"}, + {file = "easygui-0.98.3.tar.gz", hash = "sha256:d653ff79ee1f42f63b5a090f2f98ce02335d86ad8963b3ce2661805cafe99a04"}, +] + +[[package]] +name = "ebcdic" +version = "1.1.1" +description = "Additional EBCDIC codecs" +optional = false +python-versions = "*" +files = [ + {file = "ebcdic-1.1.1-py2.py3-none-any.whl", hash = "sha256:33b4cb729bc2d0bf46cc1847b0e5946897cb8d3f53520c5b9aa5fa98d7e735f1"}, +] + +[[package]] +name = "enum-compat" +version = "0.0.3" +description = "enum/enum34 compatibility package" +optional = false +python-versions = "*" +files = [ + {file = "enum-compat-0.0.3.tar.gz", hash = "sha256:3677daabed56a6f724451d585662253d8fb4e5569845aafa8bb0da36b1a8751e"}, + {file = "enum_compat-0.0.3-py3-none-any.whl", hash = "sha256:88091b617c7fc3bbbceae50db5958023c48dc40b50520005aa3bf27f8f7ea157"}, +] + +[[package]] +name = "et-xmlfile" +version = "1.1.0" +description = "An implementation of lxml.xmlfile for the standard library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, + {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "extract-msg" +version = "0.48.7" +description = "Extracts emails and attachments saved in Microsoft Outlook's .msg files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "extract_msg-0.48.7-py3-none-any.whl", hash = "sha256:0477489aa2ac417387803f19fa53ddc44136846a648b0898a114212272a1a111"}, + {file = "extract_msg-0.48.7.tar.gz", hash = "sha256:3ddf015c0e0a6ea36026fedfb7f8e434ca37150a31069363b2d0752196d15b6e"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.11.1,<4.13" +compressed-rtf = ">=1.0.6,<2" +ebcdic = ">=1.1.1,<2" +olefile = "0.47" +red-black-tree-mod = "1.20" +RTFDE = ">=0.1.1,<0.2" +tzlocal = ">=4.2,<6" + +[package.extras] +all = ["extract-msg[encoding]", "extract-msg[image]", "extract-msg[mime]"] +encoding = ["chardet (>=3.0.0,<6)"] +image = ["Pillow (>=9.5.0,<10)"] +mime = ["python-magic (>=0.4.27,<0.5)"] +readthedocs = ["sphinx-rtd-theme"] + +[[package]] +name = "ezodf" +version = "0.3.2" +description = "A Python package to create/manipulate OpenDocumentFormat files." +optional = false +python-versions = "*" +files = [ + {file = "ezodf-0.3.2.tar.gz", hash = "sha256:000da534f689c6d55297a08f9e2ed7eada9810d194d31d164388162fb391122d"}, +] + +[[package]] +name = "fake-useragent" +version = "1.5.1" +description = "Up-to-date simple useragent faker with real world database" +optional = false +python-versions = "*" +files = [ + {file = "fake-useragent-1.5.1.tar.gz", hash = "sha256:6387269f5a2196b5ba7ed8935852f75486845a1c95c50e72460e6a8e762f5c49"}, + {file = "fake_useragent-1.5.1-py3-none-any.whl", hash = "sha256:57415096557c8a4e23b62a375c21c55af5fd4ba30549227f562d2c4f5b60e3b3"}, +] + +[package.dependencies] +importlib-resources = {version = ">=5.0", markers = "python_version < \"3.10\""} + +[[package]] +name = "filelock" +version = "3.15.4" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"}, + {file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] +typing = ["typing-extensions (>=4.8)"] + +[[package]] +name = "flake8" +version = "5.0.4" +description = "the modular source code checker: pep8 pyflakes and co" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, + {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, +] + +[package.dependencies] +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.9.0,<2.10.0" +pyflakes = ">=2.5.0,<2.6.0" + +[[package]] +name = "fonttools" +version = "4.53.1" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.1.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + +[[package]] +name = "frozenlist" +version = "1.4.1" +description = "A list-like structure which implements collections.abc.MutableSequence" +optional = false +python-versions = ">=3.8" +files = [ + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, + {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, + {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, + {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, + {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, + {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, + {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, + {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, + {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, + {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, + {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, + {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, + {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, +] + +[[package]] +name = "future" +version = "1.0.0" +description = "Clean single-source support for Python 3 and 2" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"}, + {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, +] + +[[package]] +name = "geoip2" +version = "4.8.0" +description = "MaxMind GeoIP2 API" +optional = false +python-versions = ">=3.8" +files = [ + {file = "geoip2-4.8.0-py2.py3-none-any.whl", hash = "sha256:39b38ec703575355d10475c0e6aa981827a2b4b5471d308c4ecb5e79cbe366ce"}, + {file = "geoip2-4.8.0.tar.gz", hash = "sha256:dd9cc180b7d41724240ea481d5d539149e65b234f64282b231b9170794a9ac35"}, +] + +[package.dependencies] +aiohttp = ">=3.6.2,<4.0.0" +maxminddb = ">=2.5.1,<3.0.0" +requests = ">=2.24.0,<3.0.0" +setuptools = ">=60.0.0" + +[package.extras] +test = ["mocket (>=3.11.1)"] + +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +optional = false +python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + +[[package]] +name = "Google-Search-API" +version = "1.1.14" +description = "Search in google" +optional = false +python-versions = "*" +files = [] +develop = false + +[package.dependencies] +beautifulsoup4 = "*" +fake-useragent = "*" +future = "*" +requests = "*" +selenium = ">=2.44.0,<3.0.0" +unidecode = "*" +vcrpy = "*" + +[package.source] +type = "git" +url = "https://github.com/abenassi/Google-Search-API" +reference = "HEAD" +resolved_reference = "546a59cc22d3260c60a2faf9afe6477168ead627" + +[[package]] +name = "greynoise" +version = "2.3.0" +description = "Abstraction to interact with GreyNoise API." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=3.0" +files = [ + {file = "greynoise-2.3.0-py3-none-any.whl", hash = "sha256:92a9471fa98a9a3c0c9e93a15cb990dab963e2e3f1ceb1a200785906be24d4fd"}, + {file = "greynoise-2.3.0.tar.gz", hash = "sha256:b33bf61db840ff3e62a2fd987dfb01fe32d23f23e6fc21b002b214529daf11d8"}, +] + +[package.dependencies] +ansimarkup = "*" +cachetools = "*" +Click = ">=8.0.0" +click-default-group = "*" +click-repl = "*" +colorama = "*" +dict2xml = "*" +jinja2 = "*" +more-itertools = ">=8.14.0" +requests = "*" +six = "*" + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.5" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, + {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.26.0)"] + +[[package]] +name = "httplib2" +version = "0.22.0" +description = "A comprehensive HTTP client library." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "httplib2-0.22.0-py3-none-any.whl", hash = "sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc"}, + {file = "httplib2-0.22.0.tar.gz", hash = "sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81"}, +] + +[package.dependencies] +pyparsing = {version = ">=2.4.2,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.0.2 || >3.0.2,<3.0.3 || >3.0.3,<4", markers = "python_version > \"3.0\""} + +[[package]] +name = "httpx" +version = "0.27.0" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, + {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + +[[package]] +name = "idna" +version = "3.8" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, +] + +[[package]] +name = "importlib-metadata" +version = "8.4.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, + {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] + +[[package]] +name = "importlib-resources" +version = "6.4.4" +description = "Read resources from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_resources-6.4.4-py3-none-any.whl", hash = "sha256:dda242603d1c9cd836c3368b1174ed74cb4049ecd209e7a1a0104620c18c5c11"}, + {file = "importlib_resources-6.4.4.tar.gz", hash = "sha256:20600c8b7361938dc0bb2d5ec0297802e575df486f5a544fa414da65e13721f7"}, +] + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "zipp (>=3.17)"] +type = ["pytest-mypy"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" +optional = false +python-versions = "*" +files = [ + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "jaraco-classes" +version = "3.4.0" +description = "Utility functions for Python class constructs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jaraco.classes-3.4.0-py3-none-any.whl", hash = "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790"}, + {file = "jaraco.classes-3.4.0.tar.gz", hash = "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd"}, +] + +[package.dependencies] +more-itertools = "*" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + +[[package]] +name = "jaraco-context" +version = "6.0.1" +description = "Useful decorators and context managers" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jaraco.context-6.0.1-py3-none-any.whl", hash = "sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4"}, + {file = "jaraco_context-6.0.1.tar.gz", hash = "sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3"}, +] + +[package.dependencies] +"backports.tarfile" = {version = "*", markers = "python_version < \"3.12\""} + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["portend", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + +[[package]] +name = "jaraco-functools" +version = "4.0.2" +description = "Functools like those found in stdlib" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jaraco.functools-4.0.2-py3-none-any.whl", hash = "sha256:c9d16a3ed4ccb5a889ad8e0b7a343401ee5b2a71cee6ed192d3f68bc351e94e3"}, + {file = "jaraco_functools-4.0.2.tar.gz", hash = "sha256:3460c74cd0d32bf82b9576bbb3527c4364d5b27a21f5158a62aed6c4b42e23f5"}, +] + +[package.dependencies] +more-itertools = "*" + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["jaraco.classes", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + +[[package]] +name = "jbxapi" +version = "3.23.0" +description = "API for Joe Sandbox" +optional = false +python-versions = "!=3.0,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "jbxapi-3.23.0-py2.py3-none-any.whl", hash = "sha256:bf50e59ce542013bcd5ec9dd6a1c23f331301b053cce27296c6149af7bbc65e2"}, + {file = "jbxapi-3.23.0.tar.gz", hash = "sha256:200590caaa5cfb64ffb36388e6af64d9d9dd83be02155e4a0c64ccbc1cba0b04"}, +] + +[package.dependencies] +pyzipper = {version = ">=0.3.1", markers = "python_version >= \"3.5\""} +requests = ">=2.18.4,<3" + +[[package]] +name = "jeepney" +version = "0.8.0" +description = "Low-level, pure Python DBus protocol wrapper." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"}, + {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"}, +] + +[package.extras] +test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] +trio = ["async_generator", "trio"] + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "json-log-formatter" +version = "1.0" +description = "JSON log formatter" +optional = false +python-versions = ">=3.6" +files = [ + {file = "JSON-log-formatter-1.0.tar.gz", hash = "sha256:fda3f943a2cddc4c8b0f06d57db5c53a903a1d4b6fc62416339d109e8c482ef7"}, +] + +[[package]] +name = "jsonschema" +version = "4.23.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +jsonschema-specifications = ">=2023.03.6" +pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] + +[package.dependencies] +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +referencing = ">=0.31.0" + +[[package]] +name = "keyring" +version = "25.3.0" +description = "Store and access your passwords safely." +optional = false +python-versions = ">=3.8" +files = [ + {file = "keyring-25.3.0-py3-none-any.whl", hash = "sha256:8d963da00ccdf06e356acd9bf3b743208878751032d8599c6cc89eb51310ffae"}, + {file = "keyring-25.3.0.tar.gz", hash = "sha256:8d85a1ea5d6db8515b59e1c5d1d1678b03cf7fc8b8dcfb1651e8c4a524eb42ef"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.11.4", markers = "python_version < \"3.12\""} +importlib-resources = {version = "*", markers = "python_version < \"3.9\""} +"jaraco.classes" = "*" +"jaraco.context" = "*" +"jaraco.functools" = "*" +jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} +pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""} +SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} + +[package.extras] +completion = ["shtab (>=1.1.0)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + +[[package]] +name = "kiwisolver" +version = "1.4.5" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.7" +files = [ + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, + {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, +] + +[[package]] +name = "lark" +version = "1.1.9" +description = "a modern parsing library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "lark-1.1.9-py3-none-any.whl", hash = "sha256:a0dd3a87289f8ccbb325901e4222e723e7d745dbfc1803eaf5f3d2ace19cf2db"}, + {file = "lark-1.1.9.tar.gz", hash = "sha256:15fa5236490824c2c4aba0e22d2d6d823575dcaf4cdd1848e34b6ad836240fba"}, +] + +[package.extras] +atomic-cache = ["atomicwrites"] +interegular = ["interegular (>=0.3.1,<0.4.0)"] +nearley = ["js2py"] +regex = ["regex"] + +[[package]] +name = "lief" +version = "0.15.1" +description = "Library to instrument executable formats" +optional = false +python-versions = ">=3.8" +files = [ + {file = "lief-0.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a80246b96501b2b1d4927ceb3cb817eda9333ffa9e07101358929a6cffca5dae"}, + {file = "lief-0.15.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:84bf310710369544e2bb82f83d7fdab5b5ac422651184fde8bf9e35f14439691"}, + {file = "lief-0.15.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8fb58efb77358291109d2675d5459399c0794475b497992d0ecee18a4a46a207"}, + {file = "lief-0.15.1-cp310-cp310-manylinux_2_33_aarch64.whl", hash = "sha256:d5852a246361bbefa4c1d5930741765a2337638d65cfe30de1b7d61f9a54b865"}, + {file = "lief-0.15.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:12e53dc0253c303df386ae45487a2f0078026602b36d0e09e838ae1d4dbef958"}, + {file = "lief-0.15.1-cp310-cp310-win32.whl", hash = "sha256:38b9cee48f42c355359ad7e3ff18bf1ec95e518238e4e8fb25657a49169dbf4c"}, + {file = "lief-0.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ddf2ebd73766169594d631b35f84c49ef42871de552ad49f36002c60164d0aca"}, + {file = "lief-0.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20508c52de0dffcee3242253541609590167a3e56150cbacb506fdbb822206ef"}, + {file = "lief-0.15.1-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:0750c892fd3b7161a3c2279f25fe1844427610c3a5a4ae23f65674ced6f93ea5"}, + {file = "lief-0.15.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a8634ea79d6d9862297fadce025519ab25ff01fcadb333cf42967c6295f0d057"}, + {file = "lief-0.15.1-cp311-cp311-manylinux_2_33_aarch64.whl", hash = "sha256:1e11e046ad71fe8c81e1a8d1d207fe2b99c967d33ce79c3d3915cb8f5ecacf52"}, + {file = "lief-0.15.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:674b620cdf1d686f52450fd97c1056d4c92e55af8217ce85a1b2efaf5b32140b"}, + {file = "lief-0.15.1-cp311-cp311-win32.whl", hash = "sha256:dbdcd70fd23c90017705b7fe6c716f0a69c01d0d0ea7a2ff653d83dc4a61fefb"}, + {file = "lief-0.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:e9b96a37bf11ca777ff305d85d957eabad2a92a6e577b6e2fb3ab79514e5a12e"}, + {file = "lief-0.15.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1a96f17c2085ef38d12ad81427ae8a5d6ad76f0bc62a1e1f5fe384255cd2cc94"}, + {file = "lief-0.15.1-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:d780af1762022b8e01b613253af490afea3864fbd6b5a49c6de7cea8fde0443d"}, + {file = "lief-0.15.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d0f10d80202de9634a16786b53ba3a8f54ae8b9a9e124a964d83212444486087"}, + {file = "lief-0.15.1-cp312-cp312-manylinux_2_33_aarch64.whl", hash = "sha256:864f17ecf1736296e6d5fc38b11983f9d19a5e799f094e21e20d58bfb1b95b80"}, + {file = "lief-0.15.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c2ec738bcafee8a569741f4a749f0596823b12f10713306c7d0cbbf85759f51c"}, + {file = "lief-0.15.1-cp312-cp312-win32.whl", hash = "sha256:db38619edf70e27fb3686b8c0f0bec63ad494ac88ab51660c5ecd2720b506e41"}, + {file = "lief-0.15.1-cp312-cp312-win_amd64.whl", hash = "sha256:28bf0922de5fb74502a29cc47930d3a052df58dc23ab6519fa590e564f194a60"}, + {file = "lief-0.15.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:0616e6048f269d262ff93d67c497ebff3c1d3965ffb9427b0f2b474764fd2e8c"}, + {file = "lief-0.15.1-cp313-cp313-manylinux_2_33_aarch64.whl", hash = "sha256:6a08b2e512a80040429febddc777768c949bcd53f6f580e902e41ec0d9d936b8"}, + {file = "lief-0.15.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fcd489ff80860bcc2b2689faa330a46b6d66f0ee3e0f6ef9e643e2b996128a06"}, + {file = "lief-0.15.1-cp313-cp313-win32.whl", hash = "sha256:0d10e5b22e86bbf2d1e3877b604ffd8860c852b6bc00fca681fe1432f5018fe9"}, + {file = "lief-0.15.1-cp313-cp313-win_amd64.whl", hash = "sha256:5af7dcb9c3f44baaf60875df6ba9af6777db94776cc577ee86143bcce105ba2f"}, + {file = "lief-0.15.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9757ff0c7c3d6f66e5fdcc6a9df69680fad0dc2707d64a3428f0825dfce1a85"}, + {file = "lief-0.15.1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:8ac3cd099be2580d0e15150b1d2f5095c38f150af89993ddf390d7897ee8135f"}, + {file = "lief-0.15.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:4dedeab498c312a29b58f16b739895f65fa54b2a21b8d98b111e99ad3f7e30a8"}, + {file = "lief-0.15.1-cp38-cp38-manylinux_2_33_aarch64.whl", hash = "sha256:b9217578f7a45f667503b271da8481207fb4edda8d4a53e869fb922df6030484"}, + {file = "lief-0.15.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:82e6308ad8bd4bc7eadee3502ede13a5bb398725f25513a0396c8dba850f58a1"}, + {file = "lief-0.15.1-cp38-cp38-win32.whl", hash = "sha256:dde1c8f8ebe0ee9db4f2302c87ae3cacb9898dc412e0d7da07a8e4e834ac5158"}, + {file = "lief-0.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:a079a76bca23aa73c850ab5beb7598871a1bf44662658b952cead2b5ddd31bee"}, + {file = "lief-0.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:785a3aa14575f046ed9c8d44ea222ea14c697cd03b5331d1717b5b0cf4f72466"}, + {file = "lief-0.15.1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:d7044553cf07c8a2ab6e21874f07585610d996ff911b9af71dc6085a89f59daa"}, + {file = "lief-0.15.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:13285c3ff5ef6de2421d85684c954905af909db0ad3472e33c475e5f0f657dcf"}, + {file = "lief-0.15.1-cp39-cp39-manylinux_2_33_aarch64.whl", hash = "sha256:932f880ee8a130d663a97a9099516d8570b1b303af7816e70a02f9931d5ef4c2"}, + {file = "lief-0.15.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:de9453f94866e0f2c36b6bd878625880080e7e5800788f5cbc06a76debf283b9"}, + {file = "lief-0.15.1-cp39-cp39-win32.whl", hash = "sha256:4e47324736d6aa559421720758de4ce12d04fb56bdffa3dcc051fe8cdd42ed17"}, + {file = "lief-0.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:382a189514c0e6ebfb41e0db6106936c7ba94d8400651276add2899ff3570585"}, +] + +[[package]] +name = "lxml" +version = "4.9.4" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" +files = [ + {file = "lxml-4.9.4-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e214025e23db238805a600f1f37bf9f9a15413c7bf5f9d6ae194f84980c78722"}, + {file = "lxml-4.9.4-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ec53a09aee61d45e7dbe7e91252ff0491b6b5fee3d85b2d45b173d8ab453efc1"}, + {file = "lxml-4.9.4-cp27-cp27m-win32.whl", hash = "sha256:7d1d6c9e74c70ddf524e3c09d9dc0522aba9370708c2cb58680ea40174800013"}, + {file = "lxml-4.9.4-cp27-cp27m-win_amd64.whl", hash = "sha256:cb53669442895763e61df5c995f0e8361b61662f26c1b04ee82899c2789c8f69"}, + {file = "lxml-4.9.4-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:647bfe88b1997d7ae8d45dabc7c868d8cb0c8412a6e730a7651050b8c7289cf2"}, + {file = "lxml-4.9.4-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4d973729ce04784906a19108054e1fd476bc85279a403ea1a72fdb051c76fa48"}, + {file = "lxml-4.9.4-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:056a17eaaf3da87a05523472ae84246f87ac2f29a53306466c22e60282e54ff8"}, + {file = "lxml-4.9.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:aaa5c173a26960fe67daa69aa93d6d6a1cd714a6eb13802d4e4bd1d24a530644"}, + {file = "lxml-4.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:647459b23594f370c1c01768edaa0ba0959afc39caeeb793b43158bb9bb6a663"}, + {file = "lxml-4.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:bdd9abccd0927673cffe601d2c6cdad1c9321bf3437a2f507d6b037ef91ea307"}, + {file = "lxml-4.9.4-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:00e91573183ad273e242db5585b52670eddf92bacad095ce25c1e682da14ed91"}, + {file = "lxml-4.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a602ed9bd2c7d85bd58592c28e101bd9ff9c718fbde06545a70945ffd5d11868"}, + {file = "lxml-4.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:de362ac8bc962408ad8fae28f3967ce1a262b5d63ab8cefb42662566737f1dc7"}, + {file = "lxml-4.9.4-cp310-cp310-win32.whl", hash = "sha256:33714fcf5af4ff7e70a49731a7cc8fd9ce910b9ac194f66eaa18c3cc0a4c02be"}, + {file = "lxml-4.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:d3caa09e613ece43ac292fbed513a4bce170681a447d25ffcbc1b647d45a39c5"}, + {file = "lxml-4.9.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:359a8b09d712df27849e0bcb62c6a3404e780b274b0b7e4c39a88826d1926c28"}, + {file = "lxml-4.9.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:43498ea734ccdfb92e1886dfedaebeb81178a241d39a79d5351ba2b671bff2b2"}, + {file = "lxml-4.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4855161013dfb2b762e02b3f4d4a21cc7c6aec13c69e3bffbf5022b3e708dd97"}, + {file = "lxml-4.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c71b5b860c5215fdbaa56f715bc218e45a98477f816b46cfde4a84d25b13274e"}, + {file = "lxml-4.9.4-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9a2b5915c333e4364367140443b59f09feae42184459b913f0f41b9fed55794a"}, + {file = "lxml-4.9.4-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d82411dbf4d3127b6cde7da0f9373e37ad3a43e89ef374965465928f01c2b979"}, + {file = "lxml-4.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:273473d34462ae6e97c0f4e517bd1bf9588aa67a1d47d93f760a1282640e24ac"}, + {file = "lxml-4.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:389d2b2e543b27962990ab529ac6720c3dded588cc6d0f6557eec153305a3622"}, + {file = "lxml-4.9.4-cp311-cp311-win32.whl", hash = "sha256:8aecb5a7f6f7f8fe9cac0bcadd39efaca8bbf8d1bf242e9f175cbe4c925116c3"}, + {file = "lxml-4.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:c7721a3ef41591341388bb2265395ce522aba52f969d33dacd822da8f018aff8"}, + {file = "lxml-4.9.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:dbcb2dc07308453db428a95a4d03259bd8caea97d7f0776842299f2d00c72fc8"}, + {file = "lxml-4.9.4-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:01bf1df1db327e748dcb152d17389cf6d0a8c5d533ef9bab781e9d5037619229"}, + {file = "lxml-4.9.4-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e8f9f93a23634cfafbad6e46ad7d09e0f4a25a2400e4a64b1b7b7c0fbaa06d9d"}, + {file = "lxml-4.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3f3f00a9061605725df1816f5713d10cd94636347ed651abdbc75828df302b20"}, + {file = "lxml-4.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:953dd5481bd6252bd480d6ec431f61d7d87fdcbbb71b0d2bdcfc6ae00bb6fb10"}, + {file = "lxml-4.9.4-cp312-cp312-win32.whl", hash = "sha256:266f655d1baff9c47b52f529b5f6bec33f66042f65f7c56adde3fcf2ed62ae8b"}, + {file = "lxml-4.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:f1faee2a831fe249e1bae9cbc68d3cd8a30f7e37851deee4d7962b17c410dd56"}, + {file = "lxml-4.9.4-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:23d891e5bdc12e2e506e7d225d6aa929e0a0368c9916c1fddefab88166e98b20"}, + {file = "lxml-4.9.4-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e96a1788f24d03e8d61679f9881a883ecdf9c445a38f9ae3f3f193ab6c591c66"}, + {file = "lxml-4.9.4-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:5557461f83bb7cc718bc9ee1f7156d50e31747e5b38d79cf40f79ab1447afd2d"}, + {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:fdb325b7fba1e2c40b9b1db407f85642e32404131c08480dd652110fc908561b"}, + {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d74d4a3c4b8f7a1f676cedf8e84bcc57705a6d7925e6daef7a1e54ae543a197"}, + {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ac7674d1638df129d9cb4503d20ffc3922bd463c865ef3cb412f2c926108e9a4"}, + {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:ddd92e18b783aeb86ad2132d84a4b795fc5ec612e3545c1b687e7747e66e2b53"}, + {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bd9ac6e44f2db368ef8986f3989a4cad3de4cd55dbdda536e253000c801bcc7"}, + {file = "lxml-4.9.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:bc354b1393dce46026ab13075f77b30e40b61b1a53e852e99d3cc5dd1af4bc85"}, + {file = "lxml-4.9.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f836f39678cb47c9541f04d8ed4545719dc31ad850bf1832d6b4171e30d65d23"}, + {file = "lxml-4.9.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:9c131447768ed7bc05a02553d939e7f0e807e533441901dd504e217b76307745"}, + {file = "lxml-4.9.4-cp36-cp36m-win32.whl", hash = "sha256:bafa65e3acae612a7799ada439bd202403414ebe23f52e5b17f6ffc2eb98c2be"}, + {file = "lxml-4.9.4-cp36-cp36m-win_amd64.whl", hash = "sha256:6197c3f3c0b960ad033b9b7d611db11285bb461fc6b802c1dd50d04ad715c225"}, + {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:7b378847a09d6bd46047f5f3599cdc64fcb4cc5a5a2dd0a2af610361fbe77b16"}, + {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:1343df4e2e6e51182aad12162b23b0a4b3fd77f17527a78c53f0f23573663545"}, + {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6dbdacf5752fbd78ccdb434698230c4f0f95df7dd956d5f205b5ed6911a1367c"}, + {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:506becdf2ecaebaf7f7995f776394fcc8bd8a78022772de66677c84fb02dd33d"}, + {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca8e44b5ba3edb682ea4e6185b49661fc22b230cf811b9c13963c9f982d1d964"}, + {file = "lxml-4.9.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9d9d5726474cbbef279fd709008f91a49c4f758bec9c062dfbba88eab00e3ff9"}, + {file = "lxml-4.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:bbdd69e20fe2943b51e2841fc1e6a3c1de460d630f65bde12452d8c97209464d"}, + {file = "lxml-4.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8671622256a0859f5089cbe0ce4693c2af407bc053dcc99aadff7f5310b4aa02"}, + {file = "lxml-4.9.4-cp37-cp37m-win32.whl", hash = "sha256:dd4fda67f5faaef4f9ee5383435048ee3e11ad996901225ad7615bc92245bc8e"}, + {file = "lxml-4.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6bee9c2e501d835f91460b2c904bc359f8433e96799f5c2ff20feebd9bb1e590"}, + {file = "lxml-4.9.4-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:1f10f250430a4caf84115b1e0f23f3615566ca2369d1962f82bef40dd99cd81a"}, + {file = "lxml-4.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:3b505f2bbff50d261176e67be24e8909e54b5d9d08b12d4946344066d66b3e43"}, + {file = "lxml-4.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:1449f9451cd53e0fd0a7ec2ff5ede4686add13ac7a7bfa6988ff6d75cff3ebe2"}, + {file = "lxml-4.9.4-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:4ece9cca4cd1c8ba889bfa67eae7f21d0d1a2e715b4d5045395113361e8c533d"}, + {file = "lxml-4.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59bb5979f9941c61e907ee571732219fa4774d5a18f3fa5ff2df963f5dfaa6bc"}, + {file = "lxml-4.9.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b1980dbcaad634fe78e710c8587383e6e3f61dbe146bcbfd13a9c8ab2d7b1192"}, + {file = "lxml-4.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9ae6c3363261021144121427b1552b29e7b59de9d6a75bf51e03bc072efb3c37"}, + {file = "lxml-4.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bcee502c649fa6351b44bb014b98c09cb00982a475a1912a9881ca28ab4f9cd9"}, + {file = "lxml-4.9.4-cp38-cp38-win32.whl", hash = "sha256:a8edae5253efa75c2fc79a90068fe540b197d1c7ab5803b800fccfe240eed33c"}, + {file = "lxml-4.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:701847a7aaefef121c5c0d855b2affa5f9bd45196ef00266724a80e439220e46"}, + {file = "lxml-4.9.4-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:f610d980e3fccf4394ab3806de6065682982f3d27c12d4ce3ee46a8183d64a6a"}, + {file = "lxml-4.9.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:aa9b5abd07f71b081a33115d9758ef6077924082055005808f68feccb27616bd"}, + {file = "lxml-4.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:365005e8b0718ea6d64b374423e870648ab47c3a905356ab6e5a5ff03962b9a9"}, + {file = "lxml-4.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:16b9ec51cc2feab009e800f2c6327338d6ee4e752c76e95a35c4465e80390ccd"}, + {file = "lxml-4.9.4-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:a905affe76f1802edcac554e3ccf68188bea16546071d7583fb1b693f9cf756b"}, + {file = "lxml-4.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fd814847901df6e8de13ce69b84c31fc9b3fb591224d6762d0b256d510cbf382"}, + {file = "lxml-4.9.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:91bbf398ac8bb7d65a5a52127407c05f75a18d7015a270fdd94bbcb04e65d573"}, + {file = "lxml-4.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f99768232f036b4776ce419d3244a04fe83784bce871b16d2c2e984c7fcea847"}, + {file = "lxml-4.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bb5bd6212eb0edfd1e8f254585290ea1dadc3687dd8fd5e2fd9a87c31915cdab"}, + {file = "lxml-4.9.4-cp39-cp39-win32.whl", hash = "sha256:88f7c383071981c74ec1998ba9b437659e4fd02a3c4a4d3efc16774eb108d0ec"}, + {file = "lxml-4.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:936e8880cc00f839aa4173f94466a8406a96ddce814651075f95837316369899"}, + {file = "lxml-4.9.4-pp310-pypy310_pp73-macosx_11_0_x86_64.whl", hash = "sha256:f6c35b2f87c004270fa2e703b872fcc984d714d430b305145c39d53074e1ffe0"}, + {file = "lxml-4.9.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:606d445feeb0856c2b424405236a01c71af7c97e5fe42fbc778634faef2b47e4"}, + {file = "lxml-4.9.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a1bdcbebd4e13446a14de4dd1825f1e778e099f17f79718b4aeaf2403624b0f7"}, + {file = "lxml-4.9.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0a08c89b23117049ba171bf51d2f9c5f3abf507d65d016d6e0fa2f37e18c0fc5"}, + {file = "lxml-4.9.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:232fd30903d3123be4c435fb5159938c6225ee8607b635a4d3fca847003134ba"}, + {file = "lxml-4.9.4-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:231142459d32779b209aa4b4d460b175cadd604fed856f25c1571a9d78114771"}, + {file = "lxml-4.9.4-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:520486f27f1d4ce9654154b4494cf9307b495527f3a2908ad4cb48e4f7ed7ef7"}, + {file = "lxml-4.9.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:562778586949be7e0d7435fcb24aca4810913771f845d99145a6cee64d5b67ca"}, + {file = "lxml-4.9.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a9e7c6d89c77bb2770c9491d988f26a4b161d05c8ca58f63fb1f1b6b9a74be45"}, + {file = "lxml-4.9.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:786d6b57026e7e04d184313c1359ac3d68002c33e4b1042ca58c362f1d09ff58"}, + {file = "lxml-4.9.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:95ae6c5a196e2f239150aa4a479967351df7f44800c93e5a975ec726fef005e2"}, + {file = "lxml-4.9.4-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:9b556596c49fa1232b0fff4b0e69b9d4083a502e60e404b44341e2f8fb7187f5"}, + {file = "lxml-4.9.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:cc02c06e9e320869d7d1bd323df6dd4281e78ac2e7f8526835d3d48c69060683"}, + {file = "lxml-4.9.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:857d6565f9aa3464764c2cb6a2e3c2e75e1970e877c188f4aeae45954a314e0c"}, + {file = "lxml-4.9.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c42ae7e010d7d6bc51875d768110c10e8a59494855c3d4c348b068f5fb81fdcd"}, + {file = "lxml-4.9.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f10250bb190fb0742e3e1958dd5c100524c2cc5096c67c8da51233f7448dc137"}, + {file = "lxml-4.9.4.tar.gz", hash = "sha256:b1541e50b78e15fa06a2670157a1962ef06591d4c998b998047fff5e3236880e"}, +] + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html5 = ["html5lib"] +htmlsoup = ["BeautifulSoup4"] +source = ["Cython (==0.29.37)"] + +[[package]] +name = "lxml" +version = "5.3.0" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +optional = false +python-versions = ">=3.6" +files = [ + {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656"}, + {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:501d0d7e26b4d261fca8132854d845e4988097611ba2531408ec91cf3fd9d20a"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e41506fec7a7f9405b14aa2d5c8abbb4dbbd09d88f9496958b6d00cb4d45330"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f7d4a670107d75dfe5ad080bed6c341d18c4442f9378c9f58e5851e86eb79965"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41ce1f1e2c7755abfc7e759dc34d7d05fd221723ff822947132dc934d122fe22"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:44264ecae91b30e5633013fb66f6ddd05c006d3e0e884f75ce0b4755b3e3847b"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:3c174dc350d3ec52deb77f2faf05c439331d6ed5e702fc247ccb4e6b62d884b7"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:2dfab5fa6a28a0b60a20638dc48e6343c02ea9933e3279ccb132f555a62323d8"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b1c8c20847b9f34e98080da785bb2336ea982e7f913eed5809e5a3c872900f32"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2c86bf781b12ba417f64f3422cfc302523ac9cd1d8ae8c0f92a1c66e56ef2e86"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c162b216070f280fa7da844531169be0baf9ccb17263cf5a8bf876fcd3117fa5"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:36aef61a1678cb778097b4a6eeae96a69875d51d1e8f4d4b491ab3cfb54b5a03"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f65e5120863c2b266dbcc927b306c5b78e502c71edf3295dfcb9501ec96e5fc7"}, + {file = "lxml-5.3.0-cp310-cp310-win32.whl", hash = "sha256:ef0c1fe22171dd7c7c27147f2e9c3e86f8bdf473fed75f16b0c2e84a5030ce80"}, + {file = "lxml-5.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:052d99051e77a4f3e8482c65014cf6372e61b0a6f4fe9edb98503bb5364cfee3"}, + {file = "lxml-5.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b"}, + {file = "lxml-5.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be"}, + {file = "lxml-5.3.0-cp311-cp311-win32.whl", hash = "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9"}, + {file = "lxml-5.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1"}, + {file = "lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859"}, + {file = "lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d"}, + {file = "lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30"}, + {file = "lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f"}, + {file = "lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a"}, + {file = "lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b"}, + {file = "lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957"}, + {file = "lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d"}, + {file = "lxml-5.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8f0de2d390af441fe8b2c12626d103540b5d850d585b18fcada58d972b74a74e"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1afe0a8c353746e610bd9031a630a95bcfb1a720684c3f2b36c4710a0a96528f"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56b9861a71575f5795bde89256e7467ece3d339c9b43141dbdd54544566b3b94"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:9fb81d2824dff4f2e297a276297e9031f46d2682cafc484f49de182aa5e5df99"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2c226a06ecb8cdef28845ae976da407917542c5e6e75dcac7cc33eb04aaeb237"}, + {file = "lxml-5.3.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:7d3d1ca42870cdb6d0d29939630dbe48fa511c203724820fc0fd507b2fb46577"}, + {file = "lxml-5.3.0-cp36-cp36m-win32.whl", hash = "sha256:094cb601ba9f55296774c2d57ad68730daa0b13dc260e1f941b4d13678239e70"}, + {file = "lxml-5.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:eafa2c8658f4e560b098fe9fc54539f86528651f61849b22111a9b107d18910c"}, + {file = "lxml-5.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cb83f8a875b3d9b458cada4f880fa498646874ba4011dc974e071a0a84a1b033"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25f1b69d41656b05885aa185f5fdf822cb01a586d1b32739633679699f220391"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23e0553b8055600b3bf4a00b255ec5c92e1e4aebf8c2c09334f8368e8bd174d6"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ada35dd21dc6c039259596b358caab6b13f4db4d4a7f8665764d616daf9cc1d"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:81b4e48da4c69313192d8c8d4311e5d818b8be1afe68ee20f6385d0e96fc9512"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:2bc9fd5ca4729af796f9f59cd8ff160fe06a474da40aca03fcc79655ddee1a8b"}, + {file = "lxml-5.3.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:07da23d7ee08577760f0a71d67a861019103e4812c87e2fab26b039054594cc5"}, + {file = "lxml-5.3.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:ea2e2f6f801696ad7de8aec061044d6c8c0dd4037608c7cab38a9a4d316bfb11"}, + {file = "lxml-5.3.0-cp37-cp37m-win32.whl", hash = "sha256:5c54afdcbb0182d06836cc3d1be921e540be3ebdf8b8a51ee3ef987537455f84"}, + {file = "lxml-5.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f2901429da1e645ce548bf9171784c0f74f0718c3f6150ce166be39e4dd66c3e"}, + {file = "lxml-5.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c56a1d43b2f9ee4786e4658c7903f05da35b923fb53c11025712562d5cc02753"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ee8c39582d2652dcd516d1b879451500f8db3fe3607ce45d7c5957ab2596040"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdf3a3059611f7585a78ee10399a15566356116a4288380921a4b598d807a22"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:146173654d79eb1fc97498b4280c1d3e1e5d58c398fa530905c9ea50ea849b22"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:0a7056921edbdd7560746f4221dca89bb7a3fe457d3d74267995253f46343f15"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:9e4b47ac0f5e749cfc618efdf4726269441014ae1d5583e047b452a32e221920"}, + {file = "lxml-5.3.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f914c03e6a31deb632e2daa881fe198461f4d06e57ac3d0e05bbcab8eae01945"}, + {file = "lxml-5.3.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:213261f168c5e1d9b7535a67e68b1f59f92398dd17a56d934550837143f79c42"}, + {file = "lxml-5.3.0-cp38-cp38-win32.whl", hash = "sha256:218c1b2e17a710e363855594230f44060e2025b05c80d1f0661258142b2add2e"}, + {file = "lxml-5.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:315f9542011b2c4e1d280e4a20ddcca1761993dda3afc7a73b01235f8641e903"}, + {file = "lxml-5.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1ffc23010330c2ab67fac02781df60998ca8fe759e8efde6f8b756a20599c5de"}, + {file = "lxml-5.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2b3778cb38212f52fac9fe913017deea2fdf4eb1a4f8e4cfc6b009a13a6d3fcc"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b0c7a688944891086ba192e21c5229dea54382f4836a209ff8d0a660fac06be"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:747a3d3e98e24597981ca0be0fd922aebd471fa99d0043a3842d00cdcad7ad6a"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86a6b24b19eaebc448dc56b87c4865527855145d851f9fc3891673ff97950540"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b11a5d918a6216e521c715b02749240fb07ae5a1fefd4b7bf12f833bc8b4fe70"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68b87753c784d6acb8a25b05cb526c3406913c9d988d51f80adecc2b0775d6aa"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:109fa6fede314cc50eed29e6e56c540075e63d922455346f11e4d7a036d2b8cf"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:02ced472497b8362c8e902ade23e3300479f4f43e45f4105c85ef43b8db85229"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:6b038cc86b285e4f9fea2ba5ee76e89f21ed1ea898e287dc277a25884f3a7dfe"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:7437237c6a66b7ca341e868cda48be24b8701862757426852c9b3186de1da8a2"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7f41026c1d64043a36fda21d64c5026762d53a77043e73e94b71f0521939cc71"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:482c2f67761868f0108b1743098640fbb2a28a8e15bf3f47ada9fa59d9fe08c3"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:1483fd3358963cc5c1c9b122c80606a3a79ee0875bcac0204149fa09d6ff2727"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dec2d1130a9cda5b904696cec33b2cfb451304ba9081eeda7f90f724097300a"}, + {file = "lxml-5.3.0-cp39-cp39-win32.whl", hash = "sha256:a0eabd0a81625049c5df745209dc7fcef6e2aea7793e5f003ba363610aa0a3ff"}, + {file = "lxml-5.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:89e043f1d9d341c52bf2af6d02e6adde62e0a46e6755d5eb60dc6e4f0b8aeca2"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7b1cd427cb0d5f7393c31b7496419da594fe600e6fdc4b105a54f82405e6626c"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51806cfe0279e06ed8500ce19479d757db42a30fd509940b1701be9c86a5ff9a"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee70d08fd60c9565ba8190f41a46a54096afa0eeb8f76bd66f2c25d3b1b83005"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8dc2c0395bea8254d8daebc76dcf8eb3a95ec2a46fa6fae5eaccee366bfe02ce"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6ba0d3dcac281aad8a0e5b14c7ed6f9fa89c8612b47939fc94f80b16e2e9bc83"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6e91cf736959057f7aac7adfc83481e03615a8e8dd5758aa1d95ea69e8931dba"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:94d6c3782907b5e40e21cadf94b13b0842ac421192f26b84c45f13f3c9d5dc27"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c300306673aa0f3ed5ed9372b21867690a17dba38c68c44b287437c362ce486b"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d9b952e07aed35fe2e1a7ad26e929595412db48535921c5013edc8aa4a35ce"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:01220dca0d066d1349bd6a1726856a78f7929f3878f7e2ee83c296c69495309e"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:2d9b8d9177afaef80c53c0a9e30fa252ff3036fb1c6494d427c066a4ce6a282f"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:20094fc3f21ea0a8669dc4c61ed7fa8263bd37d97d93b90f28fc613371e7a875"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ace2c2326a319a0bb8a8b0e5b570c764962e95818de9f259ce814ee666603f19"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92e67a0be1639c251d21e35fe74df6bcc40cba445c2cda7c4a967656733249e2"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd5350b55f9fecddc51385463a4f67a5da829bc741e38cf689f38ec9023f54ab"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c1fefd7e3d00921c44dc9ca80a775af49698bbfd92ea84498e56acffd4c5469"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:71a8dd38fbd2f2319136d4ae855a7078c69c9a38ae06e0c17c73fd70fc6caad8"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:97acf1e1fd66ab53dacd2c35b319d7e548380c2e9e8c54525c6e76d21b1ae3b1"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:68934b242c51eb02907c5b81d138cb977b2129a0a75a8f8b60b01cb8586c7b21"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b710bc2b8292966b23a6a0121f7a6c51d45d2347edcc75f016ac123b8054d3f2"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18feb4b93302091b1541221196a2155aa296c363fd233814fa11e181adebc52f"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3eb44520c4724c2e1a57c0af33a379eee41792595023f367ba3952a2d96c2aab"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:609251a0ca4770e5a8768ff902aa02bf636339c5a93f9349b48eb1f606f7f3e9"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:516f491c834eb320d6c843156440fe7fc0d50b33e44387fcec5b02f0bc118a4c"}, + {file = "lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f"}, +] + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html-clean = ["lxml-html-clean"] +html5 = ["html5lib"] +htmlsoup = ["BeautifulSoup4"] +source = ["Cython (>=3.0.11)"] + +[[package]] +name = "maclookup" +version = "1.0.3" +description = "Python client library for macaddress.io API." +optional = false +python-versions = "*" +files = [ + {file = "maclookup-1.0.3-py2.py3-none-any.whl", hash = "sha256:33bf8eaebe3b1e4ab4ae9277dd93c78024e0ebf6b3c42f76c37695bc26ce287a"}, + {file = "maclookup-1.0.3.tar.gz", hash = "sha256:795e792cd3e03c9bdad77e52904d43ff71d3ac03b360443f99d4bae08a6bffef"}, +] + +[package.dependencies] +future = "*" +python-dateutil = "*" + +[package.extras] +dev = ["mock", "tox"] + +[[package]] +name = "markdown" +version = "3.7" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, + {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markdown-include" +version = "0.8.1" +description = "A Python-Markdown extension which provides an 'include' function" +optional = false +python-versions = ">=3.7" +files = [ + {file = "markdown-include-0.8.1.tar.gz", hash = "sha256:1d0623e0fc2757c38d35df53752768356162284259d259c486b4ab6285cdbbe3"}, + {file = "markdown_include-0.8.1-py3-none-any.whl", hash = "sha256:32f0635b9cfef46997b307e2430022852529f7a5b87c0075c504283e7cc7db53"}, +] + +[package.dependencies] +markdown = ">=3.0" + +[package.extras] +tests = ["pytest"] + +[[package]] +name = "markdownify" +version = "0.13.1" +description = "Convert HTML to markdown." +optional = false +python-versions = "*" +files = [ + {file = "markdownify-0.13.1-py3-none-any.whl", hash = "sha256:1d181d43d20902bcc69d7be85b5316ed174d0dda72ff56e14ae4c95a4a407d22"}, + {file = "markdownify-0.13.1.tar.gz", hash = "sha256:ab257f9e6bd4075118828a28c9d02f8a4bfeb7421f558834aa79b2dfeb32a098"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.9,<5" +six = ">=1.15,<2" + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "matplotlib" +version = "3.7.5" +description = "Python plotting package" +optional = false +python-versions = ">=3.8" +files = [ + {file = "matplotlib-3.7.5-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:4a87b69cb1cb20943010f63feb0b2901c17a3b435f75349fd9865713bfa63925"}, + {file = "matplotlib-3.7.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d3ce45010fefb028359accebb852ca0c21bd77ec0f281952831d235228f15810"}, + {file = "matplotlib-3.7.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fbea1e762b28400393d71be1a02144aa16692a3c4c676ba0178ce83fc2928fdd"}, + {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec0e1adc0ad70ba8227e957551e25a9d2995e319c29f94a97575bb90fa1d4469"}, + {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6738c89a635ced486c8a20e20111d33f6398a9cbebce1ced59c211e12cd61455"}, + {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1210b7919b4ed94b5573870f316bca26de3e3b07ffdb563e79327dc0e6bba515"}, + {file = "matplotlib-3.7.5-cp310-cp310-win32.whl", hash = "sha256:068ebcc59c072781d9dcdb82f0d3f1458271c2de7ca9c78f5bd672141091e9e1"}, + {file = "matplotlib-3.7.5-cp310-cp310-win_amd64.whl", hash = "sha256:f098ffbaab9df1e3ef04e5a5586a1e6b1791380698e84938d8640961c79b1fc0"}, + {file = "matplotlib-3.7.5-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:f65342c147572673f02a4abec2d5a23ad9c3898167df9b47c149f32ce61ca078"}, + {file = "matplotlib-3.7.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4ddf7fc0e0dc553891a117aa083039088d8a07686d4c93fb8a810adca68810af"}, + {file = "matplotlib-3.7.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0ccb830fc29442360d91be48527809f23a5dcaee8da5f4d9b2d5b867c1b087b8"}, + {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efc6bb28178e844d1f408dd4d6341ee8a2e906fc9e0fa3dae497da4e0cab775d"}, + {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b15c4c2d374f249f324f46e883340d494c01768dd5287f8bc00b65b625ab56c"}, + {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d028555421912307845e59e3de328260b26d055c5dac9b182cc9783854e98fb"}, + {file = "matplotlib-3.7.5-cp311-cp311-win32.whl", hash = "sha256:fe184b4625b4052fa88ef350b815559dd90cc6cc8e97b62f966e1ca84074aafa"}, + {file = "matplotlib-3.7.5-cp311-cp311-win_amd64.whl", hash = "sha256:084f1f0f2f1010868c6f1f50b4e1c6f2fb201c58475494f1e5b66fed66093647"}, + {file = "matplotlib-3.7.5-cp312-cp312-macosx_10_12_universal2.whl", hash = "sha256:34bceb9d8ddb142055ff27cd7135f539f2f01be2ce0bafbace4117abe58f8fe4"}, + {file = "matplotlib-3.7.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c5a2134162273eb8cdfd320ae907bf84d171de948e62180fa372a3ca7cf0f433"}, + {file = "matplotlib-3.7.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:039ad54683a814002ff37bf7981aa1faa40b91f4ff84149beb53d1eb64617980"}, + {file = "matplotlib-3.7.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d742ccd1b09e863b4ca58291728db645b51dab343eebb08d5d4b31b308296ce"}, + {file = "matplotlib-3.7.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:743b1c488ca6a2bc7f56079d282e44d236bf375968bfd1b7ba701fd4d0fa32d6"}, + {file = "matplotlib-3.7.5-cp312-cp312-win_amd64.whl", hash = "sha256:fbf730fca3e1f23713bc1fae0a57db386e39dc81ea57dc305c67f628c1d7a342"}, + {file = "matplotlib-3.7.5-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:cfff9b838531698ee40e40ea1a8a9dc2c01edb400b27d38de6ba44c1f9a8e3d2"}, + {file = "matplotlib-3.7.5-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:1dbcca4508bca7847fe2d64a05b237a3dcaec1f959aedb756d5b1c67b770c5ee"}, + {file = "matplotlib-3.7.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4cdf4ef46c2a1609a50411b66940b31778db1e4b73d4ecc2eaa40bd588979b13"}, + {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:167200ccfefd1674b60e957186dfd9baf58b324562ad1a28e5d0a6b3bea77905"}, + {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:53e64522934df6e1818b25fd48cf3b645b11740d78e6ef765fbb5fa5ce080d02"}, + {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3e3bc79b2d7d615067bd010caff9243ead1fc95cf735c16e4b2583173f717eb"}, + {file = "matplotlib-3.7.5-cp38-cp38-win32.whl", hash = "sha256:6b641b48c6819726ed47c55835cdd330e53747d4efff574109fd79b2d8a13748"}, + {file = "matplotlib-3.7.5-cp38-cp38-win_amd64.whl", hash = "sha256:f0b60993ed3488b4532ec6b697059897891927cbfc2b8d458a891b60ec03d9d7"}, + {file = "matplotlib-3.7.5-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:090964d0afaff9c90e4d8de7836757e72ecfb252fb02884016d809239f715651"}, + {file = "matplotlib-3.7.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:9fc6fcfbc55cd719bc0bfa60bde248eb68cf43876d4c22864603bdd23962ba25"}, + {file = "matplotlib-3.7.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7cc3078b019bb863752b8b60e8b269423000f1603cb2299608231996bd9d54"}, + {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e4e9a868e8163abaaa8259842d85f949a919e1ead17644fb77a60427c90473c"}, + {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa7ebc995a7d747dacf0a717d0eb3aa0f0c6a0e9ea88b0194d3a3cd241a1500f"}, + {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3785bfd83b05fc0e0c2ae4c4a90034fe693ef96c679634756c50fe6efcc09856"}, + {file = "matplotlib-3.7.5-cp39-cp39-win32.whl", hash = "sha256:29b058738c104d0ca8806395f1c9089dfe4d4f0f78ea765c6c704469f3fffc81"}, + {file = "matplotlib-3.7.5-cp39-cp39-win_amd64.whl", hash = "sha256:fd4028d570fa4b31b7b165d4a685942ae9cdc669f33741e388c01857d9723eab"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2a9a3f4d6a7f88a62a6a18c7e6a84aedcaf4faf0708b4ca46d87b19f1b526f88"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9b3fd853d4a7f008a938df909b96db0b454225f935d3917520305b90680579c"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0ad550da9f160737d7890217c5eeed4337d07e83ca1b2ca6535078f354e7675"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:20da7924a08306a861b3f2d1da0d1aa9a6678e480cf8eacffe18b565af2813e7"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b45c9798ea6bb920cb77eb7306409756a7fab9db9b463e462618e0559aecb30e"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a99866267da1e561c7776fe12bf4442174b79aac1a47bd7e627c7e4d077ebd83"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b6aa62adb6c268fc87d80f963aca39c64615c31830b02697743c95590ce3fbb"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e530ab6a0afd082d2e9c17eb1eb064a63c5b09bb607b2b74fa41adbe3e162286"}, + {file = "matplotlib-3.7.5.tar.gz", hash = "sha256:1e5c971558ebc811aa07f54c7b7c677d78aa518ef4c390e14673a09e0860184a"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} +kiwisolver = ">=1.0.1" +numpy = ">=1.20,<2" +packaging = ">=20.0" +pillow = ">=6.2.0" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[[package]] +name = "mattermostdriver" +version = "7.3.2" +description = "A Python Mattermost Driver" +optional = false +python-versions = ">=3.5" +files = [ + {file = "mattermostdriver-7.3.2-py3-none-any.whl", hash = "sha256:8c6f15da34873b6c88da8fa8da0342f94bef77fcd16294befd92fea7e008cd97"}, + {file = "mattermostdriver-7.3.2.tar.gz", hash = "sha256:2e4d7b4a17d3013e279c6f993746ea18cd60b45d8fa3be24f47bc2de22b9b3b4"}, +] + +[package.dependencies] +requests = ">=2.25" +websockets = ">=8" + +[[package]] +name = "maxminddb" +version = "2.6.2" +description = "Reader for the MaxMind DB format" +optional = false +python-versions = ">=3.8" +files = [ + {file = "maxminddb-2.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7cfdf5c29a2739610700b9fea7f8d68ce81dcf30bb8016f1a1853ef889a2624b"}, + {file = "maxminddb-2.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:05e873eb82281cef6e787bd40bd1d58b2e496a21b3689346f0d0420988b3cbb1"}, + {file = "maxminddb-2.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2b85ffc9fb2e192321c2f0b34d0b291b8e82de6e51a6ec7534645663678e835"}, + {file = "maxminddb-2.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28a2eaf9769262c05c486e777016771f3367c843b053c43cd5fde1108755753d"}, + {file = "maxminddb-2.6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96a1fa38322bce1d587bb6ce39a0e6ca4c1b824f48fbc5739a5ec507f63aa889"}, + {file = "maxminddb-2.6.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:eb534333f5fd7180e35c0207b3d95d621e4b9be3b8c1709995d0feb6c752b6f4"}, + {file = "maxminddb-2.6.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b281c0eec3601dde1f169a1c04e2615751c66368141aded9f03131fe635450b"}, + {file = "maxminddb-2.6.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a771df92e599ad867c16ae4acb08cc3763c9d1028f4ca772c0571da97f7f86d2"}, + {file = "maxminddb-2.6.2-cp310-cp310-win32.whl", hash = "sha256:f412a54f87ef9083911c334267188d3d1b14f2591eac94b94ca32528f21d5f25"}, + {file = "maxminddb-2.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:7e5a90a1cb0c7fd6226aa44e18a87b26fa85b6eebae36d529d7582f93e8dfbd1"}, + {file = "maxminddb-2.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38941a38278491bf95e5ca544969782c7ab33326802f6a93816867289c3f6401"}, + {file = "maxminddb-2.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eef1c26210155c7b94c4ca28fef65eb44a5ca1584427b1fbdeec1cd3c81e25c5"}, + {file = "maxminddb-2.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4d9cd7ddd02ee123a44d0d7821166d31540ea85352deb06b29d55e802f32781"}, + {file = "maxminddb-2.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8101291e5b92bd272a050c25822a5e30860d453dde16b4fffed9d751f0483a82"}, + {file = "maxminddb-2.6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c7c520d06d335b288d06a00b786cea9b7e023bd588efb1a6ef485e94ccc7244"}, + {file = "maxminddb-2.6.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:58bfd2c55c96aaaa7c4996c704edabfb1bd369dfc1592cedf8957a24062178b1"}, + {file = "maxminddb-2.6.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:886af3ba4aa26214ff39214565f53152b62a5abdb6ef9e00c76c194dbfd79231"}, + {file = "maxminddb-2.6.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:93691c8b4b4c448babb37bedc6f3d51523a3f06ab11bdd171da7ffc4005a7897"}, + {file = "maxminddb-2.6.2-cp311-cp311-win32.whl", hash = "sha256:e9013076deca5d136c260510cd05e82ec2b4ddb9476d63e2180a13ddfd305c3e"}, + {file = "maxminddb-2.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:47170ec0e1e76787cc5882301c487f495d67f3146318f2f4e2adc281951a96ef"}, + {file = "maxminddb-2.6.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eacd65e38bdf4efdf42bbc15cfa734b09eb818ecfef76b7b36e64be382be4c83"}, + {file = "maxminddb-2.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:20662878bc9514e90b0b4c4eb1a76622ecc7504d012e76bad9cdb7372fc0ef96"}, + {file = "maxminddb-2.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7607e45f7eca991fa34d57c03a791a1dfbe774ddd9250d0f35cdcc6f17142a15"}, + {file = "maxminddb-2.6.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0970b661c4fac6624b9128057ed5fe35a2d95aa60359272289cd4c7207c9a6d"}, + {file = "maxminddb-2.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12207f0becf3f2bf14e7a4bf86efcaa6e90d665a918915ae228c4e77792d7151"}, + {file = "maxminddb-2.6.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:826a1858b93b193df7fa71e3caca65c3051db20545df0020444f55c02e8ed2c3"}, + {file = "maxminddb-2.6.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e63649a82926f1d93acdd3df5f7be66dc9473653350afe73f365bb25e5b34368"}, + {file = "maxminddb-2.6.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ebf9fdf8a8e55862aabb8b2c34a4af31a8a5b686007288eeb561fa20ef348378"}, + {file = "maxminddb-2.6.2-cp312-cp312-win32.whl", hash = "sha256:2aaefb62f881151960bb67e5aeb302c159a32bd2d623cf72dad688bda1020869"}, + {file = "maxminddb-2.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:78c3aa70c62be68ace23f819e7f23258545f2bfbd92cd6c33ee398cd261f6b84"}, + {file = "maxminddb-2.6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e1e40449bd278fdca1f351df442f391e72fd3d98b054ccac1672f27d70210642"}, + {file = "maxminddb-2.6.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:80d7f943f6b8bc437eaae5da778a83d8f38e4b7463756fdee04833e1be0bdea2"}, + {file = "maxminddb-2.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:058ca89789bc1770fe58d02a88272ca91dabeef9f3fe0011fe506484355f1804"}, + {file = "maxminddb-2.6.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80d20683afe01b4d41bad1c1829f87ab12f3d19c68ec230f83318a2fd13871a7"}, + {file = "maxminddb-2.6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd90c3798e6c347d48d5d9a9c95dc678b52a5a965f1fb72152067fdf52b994da"}, + {file = "maxminddb-2.6.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:add1e55620033516c5f0734b1d9d03848859192d9f3825aabe720dfa8a783958"}, + {file = "maxminddb-2.6.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:8cb992da535264177b380e7b81943c884d57dcbfad6b3335d7f633967144746e"}, + {file = "maxminddb-2.6.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:86048ff328793599e584bcc2fc8278c2b7c5d3a4005c70403613449ec93817ef"}, + {file = "maxminddb-2.6.2-cp38-cp38-win32.whl", hash = "sha256:f2e326a99eaa924ff2fb09d6e44127983a43016228e7780888f15e9ba171d7b3"}, + {file = "maxminddb-2.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:9a2671e8f4161130803cf226cd9cb8b93ec5c4b2493f83a902986177052d95d3"}, + {file = "maxminddb-2.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a50bc348c699d8f6a5f0aa35e5096515d642ca2f38b944bd71c3dedda3d3588"}, + {file = "maxminddb-2.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc9f1203eb2b139252aa08965960fe13c36cc8b80b536490b94b05c31aa1fca9"}, + {file = "maxminddb-2.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8ccca5327cb4e706f669456ec6d556badfa92c0fdacd57a15076f3cdc061560"}, + {file = "maxminddb-2.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3987e103396e925edebbef4877e94515822f63b3b436027a0b164b500622fccd"}, + {file = "maxminddb-2.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b31ecf3083b78c77624783bfdf6177e6ac73ae14684ef182855eb5569bc78e7c"}, + {file = "maxminddb-2.6.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:cd4530b9604d66cfa5e37eb94c671e54feff87769f8ba7fa997cce959e0cb241"}, + {file = "maxminddb-2.6.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ecce0b2d125691e2311f94dbd564c2d61c36c5033d082919431a21e6c694fa3f"}, + {file = "maxminddb-2.6.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:34b6e8d667d724f60d52635f3d959f793ab4e5d57d78b27fe66f02752d8c6b08"}, + {file = "maxminddb-2.6.2-cp39-cp39-win32.whl", hash = "sha256:d15414d251513748cb646d284a2829a5f4c69d8c90963a6e6da53a1a6d0accf7"}, + {file = "maxminddb-2.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:7c1220838ba9b0bcdaa0c5846f9da70a2304df2ac255fe518370f8faf8c18316"}, + {file = "maxminddb-2.6.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:39eab93ddd75fd02f8d5ad6b1bd3f8d894828d91d6f6c1a96bb9e87c34e94aaa"}, + {file = "maxminddb-2.6.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:aa8cb54b01a29a23a0ea6659fbb38deec6f35453588c5decdbf8669feb53b624"}, + {file = "maxminddb-2.6.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c096dfd20926c4de7d7fd5b5e75c756eddd4bdac5ab7aafd4bb67d000b13743"}, + {file = "maxminddb-2.6.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1dc2b511c7255f7cbbb01e8ba01ba82e62e9c1213e382d36f9d9b0ee45c2f6b2"}, + {file = "maxminddb-2.6.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80d7495565d30260c630afbe74d61522b13dd31ed05b8916003ec5b127109a12"}, + {file = "maxminddb-2.6.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9dccd7a438f81e3df84dfc31a75af4c8d29adefb6082329385bfde604c9ea01b"}, + {file = "maxminddb-2.6.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b0a3b9cab1a94cc633df3da85c6567f0188f10165e3338ec9a6c421de9fe53b9"}, + {file = "maxminddb-2.6.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fb38aa94e76a87785b654c035f9f3ee39b74a98e9beea9a10b1aa62abdcc4cbd"}, + {file = "maxminddb-2.6.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9e9e893f7c0fa44cfdd5ab819a07d93f63ee398c28b792cedd50b94dcfea7c0"}, + {file = "maxminddb-2.6.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28af9470f28fce2ccb945478235f53fb52d98a505653b1bf4028e34df6149a06"}, + {file = "maxminddb-2.6.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a74b60cdc61a69b967ec44201c6259fbc48ef2eab2e885fbdc50ec1accaad545"}, + {file = "maxminddb-2.6.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:485c0778f6801e1437c2efd6e3b964a7ae71c8819f063e0b5460c3267d977040"}, + {file = "maxminddb-2.6.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0b480a31589750da4e36d1ba04b77ee3ac3853ac7b94d63f337b9d4d0403043f"}, + {file = "maxminddb-2.6.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:85fc9406f42c1311ce8ea9f2c820db5d7ac687a39ab5d932708dc783607378ef"}, + {file = "maxminddb-2.6.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fd1a612110ff182a559d8010e7615e5d05ef9d2c234b5f7de124ee8fdf1ecb9"}, + {file = "maxminddb-2.6.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cd7f525eb2331cf05181c5ba562cc3edec3de4b41dbb18a5fee9ad24884b499"}, + {file = "maxminddb-2.6.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d32266792b349f5507b0369d3277d45318fcd346a16dcc98b484aadc208e4d74"}, + {file = "maxminddb-2.6.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5662386db91872d5505fde9e7bb0b9530b6aab7a6f3ece7df59a2b43a7b45d17"}, + {file = "maxminddb-2.6.2.tar.gz", hash = "sha256:7d842d32e2620abc894b7d79a5a1007a69df2c6cf279a06b94c9c3913f66f264"}, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[[package]] +name = "mkdocs" +version = "1.6.0" +description = "Project documentation with Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs-1.6.0-py3-none-any.whl", hash = "sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7"}, + {file = "mkdocs-1.6.0.tar.gz", hash = "sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} +ghp-import = ">=1.0" +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +jinja2 = ">=2.11.1" +markdown = ">=3.3.6" +markupsafe = ">=2.0.1" +mergedeep = ">=1.3.4" +mkdocs-get-deps = ">=0.2.0" +packaging = ">=20.5" +pathspec = ">=0.11.1" +pyyaml = ">=5.1" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.4)", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, + {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +mergedeep = ">=1.3.4" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" + +[[package]] +name = "mkdocs-material" +version = "9.5.33" +description = "Documentation that simply works" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material-9.5.33-py3-none-any.whl", hash = "sha256:dbc79cf0fdc6e2c366aa987de8b0c9d4e2bb9f156e7466786ba2fd0f9bf7ffca"}, + {file = "mkdocs_material-9.5.33.tar.gz", hash = "sha256:d23a8b5e3243c9b2f29cdfe83051104a8024b767312dc8fde05ebe91ad55d89d"}, +] + +[package.dependencies] +babel = ">=2.10,<3.0" +colorama = ">=0.4,<1.0" +jinja2 = ">=3.0,<4.0" +markdown = ">=3.2,<4.0" +mkdocs = ">=1.6,<2.0" +mkdocs-material-extensions = ">=1.3,<2.0" +paginate = ">=0.5,<1.0" +pygments = ">=2.16,<3.0" +pymdown-extensions = ">=10.2,<11.0" +regex = ">=2022.4" +requests = ">=2.26,<3.0" + +[package.extras] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] +recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +description = "Extension pack for Python Markdown and MkDocs Material." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, + {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, +] + +[[package]] +name = "more-itertools" +version = "10.4.0" +description = "More routines for operating on iterables, beyond itertools" +optional = false +python-versions = ">=3.8" +files = [ + {file = "more-itertools-10.4.0.tar.gz", hash = "sha256:fe0e63c4ab068eac62410ab05cccca2dc71ec44ba8ef29916a0090df061cf923"}, + {file = "more_itertools-10.4.0-py3-none-any.whl", hash = "sha256:0f7d9f83a0a8dcfa8a2694a770590d98a67ea943e3d9f5298309a484758c4e27"}, +] + +[[package]] +name = "msoffcrypto-tool" +version = "5.4.2" +description = "Python tool and library for decrypting and encrypting MS Office files using a password or other keys" +optional = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "msoffcrypto_tool-5.4.2-py3-none-any.whl", hash = "sha256:274fe2181702d1e5a107ec1b68a4c9fea997a44972ae1cc9ae0cb4f6a50fef0e"}, + {file = "msoffcrypto_tool-5.4.2.tar.gz", hash = "sha256:44b545adba0407564a0cc3d6dde6ca36b7c0fdf352b85bca51618fa1d4817370"}, +] + +[package.dependencies] +cryptography = ">=39.0" +olefile = ">=0.46" + +[[package]] +name = "multidict" +version = "6.0.5" +description = "multidict implementation" +optional = false +python-versions = ">=3.7" +files = [ + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc"}, + {file = "multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319"}, + {file = "multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e"}, + {file = "multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c"}, + {file = "multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"}, + {file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"}, + {file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"}, + {file = "multidict-6.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc"}, + {file = "multidict-6.0.5-cp37-cp37m-win32.whl", hash = "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee"}, + {file = "multidict-6.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44"}, + {file = "multidict-6.0.5-cp38-cp38-win32.whl", hash = "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241"}, + {file = "multidict-6.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c"}, + {file = "multidict-6.0.5-cp39-cp39-win32.whl", hash = "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b"}, + {file = "multidict-6.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755"}, + {file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"}, + {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"}, +] + +[[package]] +name = "mwdblib" +version = "4.5.0" +description = "MWDB API bindings for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mwdblib-4.5.0-py3-none-any.whl", hash = "sha256:94fc48ad92a3cd44badc894ed5f4c70fd3ce4fbdd3a567f499ae85db9c5f7048"}, +] + +[package.dependencies] +keyring = ">=18.0.0" +requests = "*" + +[package.extras] +cli = ["beautifultable (>=1.0.0)", "click (>=7.0)", "click-default-group", "humanize (>=0.5.1)"] + +[[package]] +name = "ndjson" +version = "0.3.1" +description = "JsonDecoder for ndjson" +optional = false +python-versions = "*" +files = [ + {file = "ndjson-0.3.1-py2.py3-none-any.whl", hash = "sha256:839c22275e6baa3040077b83c005ac24199b94973309a8a1809be962c753a410"}, + {file = "ndjson-0.3.1.tar.gz", hash = "sha256:bf9746cb6bb1cb53d172cda7f154c07c786d665ff28341e4e689b796b229e5d6"}, +] + +[[package]] +name = "nose" +version = "1.3.7" +description = "nose extends unittest to make testing easier" +optional = false +python-versions = "*" +files = [ + {file = "nose-1.3.7-py2-none-any.whl", hash = "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a"}, + {file = "nose-1.3.7-py3-none-any.whl", hash = "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac"}, + {file = "nose-1.3.7.tar.gz", hash = "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98"}, +] + +[[package]] +name = "np" +version = "1.0.2" +description = "np = numpy++: numpy with added convenience functionality" +optional = false +python-versions = "*" +files = [ + {file = "np-1.0.2.tar.gz", hash = "sha256:781265283f3823663ad8fb48741aae62abcf4c78bc19f908f8aa7c1d3eb132f8"}, +] + +[[package]] +name = "numpy" +version = "1.24.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, + {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, + {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, + {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, + {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, + {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, + {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, + {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, + {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, + {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, + {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, +] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "oauth2" +version = "1.9.0.post1" +description = "library for OAuth version 1.9" +optional = false +python-versions = "*" +files = [ + {file = "oauth2-1.9.0.post1-py2.py3-none-any.whl", hash = "sha256:15b5c42301f46dd63113f1214b0d81a8b16254f65a86d3c32a1b52297f3266e6"}, + {file = "oauth2-1.9.0.post1.tar.gz", hash = "sha256:c006a85e7c60107c7cc6da1b184b5c719f6dd7202098196dfa6e55df669b59bf"}, +] + +[package.dependencies] +httplib2 = "*" + +[[package]] +name = "ODTReader" +version = "0.0.3" +description = "Lightweight python module to allow extracting text from OpenDocument (odt) files." +optional = false +python-versions = "*" +files = [] +develop = false + +[package.source] +type = "git" +url = "https://github.com/cartertemm/ODTReader.git" +reference = "HEAD" +resolved_reference = "49d6938693f6faa3ff09998f86dba551ae3a996b" + +[[package]] +name = "olefile" +version = "0.47" +description = "Python package to parse, read and write Microsoft OLE2 files (Structured Storage or Compound Document, Microsoft Office)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "olefile-0.47-py2.py3-none-any.whl", hash = "sha256:543c7da2a7adadf21214938bb79c83ea12b473a4b6ee4ad4bf854e7715e13d1f"}, + {file = "olefile-0.47.zip", hash = "sha256:599383381a0bf3dfbd932ca0ca6515acd174ed48870cbf7fee123d698c192c1c"}, +] + +[package.extras] +tests = ["pytest", "pytest-cov"] + +[[package]] +name = "oletools" +version = "0.60.2" +description = "Python tools to analyze security characteristics of MS Office and OLE files (also called Structured Storage, Compound File Binary Format or Compound Document File Format), for Malware Analysis and Incident Response #DFIR" +optional = false +python-versions = "*" +files = [ + {file = "oletools-0.60.2-py2.py3-none-any.whl", hash = "sha256:72ad8bd748fd0c4e7b5b4733af770d11543ebb2bf2697455f99f975fcd50cc96"}, + {file = "oletools-0.60.2.zip", hash = "sha256:ad452099f4695ffd8855113f453348200d195ee9fa341a09e197d66ee7e0b2c3"}, +] + +[package.dependencies] +colorclass = "*" +easygui = "*" +msoffcrypto-tool = {version = "*", markers = "platform_python_implementation != \"PyPy\" or python_version >= \"3\" and (platform_system != \"Windows\" and platform_system != \"Darwin\")"} +olefile = ">=0.46" +pcodedmp = ">=1.2.5" +pyparsing = ">=2.1.0,<4" + +[package.extras] +full = ["XLMMacroDeobfuscator"] + +[[package]] +name = "opencv-python" +version = "4.10.0.84" +description = "Wrapper package for OpenCV python bindings." +optional = false +python-versions = ">=3.6" +files = [ + {file = "opencv-python-4.10.0.84.tar.gz", hash = "sha256:72d234e4582e9658ffea8e9cae5b63d488ad06994ef12d81dc303b17472f3526"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:fc182f8f4cda51b45f01c64e4cbedfc2f00aff799debebc305d8d0210c43f251"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-macosx_12_0_x86_64.whl", hash = "sha256:71e575744f1d23f79741450254660442785f45a0797212852ee5199ef12eed98"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09a332b50488e2dda866a6c5573ee192fe3583239fb26ff2f7f9ceb0bc119ea6"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ace140fc6d647fbe1c692bcb2abce768973491222c067c131d80957c595b71f"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-win32.whl", hash = "sha256:2db02bb7e50b703f0a2d50c50ced72e95c574e1e5a0bb35a8a86d0b35c98c236"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-win_amd64.whl", hash = "sha256:32dbbd94c26f611dc5cc6979e6b7aa1f55a64d6b463cc1dcd3c95505a63e48fe"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.21.0", markers = "python_version <= \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\" and python_version >= \"3.8\""}, + {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.17.3", markers = "(platform_system != \"Darwin\" and platform_system != \"Linux\") and python_version >= \"3.8\" and python_version < \"3.9\" or platform_system != \"Darwin\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_machine != \"aarch64\" or platform_machine != \"arm64\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_system != \"Linux\" or (platform_machine != \"arm64\" and platform_machine != \"aarch64\") and python_version >= \"3.8\" and python_version < \"3.9\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, + {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, + {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, +] + +[[package]] +name = "openpyxl" +version = "3.1.5" +description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"}, + {file = "openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"}, +] + +[package.dependencies] +et-xmlfile = "*" + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "paginate" +version = "0.5.6" +description = "Divides large result sets into pages for easier browsing" +optional = false +python-versions = "*" +files = [ + {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, +] + +[[package]] +name = "pandas" +version = "1.5.3" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, + {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"}, + {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"}, + {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"}, + {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"}, + {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"}, + {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"}, + {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"}, + {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"}, + {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"}, + {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"}, + {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"}, + {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"}, + {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"}, + {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, + {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, +] + +[package.dependencies] +numpy = {version = ">=1.20.3", markers = "python_version < \"3.10\""} +python-dateutil = ">=2.8.1" +pytz = ">=2020.1" + +[package.extras] +test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] + +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "pandas-ods-reader" +version = "0.1.4" +description = "Read in .ods and .fods files and return a pandas.DataFrame." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "pandas-ods-reader-0.1.4.tar.gz", hash = "sha256:d09e57af4ec440e6d5df12795127695b2d911657d202843f10b1594b682d3c09"}, + {file = "pandas_ods_reader-0.1.4-py3-none-any.whl", hash = "sha256:37b8d52ba67d338f8bf6bf103599d8f8c6aef096708907a55d3af4a4ac0a3d62"}, +] + +[package.dependencies] +ezodf = ">=0.3.2,<0.4.0" +lxml = ">=4.6.3,<5.0.0" +pandas = ">=1.0.0,<2.0.0" + +[[package]] +name = "pandas-ods-reader" +version = "1.0.1" +description = "Read in .ods and .fods files and return a pandas.DataFrame." +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "pandas_ods_reader-1.0.1-py3-none-any.whl", hash = "sha256:35a254ec95665fb654b573d7131787bf177e9126b06746ea3c17b1b972abc79b"}, + {file = "pandas_ods_reader-1.0.1.tar.gz", hash = "sha256:e87806d72bba31845de9f0dfa6c5621a5aa9b120cb84049544fee0e8baad8f9c"}, +] + +[package.dependencies] +ezodf = ">=0.3.2" +lxml = ">=4.9.2" +pandas = ">=1.5.2" + +[[package]] +name = "passivetotal" +version = "2.5.9" +description = "Library for the RiskIQ PassiveTotal and Illuminate API" +optional = false +python-versions = "*" +files = [ + {file = "passivetotal-2.5.9-py3-none-any.whl", hash = "sha256:070c408181bf294f1cf4d49bd7184a00c9419b2bac7a3405f247f786db45ed8f"}, + {file = "passivetotal-2.5.9.tar.gz", hash = "sha256:f5f1b7843257bc1ed5ae951c48902eb809a4a632947a57d6f8ad199428b13251"}, +] + +[package.dependencies] +future = "*" +python-dateutil = "*" +requests = "*" +tldextract = "*" + +[package.extras] +pandas = ["pandas"] + +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "pcodedmp" +version = "1.2.6" +description = "A VBA p-code disassembler" +optional = false +python-versions = "*" +files = [ + {file = "pcodedmp-1.2.6-py2.py3-none-any.whl", hash = "sha256:4441f7c0ab4cbda27bd4668db3b14f36261d86e5059ce06c0828602cbe1c4278"}, + {file = "pcodedmp-1.2.6.tar.gz", hash = "sha256:025f8c809a126f45a082ffa820893e6a8d990d9d7ddb68694b5a9f0a6dbcd955"}, +] + +[package.dependencies] +oletools = ">=0.54" +win-unicode-console = {version = "*", markers = "platform_system == \"Windows\" and platform_python_implementation != \"PyPy\""} + +[[package]] +name = "pdftotext" +version = "2.2.2" +description = "Simple PDF text extraction" +optional = false +python-versions = "*" +files = [ + {file = "pdftotext-2.2.2.tar.gz", hash = "sha256:2a9aa89bc62022408781b39d188fabf5a3ad1103b6630f32c4e27e395f7966ee"}, +] + +[[package]] +name = "pillow" +version = "10.4.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] + +[[package]] +name = "pkgutil-resolve-name" +version = "1.3.10" +description = "Resolve a name to an object." +optional = false +python-versions = ">=3.6" +files = [ + {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, + {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, +] + +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "progressbar2" +version = "4.2.0" +description = "A Python Progressbar library to provide visual (yet text based) progress to long running operations." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "progressbar2-4.2.0-py2.py3-none-any.whl", hash = "sha256:1a8e201211f99a85df55f720b3b6da7fb5c8cdef56792c4547205be2de5ea606"}, + {file = "progressbar2-4.2.0.tar.gz", hash = "sha256:1393922fcb64598944ad457569fbeb4b3ac189ef50b5adb9cef3284e87e394ce"}, +] + +[package.dependencies] +python-utils = ">=3.0.0" + +[package.extras] +docs = ["sphinx (>=1.8.5)"] +tests = ["flake8 (>=3.7.7)", "freezegun (>=0.3.11)", "pytest (>=4.6.9)", "pytest-cov (>=2.6.1)", "pytest-mypy", "sphinx (>=1.8.5)"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.47" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, + {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "psutil" +version = "6.0.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, + {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, + {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, + {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, + {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, + {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, + {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, + {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, + {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, + {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + +[[package]] +name = "publicsuffixlist" +version = "1.0.2.20240822" +description = "publicsuffixlist implement" +optional = false +python-versions = ">=3.5" +files = [ + {file = "publicsuffixlist-1.0.2.20240822-py2.py3-none-any.whl", hash = "sha256:df50c2b75e16a6887431702d92a02171bf8c78d34722e8a2bd91e56cf14cbed2"}, + {file = "publicsuffixlist-1.0.2.20240822.tar.gz", hash = "sha256:4b8328db52f34a9a4bc6fcda7c6db45e729e1a6cbeeb30ab85a2a87c37b16113"}, +] + +[package.extras] +readme = ["pandoc"] +update = ["requests"] + +[[package]] +name = "pycodestyle" +version = "2.9.1" +description = "Python style guide checker" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, + {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, +] + +[[package]] +name = "pycountry" +version = "24.6.1" +description = "ISO country, subdivision, language, currency and script definitions and their translations" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycountry-24.6.1-py3-none-any.whl", hash = "sha256:f1a4fb391cd7214f8eefd39556d740adcc233c778a27f8942c8dca351d6ce06f"}, + {file = "pycountry-24.6.1.tar.gz", hash = "sha256:b61b3faccea67f87d10c1f2b0fc0be714409e8fcdcc1315613174f6466c10221"}, +] + +[package.dependencies] +importlib-resources = {version = ">5.12.0", markers = "python_version < \"3.9\""} + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pycryptodome" +version = "3.20.0" +description = "Cryptographic library for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pycryptodome-3.20.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:f0e6d631bae3f231d3634f91ae4da7a960f7ff87f2865b2d2b831af1dfb04e9a"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:baee115a9ba6c5d2709a1e88ffe62b73ecc044852a925dcb67713a288c4ec70f"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:417a276aaa9cb3be91f9014e9d18d10e840a7a9b9a9be64a42f553c5b50b4d1d"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a1250b7ea809f752b68e3e6f3fd946b5939a52eaeea18c73bdab53e9ba3c2dd"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:d5954acfe9e00bc83ed9f5cb082ed22c592fbbef86dc48b907238be64ead5c33"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-win32.whl", hash = "sha256:06d6de87c19f967f03b4cf9b34e538ef46e99a337e9a61a77dbe44b2cbcf0690"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-win_amd64.whl", hash = "sha256:ec0bb1188c1d13426039af8ffcb4dbe3aad1d7680c35a62d8eaf2a529b5d3d4f"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5601c934c498cd267640b57569e73793cb9a83506f7c73a8ec57a516f5b0b091"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d29daa681517f4bc318cd8a23af87e1f2a7bad2fe361e8aa29c77d652a065de4"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3427d9e5310af6680678f4cce149f54e0bb4af60101c7f2c16fdf878b39ccccc"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:3cd3ef3aee1079ae44afaeee13393cf68b1058f70576b11439483e34f93cf818"}, + {file = "pycryptodome-3.20.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac1c7c0624a862f2e53438a15c9259d1655325fc2ec4392e66dc46cdae24d044"}, + {file = "pycryptodome-3.20.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:76658f0d942051d12a9bd08ca1b6b34fd762a8ee4240984f7c06ddfb55eaf15a"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f35d6cee81fa145333137009d9c8ba90951d7d77b67c79cbe5f03c7eb74d8fe2"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cb39afede7055127e35a444c1c041d2e8d2f1f9c121ecef573757ba4cd2c3c"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a4c4dc60b78ec41d2afa392491d788c2e06edf48580fbfb0dd0f828af49d25"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fb3b87461fa35afa19c971b0a2b7456a7b1db7b4eba9a8424666104925b78128"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:acc2614e2e5346a4a4eab6e199203034924313626f9620b7b4b38e9ad74b7e0c"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:210ba1b647837bfc42dd5a813cdecb5b86193ae11a3f5d972b9a0ae2c7e9e4b4"}, + {file = "pycryptodome-3.20.0-cp35-abi3-win32.whl", hash = "sha256:8d6b98d0d83d21fb757a182d52940d028564efe8147baa9ce0f38d057104ae72"}, + {file = "pycryptodome-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:9b3ae153c89a480a0ec402e23db8d8d84a3833b65fa4b15b81b83be9d637aab9"}, + {file = "pycryptodome-3.20.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:4401564ebf37dfde45d096974c7a159b52eeabd9969135f0426907db367a652a"}, + {file = "pycryptodome-3.20.0-pp27-pypy_73-win32.whl", hash = "sha256:ec1f93feb3bb93380ab0ebf8b859e8e5678c0f010d2d78367cf6bc30bfeb148e"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:acae12b9ede49f38eb0ef76fdec2df2e94aad85ae46ec85be3648a57f0a7db04"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f47888542a0633baff535a04726948e876bf1ed880fddb7c10a736fa99146ab3"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e0e4a987d38cfc2e71b4a1b591bae4891eeabe5fa0f56154f576e26287bfdea"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c18b381553638414b38705f07d1ef0a7cf301bc78a5f9bc17a957eb19446834b"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a60fedd2b37b4cb11ccb5d0399efe26db9e0dd149016c1cc6c8161974ceac2d6"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:405002eafad114a2f9a930f5db65feef7b53c4784495dd8758069b89baf68eab"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ab6ab0cb755154ad14e507d1df72de9897e99fd2d4922851a276ccc14f4f1a5"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:acf6e43fa75aca2d33e93409f2dafe386fe051818ee79ee8a3e21de9caa2ac9e"}, + {file = "pycryptodome-3.20.0.tar.gz", hash = "sha256:09609209ed7de61c2b560cc5c8c4fbf892f8b15b1faf7e4cbffac97db1fffda7"}, +] + +[[package]] +name = "pycryptodomex" +version = "3.20.0" +description = "Cryptographic library for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pycryptodomex-3.20.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:645bd4ca6f543685d643dadf6a856cc382b654cc923460e3a10a49c1b3832aeb"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ff5c9a67f8a4fba4aed887216e32cbc48f2a6fb2673bb10a99e43be463e15913"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8ee606964553c1a0bc74057dd8782a37d1c2bc0f01b83193b6f8bb14523b877b"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7805830e0c56d88f4d491fa5ac640dfc894c5ec570d1ece6ed1546e9df2e98d6"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:bc3ee1b4d97081260d92ae813a83de4d2653206967c4a0a017580f8b9548ddbc"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-win32.whl", hash = "sha256:8af1a451ff9e123d0d8bd5d5e60f8e3315c3a64f3cdd6bc853e26090e195cdc8"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-win_amd64.whl", hash = "sha256:cbe71b6712429650e3883dc81286edb94c328ffcd24849accac0a4dbcc76958a"}, + {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:76bd15bb65c14900d98835fcd10f59e5e0435077431d3a394b60b15864fddd64"}, + {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:653b29b0819605fe0898829c8ad6400a6ccde096146730c2da54eede9b7b8baa"}, + {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a5ec91388984909bb5398ea49ee61b68ecb579123694bffa172c3b0a107079"}, + {file = "pycryptodomex-3.20.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:108e5f1c1cd70ffce0b68739c75734437c919d2eaec8e85bffc2c8b4d2794305"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:59af01efb011b0e8b686ba7758d59cf4a8263f9ad35911bfe3f416cee4f5c08c"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:82ee7696ed8eb9a82c7037f32ba9b7c59e51dda6f105b39f043b6ef293989cb3"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91852d4480a4537d169c29a9d104dda44094c78f1f5b67bca76c29a91042b623"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca649483d5ed251d06daf25957f802e44e6bb6df2e8f218ae71968ff8f8edc4"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e186342cfcc3aafaad565cbd496060e5a614b441cacc3995ef0091115c1f6c5"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:25cd61e846aaab76d5791d006497134602a9e451e954833018161befc3b5b9ed"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:9c682436c359b5ada67e882fec34689726a09c461efd75b6ea77b2403d5665b7"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7a7a8f33a1f1fb762ede6cc9cbab8f2a9ba13b196bfaf7bc6f0b39d2ba315a43"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-win32.whl", hash = "sha256:c39778fd0548d78917b61f03c1fa8bfda6cfcf98c767decf360945fe6f97461e"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:2a47bcc478741b71273b917232f521fd5704ab4b25d301669879e7273d3586cc"}, + {file = "pycryptodomex-3.20.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:1be97461c439a6af4fe1cf8bf6ca5936d3db252737d2f379cc6b2e394e12a458"}, + {file = "pycryptodomex-3.20.0-pp27-pypy_73-win32.whl", hash = "sha256:19764605feea0df966445d46533729b645033f134baeb3ea26ad518c9fdf212c"}, + {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e497413560e03421484189a6b65e33fe800d3bd75590e6d78d4dfdb7accf3b"}, + {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48217c7901edd95f9f097feaa0388da215ed14ce2ece803d3f300b4e694abea"}, + {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d00fe8596e1cc46b44bf3907354e9377aa030ec4cd04afbbf6e899fc1e2a7781"}, + {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88afd7a3af7ddddd42c2deda43d53d3dfc016c11327d0915f90ca34ebda91499"}, + {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d3584623e68a5064a04748fb6d76117a21a7cb5eaba20608a41c7d0c61721794"}, + {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0daad007b685db36d977f9de73f61f8da2a7104e20aca3effd30752fd56f73e1"}, + {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dcac11031a71348faaed1f403a0debd56bf5404232284cf8c761ff918886ebc"}, + {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:69138068268127cd605e03438312d8f271135a33140e2742b417d027a0539427"}, + {file = "pycryptodomex-3.20.0.tar.gz", hash = "sha256:7a710b79baddd65b806402e14766c721aee8fb83381769c27920f26476276c1e"}, +] + +[[package]] +name = "pydantic" +version = "2.8.2" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, +] + +[package.dependencies] +annotated-types = ">=0.4.0" +pydantic-core = "2.20.1" +typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} + +[package.extras] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.1" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pydeep2" +version = "0.5.1" +description = "Python bindings for ssdeep" +optional = false +python-versions = "*" +files = [ + {file = "pydeep2-0.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e14b310b820d895a7354be7fd025de874892df249cbfb3ad8a524459e1511fd8"}, + {file = "pydeep2-0.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2283893e25826b547dd1e5c71a010e86ddfd7270e2f2b8c90973c1d7984c7eb7"}, + {file = "pydeep2-0.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f248e3161deb53d46a9368a7c164e36d83004faf2f11625d47a5cf23a6bdd2cb"}, + {file = "pydeep2-0.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a13fca9be89a9fa8d92a4f49d7b9191eef94555f8ddf030fb2be4c8c15ad618c"}, + {file = "pydeep2-0.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1cb4757db97ac15ddf034c21cd6bab984f841586b6d53984e63c9a7803b2cd4"}, + {file = "pydeep2-0.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7809a1d6640bdbee68f075d53229d05229e11b4711f232728dd540f68e6483a4"}, + {file = "pydeep2-0.5.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fedc1c9660cb5d0b73ad0b5f1dbffe16990e6721cbfc6454571a4b9882d0ea4"}, + {file = "pydeep2-0.5.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca68f7d63e2ef510d410d20b223e8e97df41707fb50c4c526b6dd1d8698d9e6"}, + {file = "pydeep2-0.5.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:199d05d8b4b7544509a2ba4802ead4b41dfe7859e0ecea9d9be9e41939f11660"}, + {file = "pydeep2-0.5.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bf00de2fe1918e4d698fe8195a5c0a3a0c3050a2e3e15583748cfd20b427153"}, + {file = "pydeep2-0.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c65dc910d782fa2bc97e1b28a78d77c4bada037d14b63e3e75a1fa5918d642c5"}, + {file = "pydeep2-0.5.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef00ca5681a2c4ad5dc744db5f8ae5406d3f13121b38d84cc58dfb8fce4c3dc2"}, + {file = "pydeep2-0.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:add24d7aa0386b285fd3e99632719714efabeb13d7b03a015b7c64d1f588f815"}, + {file = "pydeep2-0.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2063cbb053e5ce684cc45fff3e72c063b26aa85e41e6435cab0c658ad9e3e1e"}, + {file = "pydeep2-0.5.1.tar.gz", hash = "sha256:44ce447e3253a69d3393f3cc53e3a87a48fe3ff9861793736a7bc218a1b95d77"}, +] + +[[package]] +name = "pydnstrails" +version = "1.0" +description = "" +optional = false +python-versions = "*" +files = [] +develop = false + +[package.source] +type = "git" +url = "https://github.com/sebdraven/pydnstrails.git" +reference = "HEAD" +resolved_reference = "48c1f740025c51289f43a24863d1845ff12fd21a" + +[[package]] +name = "pyeti-python3" +version = "1.1" +description = "Revival version of pyeti, the API for Yeti Threat Intel Platform." +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyeti_python3-1.1-py3-none-any.whl", hash = "sha256:2b2011fadacf799bd99bcb5c3feec4ffafc031bb81e1ab713cd977948ca7d698"}, +] + +[package.dependencies] +requests = "*" +tqdm = "*" + +[[package]] +name = "pyeupi" +version = "1.3.0" +description = "Python API for the European Union anti-phishing initiative." +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "pyeupi-1.3.0-py3-none-any.whl", hash = "sha256:495248912ff3635d1c3e8b9c6e012add117178440fdd6c8d75cb2019990df996"}, + {file = "pyeupi-1.3.0.tar.gz", hash = "sha256:a262d8f1c6697c2d9fd462725217e33efa54f0a0c8104ce07fb8a3be781e4d72"}, +] + +[package.dependencies] +requests = ">=2.31.0,<3.0.0" + +[package.extras] +docs = ["Sphinx (<7.2)", "Sphinx (>=7.2,<8.0)"] + +[[package]] +name = "pyfaup" +version = "1.2" +description = "Python bindings for the faup library" +optional = false +python-versions = "*" +files = [ + {file = "pyfaup-1.2-py2.py3-none-any.whl", hash = "sha256:75f96f7da86ffb5402d3fcc2dbf98a511e792cf9100c159e34cdba8996ddc7f9"}, + {file = "pyfaup-1.2.tar.gz", hash = "sha256:5648bc3ebd80239aec927aedfc218c3a6ff36de636cc53822bfeb70b0869b1e7"}, +] + +[[package]] +name = "pyflakes" +version = "2.5.0" +description = "passive checker of Python programs" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, + {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, +] + +[[package]] +name = "pygeoip" +version = "0.3.2" +description = "Pure Python GeoIP API" +optional = false +python-versions = "*" +files = [ + {file = "pygeoip-0.3.2-py2.py3-none-any.whl", hash = "sha256:1938b9dac7b00d77f94d040b9465ea52c938f3fcdcd318b5537994f3c16aef96"}, + {file = "pygeoip-0.3.2.tar.gz", hash = "sha256:f22c4e00ddf1213e0fae36dc60b46ee7c25a6339941ec1a975539014c1f9a96d"}, +] + +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pyintel471" +version = "0.1.1" +description = "Python client for Intel471" +optional = false +python-versions = "*" +files = [ + {file = "pyintel471-0.1.1-py3-none-any.whl", hash = "sha256:4e30246d3a5904d437d3653d8c7d82a4fe74b1973b95665d94275a070cab2231"}, + {file = "pyintel471-0.1.1.tar.gz", hash = "sha256:81e20fcc09b27d346977492edea693536d5709da5abae78993beaa3e09baff22"}, +] + +[[package]] +name = "pyipasnhistory" +version = "2.1.2" +description = "Python client for IP ASN History" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "pyipasnhistory-2.1.2-py3-none-any.whl", hash = "sha256:7743de1bb7e735f9b907a3cff8ab189a1d8b5517b56b64f151fc4793b2863e35"}, + {file = "pyipasnhistory-2.1.2.tar.gz", hash = "sha256:10aed86bfbaedc8a119cdd5f59eca646938eb266c717f10394ba9fc2199f0281"}, +] + +[package.dependencies] +requests = ">=2.28.1,<3.0.0" + +[package.extras] +docs = ["Sphinx (>=5.3.0,<6.0.0)"] + +[[package]] +name = "pymdown-extensions" +version = "10.9" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pymdown_extensions-10.9-py3-none-any.whl", hash = "sha256:d323f7e90d83c86113ee78f3fe62fc9dee5f56b54d912660703ea1816fed5626"}, + {file = "pymdown_extensions-10.9.tar.gz", hash = "sha256:6ff740bcd99ec4172a938970d42b96128bdc9d4b9bcad72494f29921dc69b753"}, +] + +[package.dependencies] +markdown = ">=3.6" +pyyaml = "*" + +[package.extras] +extra = ["pygments (>=2.12)"] + +[[package]] +name = "pymisp" +version = "2.4.196" +description = "Python API for MISP." +optional = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "pymisp-2.4.196-py3-none-any.whl", hash = "sha256:f56ad708566b9f912809375cb982fadf67a3eb282970e1172d971b0fad35042b"}, + {file = "pymisp-2.4.196.tar.gz", hash = "sha256:86620b0b77b51eb5d08dcb2c1705ab0ce36813e35f48a488067266f565005dc9"}, +] + +[package.dependencies] +beautifulsoup4 = {version = ">=4.12.3,<5.0.0", optional = true, markers = "extra == \"openioc\""} +deprecated = ">=1.2.14,<2.0.0" +extract_msg = {version = ">=0.48.5,<0.49.0", optional = true, markers = "extra == \"email\""} +lief = {version = ">=0.15.0,<0.16.0", optional = true, markers = "extra == \"fileobjects\""} +oletools = {version = ">=0.60.1,<0.61.0", optional = true, markers = "extra == \"email\""} +publicsuffixlist = ">=1.0.2.20240814,<2.0.0.0" +pydeep2 = {version = ">=0.5.1,<0.6.0", optional = true, markers = "extra == \"fileobjects\""} +pyfaup = {version = ">=1.2,<2.0", optional = true, markers = "extra == \"url\""} +python-dateutil = ">=2.9.0.post0,<3.0.0" +python-magic = {version = ">=0.4.27,<0.5.0", optional = true, markers = "extra == \"fileobjects\""} +reportlab = {version = ">=4.2.2,<5.0.0", optional = true, markers = "extra == \"pdfexport\""} +requests = ">=2.32.3,<3.0.0" +RTFDE = {version = ">=0.1.1,<0.2.0", optional = true, markers = "extra == \"email\""} + +[package.extras] +brotli = ["urllib3[brotli]"] +docs = ["Sphinx (>=7.2,<8.0)", "Sphinx (>=8,<9)", "docutils (>=0.21.1,<0.22.0)", "recommonmark (>=0.7.1,<0.8.0)", "sphinx-autodoc-typehints (>=2.2.3,<3.0.0)"] +email = ["RTFDE (>=0.1.1,<0.2.0)", "extract_msg (>=0.48.5,<0.49.0)", "oletools (>=0.60.1,<0.61.0)"] +fileobjects = ["lief (>=0.15.0,<0.16.0)", "pydeep2 (>=0.5.1,<0.6.0)", "python-magic (>=0.4.27,<0.5.0)"] +openioc = ["beautifulsoup4 (>=4.12.3,<5.0.0)"] +pdfexport = ["reportlab (>=4.2.2,<5.0.0)"] +url = ["pyfaup (>=1.2,<2.0)"] +virustotal = ["validators (>=0.33.0,<0.34.0)"] + +[[package]] +name = "pyonyphe" +version = "2.0" +description = "" +optional = false +python-versions = "*" +files = [] +develop = false + +[package.source] +type = "git" +url = "https://github.com/sebdraven/pyonyphe.git" +reference = "HEAD" +resolved_reference = "d1d6741f8ea4475f3bb77ff20c876f08839cabd1" + +[[package]] +name = "pyparsing" +version = "3.1.2" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pypdns" +version = "2.2.3" +description = "Python API for PDNS." +optional = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "pypdns-2.2.3-py3-none-any.whl", hash = "sha256:ddb09a5e7491a6238b21589ef5248ac6028d01fb62a12febb0ce8f854519ac6b"}, + {file = "pypdns-2.2.3.tar.gz", hash = "sha256:4d1fac1f7d55ca2fc46d991a68451fdcfd53af81648881dc0a36b90d022888da"}, +] + +[package.dependencies] +dnspython = ">=2.6.1,<3.0.0" +requests-cache = ">=1.2.0,<2.0.0" + +[package.extras] +docs = ["Sphinx (<7.2)", "Sphinx (>=7.2,<8.0)"] + +[[package]] +name = "pypssl" +version = "2.2" +description = "Python API for PSSL." +optional = false +python-versions = ">=3.6,<4.0" +files = [ + {file = "pypssl-2.2-py3-none-any.whl", hash = "sha256:88cedaa4191b50154951fce98396521ad6c1d7e3eb914343e7a12ec0df1882a8"}, + {file = "pypssl-2.2.tar.gz", hash = "sha256:249ea2152827c10e746fe94c2957c0a525f8ed7ca9db2cd972690a3a136d7bb7"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1,<3.0.0" +requests = ">=2.25.1,<3.0.0" + +[[package]] +name = "pysafebrowsing" +version = "0.1.3" +description = "Google Safe Browsing API python wrapper" +optional = false +python-versions = "*" +files = [ + {file = "pysafebrowsing-0.1.3-py3-none-any.whl", hash = "sha256:156d3eb259194e2fa155d6c3c60b2bbba7b8f3235b26f964d91353b40e87b5c5"}, + {file = "pysafebrowsing-0.1.3.tar.gz", hash = "sha256:9e8e0b1bc98d12ad3dd00e1c65dcc0a0ef6f38fe5afb361884d52a2d705d2032"}, +] + +[package.dependencies] +configparser = "*" +requests = ">=2.32.3" + +[[package]] +name = "pytesseract" +version = "0.3.13" +description = "Python-tesseract is a python wrapper for Google's Tesseract-OCR" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytesseract-0.3.13-py3-none-any.whl", hash = "sha256:7a99c6c2ac598360693d83a416e36e0b33a67638bb9d77fdcac094a3589d4b34"}, + {file = "pytesseract-0.3.13.tar.gz", hash = "sha256:4bf5f880c99406f52a3cfc2633e42d9dc67615e69d8a509d74867d3baddb5db9"}, +] + +[package.dependencies] +packaging = ">=21.3" +Pillow = ">=8.0.0" + +[[package]] +name = "pytest" +version = "8.3.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, + {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "python-baseconv" +version = "1.2.2" +description = "Convert numbers from base 10 integers to base X strings and back again." +optional = false +python-versions = "*" +files = [ + {file = "python-baseconv-1.2.2.tar.gz", hash = "sha256:0539f8bd0464013b05ad62e0a1673f0ac9086c76b43ebf9f833053527cd9931b"}, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-docx" +version = "1.1.2" +description = "Create, read, and update Microsoft Word .docx files." +optional = false +python-versions = ">=3.7" +files = [ + {file = "python_docx-1.1.2-py3-none-any.whl", hash = "sha256:08c20d6058916fb19853fcf080f7f42b6270d89eac9fa5f8c15f691c0017fabe"}, + {file = "python_docx-1.1.2.tar.gz", hash = "sha256:0cf1f22e95b9002addca7948e16f2cd7acdfd498047f1941ca5d293db7762efd"}, +] + +[package.dependencies] +lxml = ">=3.1.0" +typing-extensions = ">=4.9.0" + +[[package]] +name = "python-engineio" +version = "4.9.1" +description = "Engine.IO server and client for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "python_engineio-4.9.1-py3-none-any.whl", hash = "sha256:f995e702b21f6b9ebde4e2000cd2ad0112ba0e5116ec8d22fe3515e76ba9dddd"}, + {file = "python_engineio-4.9.1.tar.gz", hash = "sha256:7631cf5563086076611e494c643b3fa93dd3a854634b5488be0bba0ef9b99709"}, +] + +[package.dependencies] +simple-websocket = ">=0.10.0" + +[package.extras] +asyncio-client = ["aiohttp (>=3.4)"] +client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] +docs = ["sphinx"] + +[[package]] +name = "python-magic" +version = "0.4.27" +description = "File type identification using libmagic" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b"}, + {file = "python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"}, +] + +[[package]] +name = "python-pptx" +version = "1.0.2" +description = "Create, read, and update PowerPoint 2007+ (.pptx) files." +optional = false +python-versions = ">=3.8" +files = [ + {file = "python_pptx-1.0.2-py3-none-any.whl", hash = "sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba"}, + {file = "python_pptx-1.0.2.tar.gz", hash = "sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095"}, +] + +[package.dependencies] +lxml = ">=3.1.0" +Pillow = ">=3.3.2" +typing-extensions = ">=4.9.0" +XlsxWriter = ">=0.5.7" + +[[package]] +name = "python-socketio" +version = "5.11.3" +description = "Socket.IO server and client for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python_socketio-5.11.3-py3-none-any.whl", hash = "sha256:2a923a831ff70664b7c502df093c423eb6aa93c1ce68b8319e840227a26d8b69"}, + {file = "python_socketio-5.11.3.tar.gz", hash = "sha256:194af8cdbb7b0768c2e807ba76c7abc288eb5bb85559b7cddee51a6bc7a65737"}, +] + +[package.dependencies] +bidict = ">=0.21.0" +python-engineio = ">=4.8.0" +requests = {version = ">=2.21.0", optional = true, markers = "extra == \"client\""} +websocket-client = {version = ">=0.54.0", optional = true, markers = "extra == \"client\""} + +[package.extras] +asyncio-client = ["aiohttp (>=3.4)"] +client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] +docs = ["sphinx"] + +[[package]] +name = "python-utils" +version = "3.5.2" +description = "Python Utils is a module with some convenient utilities not included with the standard Python install" +optional = false +python-versions = ">3.6.0" +files = [ + {file = "python-utils-3.5.2.tar.gz", hash = "sha256:68198854fc276bc4b2403b261703c218e01ef564dcb072a7096ed9ea7aa5130c"}, + {file = "python_utils-3.5.2-py2.py3-none-any.whl", hash = "sha256:8bfefc3430f1c48408fa0e5958eee51d39840a5a987c2181a579e99ab6fe5ca6"}, +] + +[package.extras] +docs = ["mock", "python-utils", "sphinx"] +loguru = ["loguru"] +tests = ["flake8", "loguru", "pytest", "pytest-asyncio", "pytest-cov", "pytest-mypy", "sphinx", "types-setuptools"] + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + +[[package]] +name = "pywin32-ctypes" +version = "0.2.3" +description = "A (partial) reimplementation of pywin32 using ctypes/cffi" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755"}, + {file = "pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + +[[package]] +name = "pyzbar" +version = "0.1.9" +description = "Read one-dimensional barcodes and QR codes from Python 2 and 3." +optional = false +python-versions = "*" +files = [ + {file = "pyzbar-0.1.9-py2.py3-none-any.whl", hash = "sha256:4559628b8192feb25766d954b36a3753baaf5c97c03135aec7e4a026036b475d"}, + {file = "pyzbar-0.1.9-py2.py3-none-win32.whl", hash = "sha256:8f4c5264c9c7c6b9f20d01efc52a4eba1ded47d9ba857a94130afe33703eb518"}, + {file = "pyzbar-0.1.9-py2.py3-none-win_amd64.whl", hash = "sha256:13e3ee5a2f3a545204a285f41814d5c0db571967e8d4af8699a03afc55182a9c"}, +] + +[package.extras] +scripts = ["Pillow (>=3.2.0)"] + +[[package]] +name = "pyzipper" +version = "0.3.6" +description = "AES encryption for zipfile." +optional = false +python-versions = ">=3.4" +files = [ + {file = "pyzipper-0.3.6-py2.py3-none-any.whl", hash = "sha256:6d097f465bfa47796b1494e12ea65d1478107d38e13bc56f6e58eedc4f6c1a87"}, + {file = "pyzipper-0.3.6.tar.gz", hash = "sha256:0adca90a00c36a93fbe49bfa8c5add452bfe4ef85a1b8e3638739dd1c7b26bfc"}, +] + +[package.dependencies] +pycryptodomex = "*" + +[[package]] +name = "rdflib" +version = "6.3.2" +description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "rdflib-6.3.2-py3-none-any.whl", hash = "sha256:36b4e74a32aa1e4fa7b8719876fb192f19ecd45ff932ea5ebbd2e417a0247e63"}, + {file = "rdflib-6.3.2.tar.gz", hash = "sha256:72af591ff704f4caacea7ecc0c5a9056b8553e0489dd4f35a9bc52dbd41522e0"}, +] + +[package.dependencies] +isodate = ">=0.6.0,<0.7.0" +pyparsing = ">=2.1.0,<4" + +[package.extras] +berkeleydb = ["berkeleydb (>=18.1.0,<19.0.0)"] +html = ["html5lib (>=1.0,<2.0)"] +lxml = ["lxml (>=4.3.0,<5.0.0)"] +networkx = ["networkx (>=2.0.0,<3.0.0)"] + +[[package]] +name = "red-black-tree-mod" +version = "1.20" +description = "Flexible python implementation of red black trees" +optional = false +python-versions = "*" +files = [ + {file = "red-black-tree-mod-1.20.tar.gz", hash = "sha256:2448e6fc9cbf1be204c753f352c6ee49aa8156dbf1faa57dfc26bd7705077e0a"}, +] + +[[package]] +name = "redis" +version = "5.0.8" +description = "Python client for Redis database and key-value store" +optional = false +python-versions = ">=3.7" +files = [ + {file = "redis-5.0.8-py3-none-any.whl", hash = "sha256:56134ee08ea909106090934adc36f65c9bcbbaecea5b21ba704ba6fb561f8eb4"}, + {file = "redis-5.0.8.tar.gz", hash = "sha256:0c5b10d387568dfe0698c6fad6615750c24170e548ca2deac10c649d463e9870"}, +] + +[package.dependencies] +async-timeout = {version = ">=4.0.3", markers = "python_full_version < \"3.11.3\""} + +[package.extras] +hiredis = ["hiredis (>1.0.0)"] +ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] + +[[package]] +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "regex" +version = "2024.7.24" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.7.24-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b0d3f567fafa0633aee87f08b9276c7062da9616931382993c03808bb68ce"}, + {file = "regex-2024.7.24-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3426de3b91d1bc73249042742f45c2148803c111d1175b283270177fdf669024"}, + {file = "regex-2024.7.24-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f273674b445bcb6e4409bf8d1be67bc4b58e8b46fd0d560055d515b8830063cd"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23acc72f0f4e1a9e6e9843d6328177ae3074b4182167e34119ec7233dfeccf53"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65fd3d2e228cae024c411c5ccdffae4c315271eee4a8b839291f84f796b34eca"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c414cbda77dbf13c3bc88b073a1a9f375c7b0cb5e115e15d4b73ec3a2fbc6f59"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf7a89eef64b5455835f5ed30254ec19bf41f7541cd94f266ab7cbd463f00c41"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19c65b00d42804e3fbea9708f0937d157e53429a39b7c61253ff15670ff62cb5"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7a5486ca56c8869070a966321d5ab416ff0f83f30e0e2da1ab48815c8d165d46"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f51f9556785e5a203713f5efd9c085b4a45aecd2a42573e2b5041881b588d1f"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:a4997716674d36a82eab3e86f8fa77080a5d8d96a389a61ea1d0e3a94a582cf7"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c0abb5e4e8ce71a61d9446040c1e86d4e6d23f9097275c5bd49ed978755ff0fe"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:18300a1d78cf1290fa583cd8b7cde26ecb73e9f5916690cf9d42de569c89b1ce"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:416c0e4f56308f34cdb18c3f59849479dde5b19febdcd6e6fa4d04b6c31c9faa"}, + {file = "regex-2024.7.24-cp310-cp310-win32.whl", hash = "sha256:fb168b5924bef397b5ba13aabd8cf5df7d3d93f10218d7b925e360d436863f66"}, + {file = "regex-2024.7.24-cp310-cp310-win_amd64.whl", hash = "sha256:6b9fc7e9cc983e75e2518496ba1afc524227c163e43d706688a6bb9eca41617e"}, + {file = "regex-2024.7.24-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:382281306e3adaaa7b8b9ebbb3ffb43358a7bbf585fa93821300a418bb975281"}, + {file = "regex-2024.7.24-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4fdd1384619f406ad9037fe6b6eaa3de2749e2e12084abc80169e8e075377d3b"}, + {file = "regex-2024.7.24-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3d974d24edb231446f708c455fd08f94c41c1ff4f04bcf06e5f36df5ef50b95a"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2ec4419a3fe6cf8a4795752596dfe0adb4aea40d3683a132bae9c30b81e8d73"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb563dd3aea54c797adf513eeec819c4213d7dbfc311874eb4fd28d10f2ff0f2"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45104baae8b9f67569f0f1dca5e1f1ed77a54ae1cd8b0b07aba89272710db61e"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:994448ee01864501912abf2bad9203bffc34158e80fe8bfb5b031f4f8e16da51"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fac296f99283ac232d8125be932c5cd7644084a30748fda013028c815ba3364"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7e37e809b9303ec3a179085415cb5f418ecf65ec98cdfe34f6a078b46ef823ee"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:01b689e887f612610c869421241e075c02f2e3d1ae93a037cb14f88ab6a8934c"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f6442f0f0ff81775eaa5b05af8a0ffa1dda36e9cf6ec1e0d3d245e8564b684ce"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:871e3ab2838fbcb4e0865a6e01233975df3a15e6fce93b6f99d75cacbd9862d1"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c918b7a1e26b4ab40409820ddccc5d49871a82329640f5005f73572d5eaa9b5e"}, + {file = "regex-2024.7.24-cp311-cp311-win32.whl", hash = "sha256:2dfbb8baf8ba2c2b9aa2807f44ed272f0913eeeba002478c4577b8d29cde215c"}, + {file = "regex-2024.7.24-cp311-cp311-win_amd64.whl", hash = "sha256:538d30cd96ed7d1416d3956f94d54e426a8daf7c14527f6e0d6d425fcb4cca52"}, + {file = "regex-2024.7.24-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fe4ebef608553aff8deb845c7f4f1d0740ff76fa672c011cc0bacb2a00fbde86"}, + {file = "regex-2024.7.24-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:74007a5b25b7a678459f06559504f1eec2f0f17bca218c9d56f6a0a12bfffdad"}, + {file = "regex-2024.7.24-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7df9ea48641da022c2a3c9c641650cd09f0cd15e8908bf931ad538f5ca7919c9"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a1141a1dcc32904c47f6846b040275c6e5de0bf73f17d7a409035d55b76f289"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80c811cfcb5c331237d9bad3bea2c391114588cf4131707e84d9493064d267f9"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7214477bf9bd195894cf24005b1e7b496f46833337b5dedb7b2a6e33f66d962c"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d55588cba7553f0b6ec33130bc3e114b355570b45785cebdc9daed8c637dd440"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:558a57cfc32adcf19d3f791f62b5ff564922942e389e3cfdb538a23d65a6b610"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a512eed9dfd4117110b1881ba9a59b31433caed0c4101b361f768e7bcbaf93c5"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:86b17ba823ea76256b1885652e3a141a99a5c4422f4a869189db328321b73799"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5eefee9bfe23f6df09ffb6dfb23809f4d74a78acef004aa904dc7c88b9944b05"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:731fcd76bbdbf225e2eb85b7c38da9633ad3073822f5ab32379381e8c3c12e94"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eaef80eac3b4cfbdd6de53c6e108b4c534c21ae055d1dbea2de6b3b8ff3def38"}, + {file = "regex-2024.7.24-cp312-cp312-win32.whl", hash = "sha256:185e029368d6f89f36e526764cf12bf8d6f0e3a2a7737da625a76f594bdfcbfc"}, + {file = "regex-2024.7.24-cp312-cp312-win_amd64.whl", hash = "sha256:2f1baff13cc2521bea83ab2528e7a80cbe0ebb2c6f0bfad15be7da3aed443908"}, + {file = "regex-2024.7.24-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:66b4c0731a5c81921e938dcf1a88e978264e26e6ac4ec96a4d21ae0354581ae0"}, + {file = "regex-2024.7.24-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:88ecc3afd7e776967fa16c80f974cb79399ee8dc6c96423321d6f7d4b881c92b"}, + {file = "regex-2024.7.24-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:64bd50cf16bcc54b274e20235bf8edbb64184a30e1e53873ff8d444e7ac656b2"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb462f0e346fcf41a901a126b50f8781e9a474d3927930f3490f38a6e73b6950"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a82465ebbc9b1c5c50738536fdfa7cab639a261a99b469c9d4c7dcbb2b3f1e57"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68a8f8c046c6466ac61a36b65bb2395c74451df2ffb8458492ef49900efed293"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac8e84fff5d27420f3c1e879ce9929108e873667ec87e0c8eeb413a5311adfe"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba2537ef2163db9e6ccdbeb6f6424282ae4dea43177402152c67ef869cf3978b"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:43affe33137fcd679bdae93fb25924979517e011f9dea99163f80b82eadc7e53"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:c9bb87fdf2ab2370f21e4d5636e5317775e5d51ff32ebff2cf389f71b9b13750"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:945352286a541406f99b2655c973852da7911b3f4264e010218bbc1cc73168f2"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:8bc593dcce679206b60a538c302d03c29b18e3d862609317cb560e18b66d10cf"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:3f3b6ca8eae6d6c75a6cff525c8530c60e909a71a15e1b731723233331de4169"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c51edc3541e11fbe83f0c4d9412ef6c79f664a3745fab261457e84465ec9d5a8"}, + {file = "regex-2024.7.24-cp38-cp38-win32.whl", hash = "sha256:d0a07763776188b4db4c9c7fb1b8c494049f84659bb387b71c73bbc07f189e96"}, + {file = "regex-2024.7.24-cp38-cp38-win_amd64.whl", hash = "sha256:8fd5afd101dcf86a270d254364e0e8dddedebe6bd1ab9d5f732f274fa00499a5"}, + {file = "regex-2024.7.24-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0ffe3f9d430cd37d8fa5632ff6fb36d5b24818c5c986893063b4e5bdb84cdf24"}, + {file = "regex-2024.7.24-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:25419b70ba00a16abc90ee5fce061228206173231f004437730b67ac77323f0d"}, + {file = "regex-2024.7.24-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:33e2614a7ce627f0cdf2ad104797d1f68342d967de3695678c0cb84f530709f8"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d33a0021893ede5969876052796165bab6006559ab845fd7b515a30abdd990dc"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04ce29e2c5fedf296b1a1b0acc1724ba93a36fb14031f3abfb7abda2806c1535"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b16582783f44fbca6fcf46f61347340c787d7530d88b4d590a397a47583f31dd"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:836d3cc225b3e8a943d0b02633fb2f28a66e281290302a79df0e1eaa984ff7c1"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:438d9f0f4bc64e8dea78274caa5af971ceff0f8771e1a2333620969936ba10be"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:973335b1624859cb0e52f96062a28aa18f3a5fc77a96e4a3d6d76e29811a0e6e"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c5e69fd3eb0b409432b537fe3c6f44ac089c458ab6b78dcec14478422879ec5f"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fbf8c2f00904eaf63ff37718eb13acf8e178cb940520e47b2f05027f5bb34ce3"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2757ace61bc4061b69af19e4689fa4416e1a04840f33b441034202b5cd02d4"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:44fc61b99035fd9b3b9453f1713234e5a7c92a04f3577252b45feefe1b327759"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:84c312cdf839e8b579f504afcd7b65f35d60b6285d892b19adea16355e8343c9"}, + {file = "regex-2024.7.24-cp39-cp39-win32.whl", hash = "sha256:ca5b2028c2f7af4e13fb9fc29b28d0ce767c38c7facdf64f6c2cd040413055f1"}, + {file = "regex-2024.7.24-cp39-cp39-win_amd64.whl", hash = "sha256:7c479f5ae937ec9985ecaf42e2e10631551d909f203e31308c12d703922742f9"}, + {file = "regex-2024.7.24.tar.gz", hash = "sha256:9cfd009eed1a46b27c14039ad5bbc5e71b6367c5b2e6d5f5da0ea91600817506"}, +] + +[[package]] +name = "reportlab" +version = "4.2.2" +description = "The Reportlab Toolkit" +optional = false +python-versions = "<4,>=3.7" +files = [ + {file = "reportlab-4.2.2-py3-none-any.whl", hash = "sha256:927616931637e2f13e2ee3b3b6316d7a07803170e258621cff7d138bde17fbb5"}, + {file = "reportlab-4.2.2.tar.gz", hash = "sha256:765eecbdd68491c56947e29c38b8b69b834ee5dbbdd2fb7409f08ebdebf04428"}, +] + +[package.dependencies] +chardet = "*" +pillow = ">=9.0.0" + +[package.extras] +accel = ["rl-accel (>=0.9.0,<1.1)"] +pycairo = ["freetype-py (>=2.3.0,<2.4)", "rlPyCairo (>=0.2.0,<1)"] +renderpm = ["rl-renderPM (>=4.0.3,<4.1)"] + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-cache" +version = "1.2.1" +description = "A persistent cache for python requests" +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, + {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, +] + +[package.dependencies] +attrs = ">=21.2" +cattrs = ">=22.2" +platformdirs = ">=2.5" +requests = ">=2.22" +url-normalize = ">=1.4" +urllib3 = ">=1.25.5" + +[package.extras] +all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] +bson = ["bson (>=0.5)"] +docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] +dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] +json = ["ujson (>=5.4)"] +mongodb = ["pymongo (>=3)"] +redis = ["redis (>=3)"] +security = ["itsdangerous (>=2.0)"] +yaml = ["pyyaml (>=6.0.1)"] + +[[package]] +name = "requests-file" +version = "2.1.0" +description = "File transport adapter for Requests" +optional = false +python-versions = "*" +files = [ + {file = "requests_file-2.1.0-py2.py3-none-any.whl", hash = "sha256:cf270de5a4c5874e84599fc5778303d496c10ae5e870bfa378818f35d21bda5c"}, + {file = "requests_file-2.1.0.tar.gz", hash = "sha256:0f549a3f3b0699415ac04d167e9cb39bccfb730cb832b4d20be3d9867356e658"}, +] + +[package.dependencies] +requests = ">=1.0.0" + +[[package]] +name = "rich" +version = "10.16.2" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.6.2,<4.0.0" +files = [ + {file = "rich-10.16.2-py3-none-any.whl", hash = "sha256:c59d73bd804c90f747c8d7b1d023b88f2a9ac2454224a4aeaf959b21eeb42d03"}, + {file = "rich-10.16.2.tar.gz", hash = "sha256:720974689960e06c2efdb54327f8bf0cdbdf4eae4ad73b6c94213cad405c371b"}, +] + +[package.dependencies] +colorama = ">=0.4.0,<0.5.0" +commonmark = ">=0.9.0,<0.10.0" +pygments = ">=2.6.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] + +[[package]] +name = "rpds-py" +version = "0.20.0" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, + {file = "rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94"}, + {file = "rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee"}, + {file = "rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58"}, + {file = "rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0"}, + {file = "rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174"}, + {file = "rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139"}, + {file = "rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57"}, + {file = "rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a"}, + {file = "rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a"}, + {file = "rpds_py-0.20.0-cp38-none-win32.whl", hash = "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5"}, + {file = "rpds_py-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b"}, + {file = "rpds_py-0.20.0-cp39-none-win32.whl", hash = "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7"}, + {file = "rpds_py-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8"}, + {file = "rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121"}, +] + +[[package]] +name = "rtfde" +version = "0.1.2" +description = "A library for extracting HTML content from RTF encapsulated HTML as commonly found in the exchange MSG email format." +optional = false +python-versions = "~=3.8" +files = [ + {file = "RTFDE-0.1.2-py3-none-any.whl", hash = "sha256:f6d1450c99b04e930da130e8b419aa33b1f953623e1b94ad5c0f67f0362eb737"}, +] + +[package.dependencies] +lark = ">=1.1.8,<1.2.0" +oletools = ">=0.56" + +[package.extras] +dev = ["coverage (>=7.2.2,<7.3.0)", "lxml (>=4.6,<5.0)", "mypy (>=1.1,<2.0)", "pdoc3 (>=0.10.0,<0.11.0)"] +msg-parse = ["extract-msg (>=0.27,<1.0)"] + +[[package]] +name = "ruamel-yaml" +version = "0.18.6" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"}, + {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"}, +] + +[package.dependencies] +"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} + +[package.extras] +docs = ["mercurial (>5.7)", "ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.8" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +optional = false +python-versions = ">=3.6" +files = [ + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"}, + {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, + {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, +] + +[[package]] +name = "secretstorage" +version = "3.3.3" +description = "Python bindings to FreeDesktop.org Secret Service API" +optional = false +python-versions = ">=3.6" +files = [ + {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, + {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"}, +] + +[package.dependencies] +cryptography = ">=2.0" +jeepney = ">=0.6" + +[[package]] +name = "selenium" +version = "2.53.6" +description = "Python bindings for Selenium" +optional = false +python-versions = "*" +files = [ + {file = "selenium-2.53.6-py2.py3-none-any.whl", hash = "sha256:5071f43daa2e698d60d5633ab0a6630cc68a852b360be99144f1c4c1ace2746c"}, + {file = "selenium-2.53.6.tar.gz", hash = "sha256:f507181f13768d73b98dd9647a466ea5758ef5c7f07b62a285d2bd8de9b27016"}, +] + +[[package]] +name = "setuptools" +version = "73.0.1" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, + {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, +] + +[package.extras] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] + +[[package]] +name = "shellingham" +version = "1.5.4" +description = "Tool to Detect Surrounding Shell" +optional = false +python-versions = ">=3.7" +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + +[[package]] +name = "shodan" +version = "1.31.0" +description = "Python library and command-line utility for Shodan (https://developer.shodan.io)" +optional = false +python-versions = "*" +files = [ + {file = "shodan-1.31.0.tar.gz", hash = "sha256:c73275386ea02390e196c35c660706a28dd4d537c5a21eb387ab6236fac251f6"}, +] + +[package.dependencies] +click = "*" +click-plugins = "*" +colorama = "*" +requests = ">=2.2.1" +tldextract = "*" +XlsxWriter = "*" + +[[package]] +name = "sigmatools" +version = "0.23.1" +description = "Tools for the Generic Signature Format for SIEM Systems" +optional = false +python-versions = "~=3.8" +files = [ + {file = "sigmatools-0.23.1.tar.gz", hash = "sha256:3ff0ba97d9d3ea00cabc3020d38ba5e70d0c6fb1271502b590c1e5b49fbd71de"}, +] + +[package.dependencies] +progressbar2 = "*" +pymisp = "*" +PyYAML = "*" +"ruamel.yaml" = "*" +termcolor = "*" + +[package.extras] +test = ["attackcti", "coverage", "yamllint"] + +[[package]] +name = "sigmf" +version = "1.2.2" +description = "Easily interact with Signal Metadata Format (SigMF) recordings." +optional = false +python-versions = ">=3.7" +files = [ + {file = "SigMF-1.2.2-py3-none-any.whl", hash = "sha256:6cd5470d1294b34f4ad4d0f0502330f5712aa8629f912b913500c67ed1e0d7d4"}, + {file = "sigmf-1.2.2.tar.gz", hash = "sha256:9d2eeea6e3c69f90ad83c05e8faa7f5caabd24ce79e809e75ff5cc62d6765d5f"}, +] + +[package.dependencies] +jsonschema = "*" +numpy = "*" + +[package.extras] +apps = ["PySimpleGUI", "scipy"] +test = ["hypothesis", "pylint", "pytest", "pytest-cov"] + +[[package]] +name = "simple-websocket" +version = "1.0.0" +description = "Simple WebSocket server and client for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "simple-websocket-1.0.0.tar.gz", hash = "sha256:17d2c72f4a2bd85174a97e3e4c88b01c40c3f81b7b648b0cc3ce1305968928c8"}, + {file = "simple_websocket-1.0.0-py3-none-any.whl", hash = "sha256:1d5bf585e415eaa2083e2bcf02a3ecf91f9712e7b3e6b9fa0b461ad04e0837bc"}, +] + +[package.dependencies] +wsproto = "*" + +[package.extras] +docs = ["sphinx"] + +[[package]] +name = "simplejson" +version = "3.19.3" +description = "Simple, fast, extensible JSON encoder/decoder for Python" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.5" +files = [ + {file = "simplejson-3.19.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:f39caec26007a2d0efab6b8b1d74873ede9351962707afab622cc2285dd26ed0"}, + {file = "simplejson-3.19.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:83c87706265ae3028e8460d08b05f30254c569772e859e5ba61fe8af2c883468"}, + {file = "simplejson-3.19.3-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0b5ddd2c7d1d3f4d23224bc8a04bbf1430ae9a8149c05b90f8fc610f7f857a23"}, + {file = "simplejson-3.19.3-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:ad0e0b1ce9bd3edb5cf64b5b5b76eacbfdac8c5367153aeeec8a8b1407f68342"}, + {file = "simplejson-3.19.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:93be280fc69a952c76e261036312c20b910e7fa9e234f1d89bdfe3fa34f8a023"}, + {file = "simplejson-3.19.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:6d43e24b88c80f997081503f693be832fc90854f278df277dd54f8a4c847ab61"}, + {file = "simplejson-3.19.3-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:2876027ebdd599d730d36464debe84619b0368e9a642ca6e7c601be55aed439e"}, + {file = "simplejson-3.19.3-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:0766ca6222b410e08e0053a0dda3606cafb3973d5d00538307f631bb59743396"}, + {file = "simplejson-3.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:50d8b742d74c449c4dcac570d08ce0f21f6a149d2d9cf7652dbf2ba9a1bc729a"}, + {file = "simplejson-3.19.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd011fc3c1d88b779645495fdb8189fb318a26981eebcce14109460e062f209b"}, + {file = "simplejson-3.19.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:637c4d4b81825c1f4d651e56210bd35b5604034b192b02d2d8f17f7ce8c18f42"}, + {file = "simplejson-3.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f56eb03bc9e432bb81adc8ecff2486d39feb371abb442964ffb44f6db23b332"}, + {file = "simplejson-3.19.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ef59a53be400c1fad2c914b8d74c9d42384fed5174f9321dd021b7017fd40270"}, + {file = "simplejson-3.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72e8abbc86fcac83629a030888b45fed3a404d54161118be52cb491cd6975d3e"}, + {file = "simplejson-3.19.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8efb03ca77bd7725dfacc9254df00d73e6f43013cf39bd37ef1a8ed0ebb5165"}, + {file = "simplejson-3.19.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:add8850db04b98507a8b62d248a326ecc8561e6d24336d1ca5c605bbfaab4cad"}, + {file = "simplejson-3.19.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fc3dc9fb413fc34c396f52f4c87de18d0bd5023804afa8ab5cc224deeb6a9900"}, + {file = "simplejson-3.19.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4dfa420bb9225dd33b6efdabde7c6a671b51150b9b1d9c4e5cd74d3b420b3fe1"}, + {file = "simplejson-3.19.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7b5c472099b39b274dcde27f1113db8d818c9aa3ba8f78cbb8ad04a4c1ac2118"}, + {file = "simplejson-3.19.3-cp310-cp310-win32.whl", hash = "sha256:817abad79241ed4a507b3caf4d3f2be5079f39d35d4c550a061988986bffd2ec"}, + {file = "simplejson-3.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:dd5b9b1783e14803e362a558680d88939e830db2466f3fa22df5c9319f8eea94"}, + {file = "simplejson-3.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e88abff510dcff903a18d11c2a75f9964e768d99c8d147839913886144b2065e"}, + {file = "simplejson-3.19.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:934a50a614fb831614db5dbfba35127ee277624dda4d15895c957d2f5d48610c"}, + {file = "simplejson-3.19.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:212fce86a22188b0c7f53533b0f693ea9605c1a0f02c84c475a30616f55a744d"}, + {file = "simplejson-3.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d9e8f836688a8fabe6a6b41b334aa550a6823f7b4ac3d3712fc0ad8655be9a8"}, + {file = "simplejson-3.19.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23228037dc5d41c36666384062904d74409a62f52283d9858fa12f4c22cffad1"}, + {file = "simplejson-3.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0791f64fed7d4abad639491f8a6b1ba56d3c604eb94b50f8697359b92d983f36"}, + {file = "simplejson-3.19.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4f614581b61a26fbbba232a1391f6cee82bc26f2abbb6a0b44a9bba25c56a1c"}, + {file = "simplejson-3.19.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1df0aaf1cb787fdf34484ed4a1f0c545efd8811f6028623290fef1a53694e597"}, + {file = "simplejson-3.19.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:951095be8d4451a7182403354c22ec2de3e513e0cc40408b689af08d02611588"}, + {file = "simplejson-3.19.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2a954b30810988feeabde843e3263bf187697e0eb5037396276db3612434049b"}, + {file = "simplejson-3.19.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c40df31a75de98db2cdfead6074d4449cd009e79f54c1ebe5e5f1f153c68ad20"}, + {file = "simplejson-3.19.3-cp311-cp311-win32.whl", hash = "sha256:7e2a098c21ad8924076a12b6c178965d88a0ad75d1de67e1afa0a66878f277a5"}, + {file = "simplejson-3.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:c9bedebdc5fdad48af8783022bae307746d54006b783007d1d3c38e10872a2c6"}, + {file = "simplejson-3.19.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:66a0399e21c2112acacfebf3d832ebe2884f823b1c7e6d1363f2944f1db31a99"}, + {file = "simplejson-3.19.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6ef9383c5e05f445be60f1735c1816163c874c0b1ede8bb4390aff2ced34f333"}, + {file = "simplejson-3.19.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:42e5acf80d4d971238d4df97811286a044d720693092b20a56d5e56b7dcc5d09"}, + {file = "simplejson-3.19.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0b0efc7279d768db7c74d3d07f0b5c81280d16ae3fb14e9081dc903e8360771"}, + {file = "simplejson-3.19.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0552eb06e7234da892e1d02365cd2b7b2b1f8233aa5aabdb2981587b7cc92ea0"}, + {file = "simplejson-3.19.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf6a3b9a7d7191471b464fe38f684df10eb491ec9ea454003edb45a011ab187"}, + {file = "simplejson-3.19.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7017329ca8d4dca94ad5e59f496e5fc77630aecfc39df381ffc1d37fb6b25832"}, + {file = "simplejson-3.19.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:67a20641afebf4cfbcff50061f07daad1eace6e7b31d7622b6fa2c40d43900ba"}, + {file = "simplejson-3.19.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:dd6a7dabcc4c32daf601bc45e01b79175dde4b52548becea4f9545b0a4428169"}, + {file = "simplejson-3.19.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:08f9b443a94e72dd02c87098c96886d35790e79e46b24e67accafbf13b73d43b"}, + {file = "simplejson-3.19.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fa97278ae6614346b5ca41a45a911f37a3261b57dbe4a00602048652c862c28b"}, + {file = "simplejson-3.19.3-cp312-cp312-win32.whl", hash = "sha256:ef28c3b328d29b5e2756903aed888960bc5df39b4c2eab157ae212f70ed5bf74"}, + {file = "simplejson-3.19.3-cp312-cp312-win_amd64.whl", hash = "sha256:1e662336db50ad665777e6548b5076329a94a0c3d4a0472971c588b3ef27de3a"}, + {file = "simplejson-3.19.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0959e6cb62e3994b5a40e31047ff97ef5c4138875fae31659bead691bed55896"}, + {file = "simplejson-3.19.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a7bfad839c624e139a4863007233a3f194e7c51551081f9789cba52e4da5167"}, + {file = "simplejson-3.19.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afab2f7f2486a866ff04d6d905e9386ca6a231379181a3838abce1f32fbdcc37"}, + {file = "simplejson-3.19.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d00313681015ac498e1736b304446ee6d1c72c5b287cd196996dad84369998f7"}, + {file = "simplejson-3.19.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d936ae682d5b878af9d9eb4d8bb1fdd5e41275c8eb59ceddb0aeed857bb264a2"}, + {file = "simplejson-3.19.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c6657485393f2e9b8177c77a7634f13ebe70d5e6de150aae1677d91516ce6b"}, + {file = "simplejson-3.19.3-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a6a750d3c7461b1c47cfc6bba8d9e57a455e7c5f80057d2a82f738040dd1129"}, + {file = "simplejson-3.19.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ea7a4a998c87c5674a27089e022110a1a08a7753f21af3baf09efe9915c23c3c"}, + {file = "simplejson-3.19.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6300680d83a399be2b8f3b0ef7ef90b35d2a29fe6e9c21438097e0938bbc1564"}, + {file = "simplejson-3.19.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ab69f811a660c362651ae395eba8ce84f84c944cea0df5718ea0ba9d1e4e7252"}, + {file = "simplejson-3.19.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:256e09d0f94d9c3d177d9e95fd27a68c875a4baa2046633df387b86b652f5747"}, + {file = "simplejson-3.19.3-cp313-cp313-win32.whl", hash = "sha256:2c78293470313aefa9cfc5e3f75ca0635721fb016fb1121c1c5b0cb8cc74712a"}, + {file = "simplejson-3.19.3-cp313-cp313-win_amd64.whl", hash = "sha256:3bbcdc438dc1683b35f7a8dc100960c721f922f9ede8127f63bed7dfded4c64c"}, + {file = "simplejson-3.19.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:89b35433186e977fa86ff1fd179c1fadff39cfa3afa1648dab0b6ca53153acd9"}, + {file = "simplejson-3.19.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d43c2d7504eda566c50203cdc9dc043aff6f55f1b7dae0dcd79dfefef9159d1c"}, + {file = "simplejson-3.19.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6890ff9cf0bd2e1d487e2a8869ebd620a44684c0a9667fa5ee751d099d5d84c8"}, + {file = "simplejson-3.19.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1069143a8fb3905e1bc0696c62be7e3adf812e9f1976ac9ae15b05112ff57cc9"}, + {file = "simplejson-3.19.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb324bb903330cbb35d87cce367a12631cd5720afa06e5b9c906483970946da6"}, + {file = "simplejson-3.19.3-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:0a32859d45d7b85fb803bb68f6bee14526991a1190269116c33399fa0daf9bbf"}, + {file = "simplejson-3.19.3-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:23833ee7e791ec968b744dfee2a2d39df7152050051096caf4296506d75608d8"}, + {file = "simplejson-3.19.3-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:d73efb03c5b39249c82488a994f0998f9e4399e3d085209d2120503305ba77a8"}, + {file = "simplejson-3.19.3-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:7923878b7a0142d39763ec2dbecff3053c1bedd3653585a8474666e420fe83f5"}, + {file = "simplejson-3.19.3-cp36-cp36m-win32.whl", hash = "sha256:7355c7203353c36d46c4e7b6055293b3d2be097bbc5e2874a2b8a7259f0325dd"}, + {file = "simplejson-3.19.3-cp36-cp36m-win_amd64.whl", hash = "sha256:d1b8b4d6379fe55f471914345fe6171d81a18649dacf3248abfc9c349b4442eb"}, + {file = "simplejson-3.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d36608557b4dcd7a62c29ad4cd7c5a1720bbf7dc942eff9dc42d2c542a5f042d"}, + {file = "simplejson-3.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7137e69c6781ecf23afab064be94a277236c9cba31aa48ff1a0ec3995c69171e"}, + {file = "simplejson-3.19.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76f8c28fe2d426182405b18ddf3001fce47835a557dc15c3d8bdea01c03361da"}, + {file = "simplejson-3.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff7bc1bbdaa3e487c9469128bf39408e91f5573901cb852e03af378d3582c52d"}, + {file = "simplejson-3.19.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0782cb9bf827f0c488b6aa0f2819f618308a3caf2973cfd792e45d631bec4db"}, + {file = "simplejson-3.19.3-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:6fea0716c593dabb4392c4996d4e902a83b2428e6da82938cf28a523a11eb277"}, + {file = "simplejson-3.19.3-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:8f41bb5370b34f63171e65fdb00e12be1d83675cecb23e627df26f4c88dfc021"}, + {file = "simplejson-3.19.3-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:37105d1d708365b91165e1a6e505bdecc88637091348cf4b6adcdcb4f5a5fb8b"}, + {file = "simplejson-3.19.3-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:b9198c1f1f8910a3b86b60f4fe2556d9d28d3fefe35bffe6be509a27402e694d"}, + {file = "simplejson-3.19.3-cp37-cp37m-win32.whl", hash = "sha256:bc164f32dd9691e7082ce5df24b4cf8c6c394bbf9bdeeb5d843127cd07ab8ad2"}, + {file = "simplejson-3.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:1bd41f2cb1a2c57656ceff67b12d005cb255c728265e222027ad73193a04005a"}, + {file = "simplejson-3.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0733ecd95ae03ae718ec74aad818f5af5f3155d596f7b242acbc1621e765e5fb"}, + {file = "simplejson-3.19.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4a0710d1a5e41c4f829caa1572793dd3130c8d65c2b194c24ff29c4c305c26e0"}, + {file = "simplejson-3.19.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1a53a07320c5ff574d8b1a89c937ce33608832f166f39dff0581ac43dc979abd"}, + {file = "simplejson-3.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1773cabfba66a6337b547e45dafbd471b09487370bcab75bd28f626520410d29"}, + {file = "simplejson-3.19.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c0104b4b7d2c75ccedbf1d9d5a3bd2daa75e51053935a44ba012e2fd4c43752"}, + {file = "simplejson-3.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c49eeb94b8f09dc8a5843c156a22b8bde6aa1ddc65ca8ddc62dddcc001e6a2d"}, + {file = "simplejson-3.19.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dc5c1a85ff388e98ea877042daec3d157b6db0d85bac6ba5498034689793e7e"}, + {file = "simplejson-3.19.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:49549e3d81ab4a58424405aa545602674d8c35c20e986b42bb8668e782a94bac"}, + {file = "simplejson-3.19.3-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:e1a1452ad5723ff129b081e3c8aa4ba56b8734fee4223355ed7b815a7ece69bc"}, + {file = "simplejson-3.19.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:d0d5a63f1768fed7e78cf55712dee81f5a345e34d34224f3507ebf71df2b754d"}, + {file = "simplejson-3.19.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7e062767ac165df9a46963f5735aa4eee0089ec1e48b3f2ec46182754b96f55e"}, + {file = "simplejson-3.19.3-cp38-cp38-win32.whl", hash = "sha256:56134bbafe458a7b21f6fddbf889d36bec6d903718f4430768e3af822f8e27c2"}, + {file = "simplejson-3.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:bcde83a553a96dc7533736c547bddaa35414a2566ab0ecf7d3964fc4bdb84c11"}, + {file = "simplejson-3.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b5587feda2b65a79da985ae6d116daf6428bf7489992badc29fc96d16cd27b05"}, + {file = "simplejson-3.19.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e0d2b00ecbcd1a3c5ea1abc8bb99a26508f758c1759fd01c3be482a3655a176f"}, + {file = "simplejson-3.19.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:32a3ada8f3ea41db35e6d37b86dade03760f804628ec22e4fe775b703d567426"}, + {file = "simplejson-3.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f455672f4738b0f47183c5896e3606cd65c9ddee3805a4d18e8c96aa3f47c84"}, + {file = "simplejson-3.19.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b737a5fefedb8333fa50b8db3dcc9b1d18fd6c598f89fa7debff8b46bf4e511"}, + {file = "simplejson-3.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb47ee773ce67476a960e2db4a0a906680c54f662521550828c0cc57d0099426"}, + {file = "simplejson-3.19.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eed8cd98a7b24861da9d3d937f5fbfb6657350c547528a117297fe49e3960667"}, + {file = "simplejson-3.19.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:619756f1dd634b5bdf57d9a3914300526c3b348188a765e45b8b08eabef0c94e"}, + {file = "simplejson-3.19.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:dd7230d061e755d60a4d5445bae854afe33444cdb182f3815cff26ac9fb29a15"}, + {file = "simplejson-3.19.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:101a3c8392028cd704a93c7cba8926594e775ca3c91e0bee82144e34190903f1"}, + {file = "simplejson-3.19.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e557712fc79f251673aeb3fad3501d7d4da3a27eff0857af2e1d1afbbcf6685"}, + {file = "simplejson-3.19.3-cp39-cp39-win32.whl", hash = "sha256:0bc5544e3128891bf613b9f71813ee2ec9c11574806f74dd8bb84e5e95bf64a2"}, + {file = "simplejson-3.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:06662392e4913dc8846d6a71a6d5de86db5fba244831abe1dd741d62a4136764"}, + {file = "simplejson-3.19.3-py3-none-any.whl", hash = "sha256:49cc4c7b940d43bd12bf87ec63f28cbc4964fc4e12c031cc8cd01650f43eb94e"}, + {file = "simplejson-3.19.3.tar.gz", hash = "sha256:8e086896c36210ab6050f2f9f095a5f1e03c83fa0e7f296d6cba425411364680"}, +] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "slack-sdk" +version = "3.31.0" +description = "The Slack API Platform SDK for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "slack_sdk-3.31.0-py2.py3-none-any.whl", hash = "sha256:a120cc461e8ebb7d9175f171dbe0ded37a6878d9f7b96b28e4bad1227399047b"}, + {file = "slack_sdk-3.31.0.tar.gz", hash = "sha256:740d2f9c49cbfcbd46fca56b4be9d527934c225312aac18fd2c0fca0ef6bc935"}, +] + +[package.extras] +optional = ["SQLAlchemy (>=1.4,<3)", "aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "websocket-client (>=1,<2)", "websockets (>=9.1,<13)"] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "socialscan" +version = "1.4.2" +description = "Open-source intelligence tool for checking email address and username usage on online platforms" +optional = false +python-versions = ">=3.6" +files = [ + {file = "socialscan-1.4.2-py3-none-any.whl", hash = "sha256:47f042bb2ab1afb77c2cf2f31e6ab43afa91ff87849a79307cf753dfc7b84f20"}, + {file = "socialscan-1.4.2.tar.gz", hash = "sha256:d03eb63177c516b1b8eb1fbca3d25753bb6d68b56e7325a96414b8b319c5daad"}, +] + +[package.dependencies] +aiohttp = ">=3.5.0" +colorama = "*" +tqdm = ">=4.31.0" + +[package.extras] +tests = ["aiohttp (>=3.5.0)", "colorama", "dataclasses", "flake8", "tox", "tqdm (>=4.31.0)"] + +[[package]] +name = "socketio-client" +version = "0.5.7.4" +description = "A socket.io client library" +optional = false +python-versions = "*" +files = [ + {file = "socketIO-client-0.5.7.4.tar.gz", hash = "sha256:ef2e362a85ef2816fb224d727319c4b743d63b4dd9e1da99c622c9643fc4e2a0"}, +] + +[package.dependencies] +requests = ">=2.7.0" +six = ">=1.10.0" +websocket-client = ">=0.44.0" + +[[package]] +name = "softenum" +version = "1.0.1" +description = "" +optional = false +python-versions = ">=3.7.0,<4.0.0" +files = [ + {file = "softenum-1.0.1-py3-none-any.whl", hash = "sha256:df6459434d79ed397a28a39c3f7ea2a21b94d7fb3bad8452361a5f01b22793c1"}, + {file = "softenum-1.0.1.tar.gz", hash = "sha256:6c7d9c2b49937b1ba637b2cc3c57db1e470ed7ca9457109b4833a5824bbc1476"}, +] + +[[package]] +name = "soupsieve" +version = "2.6" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, + {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, +] + +[[package]] +name = "sparqlwrapper" +version = "2.0.0" +description = "SPARQL Endpoint interface to Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "SPARQLWrapper-2.0.0-py3-none-any.whl", hash = "sha256:c99a7204fff676ee28e6acef327dc1ff8451c6f7217dcd8d49e8872f324a8a20"}, + {file = "SPARQLWrapper-2.0.0.tar.gz", hash = "sha256:3fed3ebcc77617a4a74d2644b86fd88e0f32e7f7003ac7b2b334c026201731f1"}, +] + +[package.dependencies] +rdflib = ">=6.1.1" + +[package.extras] +dev = ["mypy (>=0.931)", "pandas (>=1.3.5)", "pandas-stubs (>=1.2.0.48)", "setuptools (>=3.7.1)"] +docs = ["sphinx (<5)", "sphinx-rtd-theme"] +keepalive = ["keepalive (>=0.5)"] +pandas = ["pandas (>=1.3.5)"] + +[[package]] +name = "stix2" +version = "3.0.1" +description = "Produce and consume STIX 2 JSON content" +optional = false +python-versions = ">=3.6" +files = [ + {file = "stix2-3.0.1-py2.py3-none-any.whl", hash = "sha256:827acf0b5b319c1b857c9db0d54907bb438b2b32312d236c891a305ad49b0ba2"}, + {file = "stix2-3.0.1.tar.gz", hash = "sha256:2a2718dc3451c84c709990b2ca220cc39c75ed23e0864d7e8d8190a9365b0cbf"}, +] + +[package.dependencies] +pytz = "*" +requests = "*" +simplejson = "*" +stix2-patterns = ">=1.2.0" + +[package.extras] +semantic = ["haversine", "rapidfuzz"] +taxii = ["taxii2-client (>=2.3.0)"] + +[[package]] +name = "stix2-patterns" +version = "2.0.0" +description = "Validate STIX 2 Patterns." +optional = false +python-versions = ">=3.6" +files = [ + {file = "stix2-patterns-2.0.0.tar.gz", hash = "sha256:07750c5a5af2c758e9d2aa4dde9d8e04bcd162ac2a9b0b4c4de4481d443efa08"}, + {file = "stix2_patterns-2.0.0-py2.py3-none-any.whl", hash = "sha256:ca4d68b2db42ed99794a418388769d2676ca828e9cac0b8629e73cd3f68f6458"}, +] + +[package.dependencies] +antlr4-python3-runtime = ">=4.9.0,<4.10.0" +six = "*" + +[package.extras] +dev = ["bumpversion", "check-manifest", "coverage", "pre-commit", "pytest", "pytest-cov", "sphinx", "sphinx-prompt", "tox"] +docs = ["sphinx", "sphinx-prompt"] +test = ["coverage", "pytest", "pytest-cov"] + +[[package]] +name = "tabulate" +version = "0.9.0" +description = "Pretty-print tabular data" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] + +[package.extras] +widechars = ["wcwidth"] + +[[package]] +name = "tau-clients" +version = "0.3.0" +description = "Set of clients to interface with various VMware products" +optional = false +python-versions = ">=3.6" +files = [ + {file = "tau-clients-0.3.0.tar.gz", hash = "sha256:3450999b521fcb1ce0ece94373697e7d5fadd10d66992776df9f91871d51c3c7"}, + {file = "tau_clients-0.3.0-py3-none-any.whl", hash = "sha256:d24e22cc31333efa1c78eb2968c6330e640db1ff563bf5768f6d834db11f2a05"}, +] + +[package.dependencies] +more-itertools = "*" +requests = "*" +vt-py = "*" + +[package.extras] +misp = ["pymisp"] + +[[package]] +name = "taxii2-client" +version = "2.3.0" +description = "TAXII 2 Client Library" +optional = false +python-versions = "*" +files = [ + {file = "taxii2-client-2.3.0.tar.gz", hash = "sha256:fb3bf895e2eaff3cd08bb7aad75c9d30682ffc00b9f3add77de3a67dc6b895a3"}, + {file = "taxii2_client-2.3.0-py2.py3-none-any.whl", hash = "sha256:b4212b8a8bab170cd5dc386ca3ea36bc44b53932f1da30db150abeef00bce7b9"}, +] + +[package.dependencies] +pytz = "*" +requests = "*" +six = "*" + +[package.extras] +docs = ["sphinx", "sphinx-prompt"] +test = ["coverage", "pytest", "pytest-cov", "responses", "tox"] + +[[package]] +name = "termcolor" +version = "2.4.0" +description = "ANSI color formatting for output in terminal" +optional = false +python-versions = ">=3.8" +files = [ + {file = "termcolor-2.4.0-py3-none-any.whl", hash = "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63"}, + {file = "termcolor-2.4.0.tar.gz", hash = "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a"}, +] + +[package.extras] +tests = ["pytest", "pytest-cov"] + +[[package]] +name = "tldextract" +version = "5.1.2" +description = "Accurately separates a URL's subdomain, domain, and public suffix, using the Public Suffix List (PSL). By default, this includes the public ICANN TLDs and their exceptions. You can optionally support the Public Suffix List's private domains as well." +optional = false +python-versions = ">=3.8" +files = [ + {file = "tldextract-5.1.2-py3-none-any.whl", hash = "sha256:4dfc4c277b6b97fa053899fcdb892d2dc27295851ab5fac4e07797b6a21b2e46"}, + {file = "tldextract-5.1.2.tar.gz", hash = "sha256:c9e17f756f05afb5abac04fe8f766e7e70f9fe387adb1859f0f52408ee060200"}, +] + +[package.dependencies] +filelock = ">=3.0.8" +idna = "*" +requests = ">=2.1.0" +requests-file = ">=1.4" + +[package.extras] +release = ["build", "twine"] +testing = ["black", "mypy", "pytest", "pytest-gitignore", "pytest-mock", "responses", "ruff", "syrupy", "tox", "types-filelock", "types-requests"] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "tornado" +version = "6.4.1" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">=3.8" +files = [ + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"}, + {file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"}, + {file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"}, + {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, +] + +[[package]] +name = "tqdm" +version = "4.66.5" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, + {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "trustar" +version = "0.3.34" +description = "Python SDK for the TruSTAR REST API" +optional = false +python-versions = "*" +files = [] +develop = false + +[package.dependencies] +configparser = "*" +future = "*" +json_log_formatter = "*" +python-dateutil = "*" +pytz = "*" +PyYAML = "*" +requests = "*" +six = "*" +tzlocal = "*" +unicodecsv = "*" + +[package.source] +type = "git" +url = "https://github.com/SteveClement/trustar-python.git" +reference = "HEAD" +resolved_reference = "6954eae38e0c77eaeef26084b6c5fd033925c1c7" + +[[package]] +name = "typer" +version = "0.12.4" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.7" +files = [ + {file = "typer-0.12.4-py3-none-any.whl", hash = "sha256:819aa03699f438397e876aa12b0d63766864ecba1b579092cc9fe35d886e34b6"}, + {file = "typer-0.12.4.tar.gz", hash = "sha256:c9c1613ed6a166162705b3347b8d10b661ccc5d95692654d0fb628118f2c34e6"}, +] + +[package.dependencies] +click = ">=8.0.0" +rich = ">=10.11.0" +shellingham = ">=1.3.0" +typing-extensions = ">=3.7.4.3" + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "tzlocal" +version = "5.2" +description = "tzinfo object for the local timezone" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"}, + {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"}, +] + +[package.dependencies] +"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} +tzdata = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"] + +[[package]] +name = "unicodecsv" +version = "0.14.1" +description = "Python2's stdlib csv module is nice, but it doesn't support unicode. This module is a drop-in replacement which *does*." +optional = false +python-versions = "*" +files = [ + {file = "unicodecsv-0.14.1.tar.gz", hash = "sha256:018c08037d48649a0412063ff4eda26eaa81eff1546dbffa51fa5293276ff7fc"}, +] + +[[package]] +name = "unidecode" +version = "1.3.8" +description = "ASCII transliterations of Unicode text" +optional = false +python-versions = ">=3.5" +files = [ + {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, + {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, +] + +[[package]] +name = "url-normalize" +version = "1.4.3" +description = "URL normalization for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, + {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "urlarchiver" +version = "0.2" +description = "url-archiver is a simple library to fetch and archive URL on the file-system." +optional = false +python-versions = "*" +files = [ + {file = "urlarchiver-0.2.tar.gz", hash = "sha256:652e0890dab58bf62a759656671dcfb9a40eb4a77aac8a8d93154f00360238b5"}, +] + +[package.dependencies] +requests = "*" +url-normalize = "*" + +[[package]] +name = "urllib3" +version = "1.26.19" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "urllib3-1.26.19-py2.py3-none-any.whl", hash = "sha256:37a0344459b199fce0e80b0d3569837ec6b6937435c5244e7fd73fa6006830f3"}, + {file = "urllib3-1.26.19.tar.gz", hash = "sha256:3e3d753a8618b86d7de333b4223005f68720bcd6a7d2bcb9fbd2229ec7c1e429"}, +] + +[package.extras] +brotli = ["brotli (==1.0.9)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "urllib3" +version = "2.2.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "vcrpy" +version = "6.0.1" +description = "Automatically mock your HTTP interactions to simplify and speed up testing" +optional = false +python-versions = ">=3.8" +files = [ + {file = "vcrpy-6.0.1-py2.py3-none-any.whl", hash = "sha256:621c3fb2d6bd8aa9f87532c688e4575bcbbde0c0afeb5ebdb7e14cac409edfdd"}, + {file = "vcrpy-6.0.1.tar.gz", hash = "sha256:9e023fee7f892baa0bbda2f7da7c8ac51165c1c6e38ff8688683a12a4bde9278"}, +] + +[package.dependencies] +PyYAML = "*" +urllib3 = {version = "<2", markers = "platform_python_implementation == \"PyPy\" or python_version < \"3.10\""} +wrapt = "*" +yarl = "*" + +[package.extras] +tests = ["Werkzeug (==2.0.3)", "aiohttp", "boto3", "httplib2", "httpx", "pytest", "pytest-aiohttp", "pytest-asyncio", "pytest-cov", "pytest-httpbin", "requests (>=2.22.0)", "tornado", "urllib3"] + +[[package]] +name = "vt-graph-api" +version = "2.2.0" +description = "The official Python client library for VirusTotal Graph API" +optional = false +python-versions = "*" +files = [ + {file = "vt_graph_api-2.2.0-py3-none-any.whl", hash = "sha256:78da5af6a0583d0d8881c4fc3b2cb2f64075e40ac06bd47c13c414f09ff175fd"}, + {file = "vt_graph_api-2.2.0.tar.gz", hash = "sha256:c44936aac6de7755c1445ed46ecc98c3c613f4b467b4738426a28101183df7ef"}, +] + +[package.dependencies] +requests = "*" +six = "*" + +[[package]] +name = "vt-py" +version = "0.18.3" +description = "The official Python client library for VirusTotal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "vt_py-0.18.3-py3-none-any.whl", hash = "sha256:90630a8916cea0d6cc3ed7ebfdd82dd71640ac0f12429cac2ca93645562d84d4"}, + {file = "vt_py-0.18.3.tar.gz", hash = "sha256:187304b7dac378c71cddf82d34045ddbfea0e25e7ade0156feda36d408858186"}, +] + +[package.dependencies] +aiohttp = {version = "*", markers = "python_version > \"3.7\""} + +[package.extras] +test = ["flask", "pytest", "pytest-asyncio", "pytest-httpserver"] + +[[package]] +name = "vulners" +version = "2.2.0" +description = "Python library and command-line utility for Vulners (https://vulners.com)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "vulners-2.2.0-py3-none-any.whl", hash = "sha256:ffe8b79402ad4aeb64762fc3eeabfc82c0563ec8e2b79870c0e440618e1fe0e6"}, + {file = "vulners-2.2.0.tar.gz", hash = "sha256:8b444eba2174dc7ce643fc1d52d9fc5583f97ac86785e15e7f1bfa3117c28e5c"}, +] + +[package.dependencies] +appdirs = ">=1.4.4,<2.0.0" +requests = ">=2.31.0,<3.0.0" +six = ">=1.16.0,<2.0.0" + +[[package]] +name = "vysion" +version = "2.0.8" +description = "The official Python client library for Vysion" +optional = false +python-versions = "<4.0.0,>=3.8.0" +files = [ + {file = "vysion-2.0.8-py3-none-any.whl", hash = "sha256:52c8682e5685609c903ca6ea6c077e885c5bc715f082343f2b96adbda416aea7"}, + {file = "vysion-2.0.8.tar.gz", hash = "sha256:af553a9242c76c76fb56414f28a9f896d326c3bbbdc74d9033545495267969c5"}, +] + +[package.dependencies] +pydantic = ">=2.0.1,<3.0.0" +pymisp = ">=2.4.194,<3.0.0" +requests = ">=2.28.1,<3.0.0" +softenum = "1.0.1" + +[[package]] +name = "wand" +version = "0.6.13" +description = "Ctypes-based simple MagickWand API binding for Python" +optional = false +python-versions = "*" +files = [ + {file = "Wand-0.6.13-py2.py3-none-any.whl", hash = "sha256:e5dda0ac2204a40c29ef5c4cb310770c95d3d05c37b1379e69c94ea79d7d19c0"}, + {file = "Wand-0.6.13.tar.gz", hash = "sha256:f5013484eaf7a20eb22d1821aaefe60b50cc329722372b5f8565d46d4aaafcca"}, +] + +[package.extras] +doc = ["Sphinx (>=5.3.0)"] +test = ["pytest (>=7.2.0)"] + +[[package]] +name = "watchdog" +version = "4.0.2" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.8" +files = [ + {file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ede7f010f2239b97cc79e6cb3c249e72962404ae3865860855d5cbe708b0fd22"}, + {file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2cffa171445b0efa0726c561eca9a27d00a1f2b83846dbd5a4f639c4f8ca8e1"}, + {file = "watchdog-4.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c50f148b31b03fbadd6d0b5980e38b558046b127dc483e5e4505fcef250f9503"}, + {file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7c7d4bf585ad501c5f6c980e7be9c4f15604c7cc150e942d82083b31a7548930"}, + {file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:914285126ad0b6eb2258bbbcb7b288d9dfd655ae88fa28945be05a7b475a800b"}, + {file = "watchdog-4.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:984306dc4720da5498b16fc037b36ac443816125a3705dfde4fd90652d8028ef"}, + {file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1cdcfd8142f604630deef34722d695fb455d04ab7cfe9963055df1fc69e6727a"}, + {file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7ab624ff2f663f98cd03c8b7eedc09375a911794dfea6bf2a359fcc266bff29"}, + {file = "watchdog-4.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:132937547a716027bd5714383dfc40dc66c26769f1ce8a72a859d6a48f371f3a"}, + {file = "watchdog-4.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd67c7df93eb58f360c43802acc945fa8da70c675b6fa37a241e17ca698ca49b"}, + {file = "watchdog-4.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcfd02377be80ef3b6bc4ce481ef3959640458d6feaae0bd43dd90a43da90a7d"}, + {file = "watchdog-4.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:980b71510f59c884d684b3663d46e7a14b457c9611c481e5cef08f4dd022eed7"}, + {file = "watchdog-4.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:aa160781cafff2719b663c8a506156e9289d111d80f3387cf3af49cedee1f040"}, + {file = "watchdog-4.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f6ee8dedd255087bc7fe82adf046f0b75479b989185fb0bdf9a98b612170eac7"}, + {file = "watchdog-4.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0b4359067d30d5b864e09c8597b112fe0a0a59321a0f331498b013fb097406b4"}, + {file = "watchdog-4.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:770eef5372f146997638d737c9a3c597a3b41037cfbc5c41538fc27c09c3a3f9"}, + {file = "watchdog-4.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eeea812f38536a0aa859972d50c76e37f4456474b02bd93674d1947cf1e39578"}, + {file = "watchdog-4.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b2c45f6e1e57ebb4687690c05bc3a2c1fb6ab260550c4290b8abb1335e0fd08b"}, + {file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:10b6683df70d340ac3279eff0b2766813f00f35a1d37515d2c99959ada8f05fa"}, + {file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7c739888c20f99824f7aa9d31ac8a97353e22d0c0e54703a547a218f6637eb3"}, + {file = "watchdog-4.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c100d09ac72a8a08ddbf0629ddfa0b8ee41740f9051429baa8e31bb903ad7508"}, + {file = "watchdog-4.0.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:f5315a8c8dd6dd9425b974515081fc0aadca1d1d61e078d2246509fd756141ee"}, + {file = "watchdog-4.0.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:2d468028a77b42cc685ed694a7a550a8d1771bb05193ba7b24006b8241a571a1"}, + {file = "watchdog-4.0.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f15edcae3830ff20e55d1f4e743e92970c847bcddc8b7509bcd172aa04de506e"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:936acba76d636f70db8f3c66e76aa6cb5136a936fc2a5088b9ce1c7a3508fc83"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:e252f8ca942a870f38cf785aef420285431311652d871409a64e2a0a52a2174c"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_i686.whl", hash = "sha256:0e83619a2d5d436a7e58a1aea957a3c1ccbf9782c43c0b4fed80580e5e4acd1a"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:88456d65f207b39f1981bf772e473799fcdc10801062c36fd5ad9f9d1d463a73"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:32be97f3b75693a93c683787a87a0dc8db98bb84701539954eef991fb35f5fbc"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:c82253cfc9be68e3e49282831afad2c1f6593af80c0daf1287f6a92657986757"}, + {file = "watchdog-4.0.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c0b14488bd336c5b1845cee83d3e631a1f8b4e9c5091ec539406e4a324f882d8"}, + {file = "watchdog-4.0.2-py3-none-win32.whl", hash = "sha256:0d8a7e523ef03757a5aa29f591437d64d0d894635f8a50f370fe37f913ce4e19"}, + {file = "watchdog-4.0.2-py3-none-win_amd64.whl", hash = "sha256:c344453ef3bf875a535b0488e3ad28e341adbd5a9ffb0f7d62cefacc8824ef2b"}, + {file = "watchdog-4.0.2-py3-none-win_ia64.whl", hash = "sha256:baececaa8edff42cd16558a639a9b0ddf425f93d892e8392a56bf904f5eff22c"}, + {file = "watchdog-4.0.2.tar.gz", hash = "sha256:b4dfbb6c49221be4535623ea4474a4d6ee0a9cef4a80b20c28db4d858b64e270"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[[package]] +name = "websocket-client" +version = "1.8.0" +description = "WebSocket client for Python with low level API options" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, + {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, +] + +[package.extras] +docs = ["Sphinx (>=6.0)", "myst-parser (>=2.0.0)", "sphinx-rtd-theme (>=1.1.0)"] +optional = ["python-socks", "wsaccel"] +test = ["websockets"] + +[[package]] +name = "websockets" +version = "13.0" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websockets-13.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ad4fa707ff9e2ffee019e946257b5300a45137a58f41fbd9a4db8e684ab61528"}, + {file = "websockets-13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6fd757f313c13c34dae9f126d3ba4cf97175859c719e57c6a614b781c86b617e"}, + {file = "websockets-13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cbac2eb7ce0fac755fb983c9247c4a60c4019bcde4c0e4d167aeb17520cc7ef1"}, + {file = "websockets-13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4b83cf7354cbbc058e97b3e545dceb75b8d9cf17fd5a19db419c319ddbaaf7a"}, + {file = "websockets-13.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9202c0010c78fad1041e1c5285232b6508d3633f92825687549540a70e9e5901"}, + {file = "websockets-13.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6566e79c8c7cbea75ec450f6e1828945fc5c9a4769ceb1c7b6e22470539712"}, + {file = "websockets-13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e7fcad070dcd9ad37a09d89a4cbc2a5e3e45080b88977c0da87b3090f9f55ead"}, + {file = "websockets-13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a8f7d65358a25172db00c69bcc7df834155ee24229f560d035758fd6613111a"}, + {file = "websockets-13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:63b702fb31e3f058f946ccdfa551f4d57a06f7729c369e8815eb18643099db37"}, + {file = "websockets-13.0-cp310-cp310-win32.whl", hash = "sha256:3a20cf14ba7b482c4a1924b5e061729afb89c890ca9ed44ac4127c6c5986e424"}, + {file = "websockets-13.0-cp310-cp310-win_amd64.whl", hash = "sha256:587245f0704d0bb675f919898d7473e8827a6d578e5a122a21756ca44b811ec8"}, + {file = "websockets-13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:06df8306c241c235075d2ae77367038e701e53bc8c1bb4f6644f4f53aa6dedd0"}, + {file = "websockets-13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85a1f92a02f0b8c1bf02699731a70a8a74402bb3f82bee36e7768b19a8ed9709"}, + {file = "websockets-13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9ed02c604349068d46d87ef4c2012c112c791f2bec08671903a6bb2bd9c06784"}, + {file = "websockets-13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b89849171b590107f6724a7b0790736daead40926ddf47eadf998b4ff51d6414"}, + {file = "websockets-13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:939a16849d71203628157a5e4a495da63967c744e1e32018e9b9e2689aca64d4"}, + {file = "websockets-13.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad818cdac37c0ad4c58e51cb4964eae4f18b43c4a83cb37170b0d90c31bd80cf"}, + {file = "websockets-13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cbfe82a07596a044de78bb7a62519e71690c5812c26c5f1d4b877e64e4f46309"}, + {file = "websockets-13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e07e76c49f39c5b45cbd7362b94f001ae209a3ea4905ae9a09cfd53b3c76373d"}, + {file = "websockets-13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:372f46a0096cfda23c88f7e42349a33f8375e10912f712e6b496d3a9a557290f"}, + {file = "websockets-13.0-cp311-cp311-win32.whl", hash = "sha256:376a43a4fd96725f13450d3d2e98f4f36c3525c562ab53d9a98dd2950dca9a8a"}, + {file = "websockets-13.0-cp311-cp311-win_amd64.whl", hash = "sha256:2be1382a4daa61e2f3e2be3b3c86932a8db9d1f85297feb6e9df22f391f94452"}, + {file = "websockets-13.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b5407c34776b9b77bd89a5f95eb0a34aaf91889e3f911c63f13035220eb50107"}, + {file = "websockets-13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4782ec789f059f888c1e8fdf94383d0e64b531cffebbf26dd55afd53ab487ca4"}, + {file = "websockets-13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c8feb8e19ef65c9994e652c5b0324abd657bedd0abeb946fb4f5163012c1e730"}, + {file = "websockets-13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f3d2e20c442b58dbac593cb1e02bc02d149a86056cc4126d977ad902472e3b"}, + {file = "websockets-13.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e39d393e0ab5b8bd01717cc26f2922026050188947ff54fe6a49dc489f7750b7"}, + {file = "websockets-13.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f661a4205741bdc88ac9c2b2ec003c72cee97e4acd156eb733662ff004ba429"}, + {file = "websockets-13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:384129ad0490e06bab2b98c1da9b488acb35bb11e2464c728376c6f55f0d45f3"}, + {file = "websockets-13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:df5c0eff91f61b8205a6c9f7b255ff390cdb77b61c7b41f79ca10afcbb22b6cb"}, + {file = "websockets-13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:02cc9bb1a887dac0e08bf657c5d00aa3fac0d03215d35a599130c2034ae6663a"}, + {file = "websockets-13.0-cp312-cp312-win32.whl", hash = "sha256:d9726d2c9bd6aed8cb994d89b3910ca0079406edce3670886ec828a73e7bdd53"}, + {file = "websockets-13.0-cp312-cp312-win_amd64.whl", hash = "sha256:fa0839f35322f7b038d8adcf679e2698c3a483688cc92e3bd15ee4fb06669e9a"}, + {file = "websockets-13.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:da7e501e59857e8e3e9d10586139dc196b80445a591451ca9998aafba1af5278"}, + {file = "websockets-13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a00e1e587c655749afb5b135d8d3edcfe84ec6db864201e40a882e64168610b3"}, + {file = "websockets-13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a7fbf2a8fe7556a8f4e68cb3e736884af7bf93653e79f6219f17ebb75e97d8f0"}, + {file = "websockets-13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ea9c9c7443a97ea4d84d3e4d42d0e8c4235834edae652993abcd2aff94affd7"}, + {file = "websockets-13.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35c2221b539b360203f3f9ad168e527bf16d903e385068ae842c186efb13d0ea"}, + {file = "websockets-13.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:358d37c5c431dd050ffb06b4b075505aae3f4f795d7fff9794e5ed96ce99b998"}, + {file = "websockets-13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:038e7a0f1bfafc7bf52915ab3506b7a03d1e06381e9f60440c856e8918138151"}, + {file = "websockets-13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fd038bc9e2c134847f1e0ce3191797fad110756e690c2fdd9702ed34e7a43abb"}, + {file = "websockets-13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93b8c2008f372379fb6e5d2b3f7c9ec32f7b80316543fd3a5ace6610c5cde1b0"}, + {file = "websockets-13.0-cp313-cp313-win32.whl", hash = "sha256:851fd0afb3bc0b73f7c5b5858975d42769a5fdde5314f4ef2c106aec63100687"}, + {file = "websockets-13.0-cp313-cp313-win_amd64.whl", hash = "sha256:7d14901fdcf212804970c30ab9ee8f3f0212e620c7ea93079d6534863444fb4e"}, + {file = "websockets-13.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae7a519a56a714f64c3445cabde9fc2fc927e7eae44f413eae187cddd9e54178"}, + {file = "websockets-13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5575031472ca87302aeb2ce2c2349f4c6ea978c86a9d1289bc5d16058ad4c10a"}, + {file = "websockets-13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9895df6cd0bfe79d09bcd1dbdc03862846f26fbd93797153de954306620c1d00"}, + {file = "websockets-13.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4de299c947a54fca9ce1c5fd4a08eb92ffce91961becb13bd9195f7c6e71b47"}, + {file = "websockets-13.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05c25f7b849702950b6fd0e233989bb73a0d2bc83faa3b7233313ca395205f6d"}, + {file = "websockets-13.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ede95125a30602b1691a4b1da88946bf27dae283cf30f22cd2cb8ca4b2e0d119"}, + {file = "websockets-13.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:addf0a16e4983280efed272d8cb3b2e05f0051755372461e7d966b80a6554e16"}, + {file = "websockets-13.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:06b3186e97bf9a33921fa60734d5ed90f2a9b407cce8d23c7333a0984049ef61"}, + {file = "websockets-13.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:eae368cac85adc4c7dc3b0d5f84ffcca609d658db6447387300478e44db70796"}, + {file = "websockets-13.0-cp38-cp38-win32.whl", hash = "sha256:337837ac788d955728b1ab01876d72b73da59819a3388e1c5e8e05c3999f1afa"}, + {file = "websockets-13.0-cp38-cp38-win_amd64.whl", hash = "sha256:f66e00e42f25ca7e91076366303e11c82572ca87cc5aae51e6e9c094f315ab41"}, + {file = "websockets-13.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:94c1c02721139fe9940b38d28fb15b4b782981d800d5f40f9966264fbf23dcc8"}, + {file = "websockets-13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd4ba86513430513e2aa25a441bb538f6f83734dc368a2c5d18afdd39097aa33"}, + {file = "websockets-13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a1ab8f0e0cadc5be5f3f9fa11a663957fecbf483d434762c8dfb8aa44948944a"}, + {file = "websockets-13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3670def5d3dfd5af6f6e2b3b243ea8f1f72d8da1ef927322f0703f85c90d9603"}, + {file = "websockets-13.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6058b6be92743358885ad6dcdecb378fde4a4c74d4dd16a089d07580c75a0e80"}, + {file = "websockets-13.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516062a0a8ef5ecbfa4acbaec14b199fc070577834f9fe3d40800a99f92523ca"}, + {file = "websockets-13.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:da7e918d82e7bdfc6f66d31febe1b2e28a1ca3387315f918de26f5e367f61572"}, + {file = "websockets-13.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9cc7f35dcb49a4e32db82a849fcc0714c4d4acc9d2273aded2d61f87d7f660b7"}, + {file = "websockets-13.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f5737c53eb2c8ed8f64b50d3dafd3c1dae739f78aa495a288421ac1b3de82717"}, + {file = "websockets-13.0-cp39-cp39-win32.whl", hash = "sha256:265e1f0d3f788ce8ef99dca591a1aec5263b26083ca0934467ad9a1d1181067c"}, + {file = "websockets-13.0-cp39-cp39-win_amd64.whl", hash = "sha256:4d70c89e3d3b347a7c4d3c33f8d323f0584c9ceb69b82c2ef8a174ca84ea3d4a"}, + {file = "websockets-13.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:602cbd010d8c21c8475f1798b705bb18567eb189c533ab5ef568bc3033fdf417"}, + {file = "websockets-13.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:bf8eb5dca4f484a60f5327b044e842e0d7f7cdbf02ea6dc4a4f811259f1f1f0b"}, + {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89d795c1802d99a643bf689b277e8604c14b5af1bc0a31dade2cd7a678087212"}, + {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:788bc841d250beccff67a20a5a53a15657a60111ef9c0c0a97fbdd614fae0fe2"}, + {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7334752052532c156d28b8eaf3558137e115c7871ea82adff69b6d94a7bee273"}, + {file = "websockets-13.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7a1963302947332c3039e3f66209ec73b1626f8a0191649e0713c391e9f5b0d"}, + {file = "websockets-13.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e1cf4e1eb84b4fd74a47688e8b0940c89a04ad9f6937afa43d468e71128cd68"}, + {file = "websockets-13.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:c026ee729c4ce55708a14b839ba35086dfae265fc12813b62d34ce33f4980c1c"}, + {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5f9d23fbbf96eefde836d9692670bfc89e2d159f456d499c5efcf6a6281c1af"}, + {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ad684cb7efce227d756bae3e8484f2e56aa128398753b54245efdfbd1108f2c"}, + {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1e10b3fbed7be4a59831d3a939900e50fcd34d93716e433d4193a4d0d1d335d"}, + {file = "websockets-13.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d42a818e634f789350cd8fb413a3f5eec1cf0400a53d02062534c41519f5125c"}, + {file = "websockets-13.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5ba5e9b332267d0f2c33ede390061850f1ac3ee6cd1bdcf4c5ea33ead971966"}, + {file = "websockets-13.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f9af457ed593e35f467140d8b61d425495b127744a9d65d45a366f8678449a23"}, + {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcea3eb58c09c3a31cc83b45c06d5907f02ddaf10920aaa6443975310f699b95"}, + {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c210d1460dc8d326ffdef9703c2f83269b7539a1690ad11ae04162bc1878d33d"}, + {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b32f38bc81170fd56d0482d505b556e52bf9078b36819a8ba52624bd6667e39e"}, + {file = "websockets-13.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:81a11a1ddd5320429db47c04d35119c3e674d215173d87aaeb06ae80f6e9031f"}, + {file = "websockets-13.0-py3-none-any.whl", hash = "sha256:dbbac01e80aee253d44c4f098ab3cc17c822518519e869b284cfbb8cd16cc9de"}, + {file = "websockets-13.0.tar.gz", hash = "sha256:b7bf950234a482b7461afdb2ec99eee3548ec4d53f418c7990bb79c620476602"}, +] + +[[package]] +name = "win-unicode-console" +version = "0.5" +description = "Enable Unicode input and display when running Python from Windows console." +optional = false +python-versions = "*" +files = [ + {file = "win_unicode_console-0.5.zip", hash = "sha256:d4142d4d56d46f449d6f00536a73625a871cba040f0bc1a2e305a04578f07d1e"}, +] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[[package]] +name = "wsproto" +version = "1.2.0" +description = "WebSockets state-machine based protocol implementation" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"}, + {file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"}, +] + +[package.dependencies] +h11 = ">=0.9.0,<1" + +[[package]] +name = "xlrd" +version = "2.0.1" +description = "Library for developers to extract data from Microsoft Excel (tm) .xls spreadsheet files" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "xlrd-2.0.1-py2.py3-none-any.whl", hash = "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd"}, + {file = "xlrd-2.0.1.tar.gz", hash = "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88"}, +] + +[package.extras] +build = ["twine", "wheel"] +docs = ["sphinx"] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "xlsxwriter" +version = "3.2.0" +description = "A Python module for creating Excel XLSX files." +optional = false +python-versions = ">=3.6" +files = [ + {file = "XlsxWriter-3.2.0-py3-none-any.whl", hash = "sha256:ecfd5405b3e0e228219bcaf24c2ca0915e012ca9464a14048021d21a995d490e"}, + {file = "XlsxWriter-3.2.0.tar.gz", hash = "sha256:9977d0c661a72866a61f9f7a809e25ebbb0fb7036baa3b9fe74afcfca6b3cb8c"}, +] + +[[package]] +name = "yara-python" +version = "4.5.0" +description = "Python interface for YARA" +optional = false +python-versions = "*" +files = [ + {file = "yara-python-4.5.0.tar.gz", hash = "sha256:4feecc56d2fe1d23ecb17cb2d3bc2e3859ebf7a2201d0ca3ae0756a728122b27"}, + {file = "yara_python-4.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3feb72c2146c50e583d7e3cacbb49f280fb5cac0494cae1b48e5980ecbdc1571"}, + {file = "yara_python-4.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1a036c41eaebdf6c0a674e0bd9d37c9d06d1d7427455866ace09d3a159c442b0"}, + {file = "yara_python-4.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acbc950b051a576dd4c6825bf4ebb1c0f0c5eea35b3e01bde921b744e2cc92e1"}, + {file = "yara_python-4.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11bb478dee0450af1f6643a138b9eaec085ab79aa4a4aef786390c5dfc70f0d0"}, + {file = "yara_python-4.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1633d5653d37b6ef6517113ed446159d8de67d02893c00c43daecd9bbcb9700b"}, + {file = "yara_python-4.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:82109dd8c932c3326a9747ac3ac62857868fcc9d9fe55d6f46ff0b4dcf14eb57"}, + {file = "yara_python-4.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:85af2755732081e5fb99fc4295659690f97b61b7a1428e857dbfe91f12f9cf7d"}, + {file = "yara_python-4.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a776f86060aebd4e31c74927ddd13e6b3c21a59e4586da8667e69849e5008872"}, + {file = "yara_python-4.5.0-cp310-cp310-win32.whl", hash = "sha256:535f274738d6ad5501b4450b0bf3cd3c0d1547e9773a7ca1cf9e855d8a1cf741"}, + {file = "yara_python-4.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:5de0bf8ea0d530e8af2b59c56c5506219f060b4b25b196ba88fd19753529246d"}, + {file = "yara_python-4.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aeadaa62aa523e71abcb438f6f07761b9d62177021bb0e919a180d5b1e8cc05f"}, + {file = "yara_python-4.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0b4cc4eb937c1fd3747682cae639179a6bc03a24c86dde861ca2ba1abafe8404"}, + {file = "yara_python-4.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c77dfe89038a1e0a134d44aacb05d48b268312ca3a58df1fc0cf212aaaa79ff"}, + {file = "yara_python-4.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:570d1f0f9893ec114a25ed9704e992ce58fb28c3399f6a3d81ea42d4e90c6a9d"}, + {file = "yara_python-4.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4650def8807d5b6736a1144ca2d880198deafec2313816a4fcc365c00f9b61b"}, + {file = "yara_python-4.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f557ce581e35ae23f19da6e80be1f84a1ac98b17b67b04cf46a9877d8d4fa870"}, + {file = "yara_python-4.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2d400917ebaf35663975ff001a6c13e432af68e641879194152212b8e87dd974"}, + {file = "yara_python-4.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c5de6ed584bf59005186628f88df718475ccb6818912b0b12a151a2e61f0c29c"}, + {file = "yara_python-4.5.0-cp311-cp311-win32.whl", hash = "sha256:17bee3e24258ef9d31cbc11342d22d513e005b7a551083adbb01d3ffc748c945"}, + {file = "yara_python-4.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:36acc235bf7aa61145daf364c97d3723e9c0e350cca6ae00bf717088a2c72f3b"}, + {file = "yara_python-4.5.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6918ddc68d89f4da1eb851d6a841ebc615cec31532f74698e4f51e58b44213e0"}, + {file = "yara_python-4.5.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9a9d666acc4d6d1ec59da4864ac4e25552169bd92520b050e5fcf92212d3ab1e"}, + {file = "yara_python-4.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a96d7b4a7e060c40b290d2264c17623f063a5604e6502b06cd145f2f0e6e82ed"}, + {file = "yara_python-4.5.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91f782bdea16441c87f0231f038cf6d151e36718154871f5c5fb274364d144e7"}, + {file = "yara_python-4.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:006f4af0cf30725425b6777016e6d6d7b2854955f0402b227f70d6fbdc594272"}, + {file = "yara_python-4.5.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7645a4d23d7749c390da92de105831762499eba22e39e956d0fddfda05d949eb"}, + {file = "yara_python-4.5.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:244fd95d0e4f4f1fbe85032f7e9b779e2cb4c6678787725482d2b43925ff2ed3"}, + {file = "yara_python-4.5.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c17980d60ff3f7cfabab2df28965efb8e0b38508a5c47a0ad6917016edc0328c"}, + {file = "yara_python-4.5.0-cp312-cp312-win32.whl", hash = "sha256:86549302cae8f9c5fb1394e2e9fd9dc802e3c488723935e50fdcb0d6b639ab51"}, + {file = "yara_python-4.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:36423ffd5e2e1f39562df6bd569be997c2fd06e0f30019dfadf339ff88278a4f"}, + {file = "yara_python-4.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:49f8e215c9ebd0b43a782d3cfbeee6f82e2a647482cff6c676e96da57014d878"}, + {file = "yara_python-4.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:262be4841add4d7e978db317e63f657291b4c9a64469bcdf43cdee8b3f28e0c0"}, + {file = "yara_python-4.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ee9e222daa982d31dc4be5fabf838726a3fb6a6425253c73f53aa0f0e2f457"}, + {file = "yara_python-4.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6d7d16fffc0fe92cd8d4ead9fbd58f1da7fcd9d39ff5c32924691db66257927"}, + {file = "yara_python-4.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6ebbe0c112da598828d8fad15356a20b739dd2ef0dd0d90f6ec0f00ce9aa7ae1"}, + {file = "yara_python-4.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a08162e9b4bdbae1e2e34ab83b6f145d334d650399aab9afb5341ce67a866a5c"}, + {file = "yara_python-4.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:65b0e4c168f0210d9b6be7b95bb7e2a97a545d52e9d3403370c3c5506b9d31f1"}, + {file = "yara_python-4.5.0-cp37-cp37m-win32.whl", hash = "sha256:3393eced9af44507193f7724b8f37ed5f0c5620fb402b886d6f07f578aab43af"}, + {file = "yara_python-4.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:de539783415e5b73e81d0a26fbe21cf2ade1b32fbd653be8a0f7430907337883"}, + {file = "yara_python-4.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:067610dfedfe361b748bbf9148183df11141748f2a83b4bdb873fde96a62e204"}, + {file = "yara_python-4.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8342783942dd8bdc46f1047cdb45ff68dcfe7aef0499b644deabd3d685a2d7e6"}, + {file = "yara_python-4.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f14db61a8e54c61cced58d070630033b68e276036053f402e76a1b7ebc5ad0f0"}, + {file = "yara_python-4.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:468743b991341440fa4fd6c1414b2f5948970d26330ac1ae811f10d559c57771"}, + {file = "yara_python-4.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cde3be15f16c3b24a3e7a08327deeec9225cecf060c930fef58d38ae4554b17e"}, + {file = "yara_python-4.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1b07363c9b44796fe991e29a5756a48ae195f3cbe4d72bb70b1932f5ccadd153"}, + {file = "yara_python-4.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8072d6f89d7352d09d1eeda6a8fa15582ff141495f24ceb448c7b7f7592d1820"}, + {file = "yara_python-4.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29735530650093e251abe11f76d78382fb8e87f24e7bc154e4fe28c624e7d4f7"}, + {file = "yara_python-4.5.0-cp38-cp38-win32.whl", hash = "sha256:016a7ce7ec60b1dcecec6a23557abd3b78b442a8ac7dd14c4e8047ac07227ea6"}, + {file = "yara_python-4.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:47fe5195687fff0f7ec435ce75b46a35b05b257c7550de5cb417bad9750bebde"}, + {file = "yara_python-4.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:aea5ba7084b48fb3d5edd6b01c7e45763a1f0a4dd83bc0c3c1975e61aeae86cf"}, + {file = "yara_python-4.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:16894888f599b4acdf57a4fc157108fb804823149f60e81a0afba0b7d2ebbf5f"}, + {file = "yara_python-4.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e80d2d8e5f7e9c25c8150f7281183abb2e53d81c0d33cecdf1459faeb042572"}, + {file = "yara_python-4.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:898fbdc6c5f5913935ce2586242dd94673d27f3a031dc0704598237c25ed4431"}, + {file = "yara_python-4.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e94d576dd98f7b957d34b8b03cabdf0372d11e9f65cd45bb823cbc3a086ec25"}, + {file = "yara_python-4.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d95e525074624c2618cb8146b4cc22455e786fbbe575b99bf191824a23f460db"}, + {file = "yara_python-4.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:185d542aefc154c28d59b7385f3d8d7baacbb74451f2f153a51c1216ae063d70"}, + {file = "yara_python-4.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e7571f164a2da121fbc3a0d4df68fec82d2ae39bb8ea48b5a77467a467741573"}, + {file = "yara_python-4.5.0-cp39-cp39-win32.whl", hash = "sha256:692ae9d9647026908d5202a9ec68da6c8b4e4fb161828a425bc847ad03e66341"}, + {file = "yara_python-4.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:b08ebeab39aab6fd80da875aa9fe0ec21ab8432f4656a0f4011a5069a9c3aab4"}, + {file = "yara_python-4.5.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:cf9758f5b22cd0d9e14cec363d5eda3af637d93728bf5287ee0887a2fce036b1"}, + {file = "yara_python-4.5.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b68c7367df3d10d55fbeda985c02425ef9b549805fa9893505e25d68ef039e8"}, + {file = "yara_python-4.5.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe47ea00cd442eeb0bfea9ffea3cec97074e0e88843358a0552063b978655736"}, + {file = "yara_python-4.5.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:344b679576d51fc6397eac3282e4ad27b1ab093cf9571a47e47b50debcd03dbf"}, + {file = "yara_python-4.5.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5c02545da623e58f5df8292a7d214b97667989904271d30b5e389b9ab1a81395"}, + {file = "yara_python-4.5.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e344f6953be0f60dc4fa94f629568e12ed9d2b981997e22bf32bd83083774c2f"}, + {file = "yara_python-4.5.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77da34bac1807d270df4840d28c01a7d879e0ce0a0c692a0b0bd8f2adf4f6d1c"}, + {file = "yara_python-4.5.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d262ddf7032f1a9efe9c7533315c37db86ad58c10b5888d704f50f0f82bdfb8"}, + {file = "yara_python-4.5.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d04c17b27e33f9541a47f12972fc1a5836d2dfa947f48ed3242c5c9c32fc47b"}, + {file = "yara_python-4.5.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:847c249bbf6847f6d056921315eeef2d9c2ac79fcf063384d9b752b51e087afd"}, + {file = "yara_python-4.5.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0361820a3a8ec522cbb259d6af664d5f7dd19b29e4bcce9c36e480832b4172fc"}, + {file = "yara_python-4.5.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00a7c3d593ef0d065d84c06ed365ce24735f553669de1e066851e8f6cdfc2051"}, + {file = "yara_python-4.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a45b201d634be0f37bcb5fcf898fc91c66032c3f87b3e7656953f111e475f409"}, + {file = "yara_python-4.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c1cbcfc262840ea1fb19bc961eaff51d764896bd411643f5695a46046cae99b"}, + {file = "yara_python-4.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:445d80c3a327345cae346cb12c86b01265127319a9cf3a1d93e301ee080fb2c7"}, + {file = "yara_python-4.5.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c966f098254d6883ea9b1bba9743a298658cc58f43904ea6564e31e3e0d699d8"}, + {file = "yara_python-4.5.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c901ce071141261a857ea779bcdf0c1e63e238d1b597a411dc2f816796a25c63"}, + {file = "yara_python-4.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26085645d894bdfa75e2e88ba57d8297ed89c415ae3c2224ef27095c13c0c050"}, + {file = "yara_python-4.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0778e2d41bde173dd5e4758bb2f6d58832f149ff10d333e8751ae3cc4b195b2"}, + {file = "yara_python-4.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:648072ba075b930d976b5f6ae8c4563e4e32a057a2a8bd5be0e82ac98b682c60"}, +] + +[[package]] +name = "yarl" +version = "1.9.4" +description = "Yet another URL library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, + {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, + {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, + {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, + {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, + {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, + {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, + {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, + {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, + {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, + {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, + {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, + {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, + {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, + {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, + {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, +] + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" + +[[package]] +name = "zipp" +version = "3.20.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, + {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, +] + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.8.*,<3.13" +content-hash = "1c4eb4ee656ee6092c9e63bcf01fc432d4c2238b8781978fe03f4857ef79e6aa" diff --git a/pyproject.toml b/pyproject.toml index b0471b7f..10994ff3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,128 @@ [build-system] -requires = ["setuptools", "wheel"] -build-backend = "setuptools.build_meta:__legacy__" \ No newline at end of file +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +name = "misp-modules" +version = "2.4.197" +description = "MISP modules are autonomous modules that can be used for expansion and other services in MISP" +authors = ["Alexandre Dulaunoy "] +license = "AGPL-3.0-only" +repository = "https://github.com/MISP/misp-modules" +documentation = "https://misp.github.io/misp-modules" +readme = "README.md" +classifiers=[ + 'License :: OSI Approved :: GNU Affero General Public License v3', + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Science/Research', + 'Programming Language :: Python :: 3', + 'Topic :: Security', +] +packages = [{include = "misp_modules"}] + +[tool.poetry.urls] +"Bug Tracker" = "https://github.com/MISP/misp-modules/issues" +"Source" = "https://github.com/MISP/misp-modules" + +[tool.poetry.scripts] +misp-modules = "misp_modules:main" + +[tool.poetry.dependencies] +## platform (pin this to your python version, for 'poetry export' to work) +python = ">=3.8.*,<3.13" +## core dependencies +psutil = "*" +pyparsing = "*" +redis = "*" +tornado = "*" +## module dependencies (if a dependency fails loading with '*', pin it here) +censys = "2.0.9" +socialscan = "<2.0.0" +yara-python = "4.5.0" +# required to support both python 3.8 and wheel builds on python 3.12 +numpy = [{version = "1.24.4", python = "3.8.*"}, {version = ">=1.26.4,<2.0.0", python = ">=3.9"}] +pandas = [{version = "1.5.3", python = "3.8.*"}, {version = ">=2.0.0", python = ">=3.9"}] +pandas_ods_reader = [{version = "0.1.4", python = "3.8.*"}, {version = ">=1.0.0", python = ">=3.9"}] +## module dependencies +apiosintds = "*" +assemblyline_client = "*" +backscatter = "*" +blockchain = "*" +clamd = "*" +crowdstrike-falconpy = "*" +dnsdb2 = "*" +domaintools_api = "*" +geoip2 = "*" +greynoise = "*" +jbxapi = "*" +maclookup = "*" +markdownify = "*" +matplotlib = "*" +mattermostdriver = "*" +mwdblib = "*" +ndjson = "*" +np = "*" +oauth2 = "*" +opencv-python = "*" +openpyxl = "*" +passivetotal = "*" +pdftotext = "*" +pycountry = "*" +pyeti-python3 = "*" +pyeupi = "*" +pyfaup = "*" +pygeoip = "*" +pyintel471 = "*" +pyipasnhistory = "*" +pymisp = { version = "*", extras = ["fileobjects", "openioc", "pdfexport", "email", "url"] } +pypdns = "*" +pypssl = "*" +pysafebrowsing = "*" +pytesseract = "*" +python-docx = "*" +python-pptx = "*" +pyzbar = "*" +requests = { version = "*", extras = ["security"] } +shodan = "*" +sigmatools = "*" +sigmf = "*" +slack-sdk = "*" +sparqlwrapper = "*" +stix2 = "*" +tau-clients = "*" +taxii2-client = "*" +urlarchiver = "*" +vt-graph-api = "*" +vt-py = "*" +vulners = "*" +vysion = "*" +wand = "*" +xlrd = "*" + +[tool.poetry.group.test] +optional = true + +[tool.poetry.group.test.dependencies] +codecov = "*" +flake8 = "*" +nose = "*" +pytest = "*" + +[tool.poetry.group.docs] +optional = true + +[tool.poetry.group.docs.dependencies] +mkdocs = "*" +mkdocs-material = "*" +markdown_include = "*" + +[tool.poetry.group.unstable] +optional = true + +[tool.poetry.group.unstable.dependencies] +odtreader = { git = "https://github.com/cartertemm/ODTReader.git" } +google-search-api = { git = "https://github.com/abenassi/Google-Search-API" } +trustar = { git = "https://github.com/SteveClement/trustar-python.git" } +pydnstrails = { git = "https://github.com/sebdraven/pydnstrails.git" } +pyonyphe = { git = "https://github.com/sebdraven/pyonyphe.git" } diff --git a/setup.py b/setup.py deleted file mode 100644 index ea551744..00000000 --- a/setup.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -from setuptools import setup, find_packages - -setup( - name='misp-modules', - version='1.0', - author='Alexandre Dulaunoy', - author_email='alexandre.dulaunoy@circl.lu', - maintainer='Alexandre Dulaunoy', - url='https://github.com/MISP/misp-modules', - description='MISP modules are autonomous modules that can be used for expansion and other services in MISP', - packages=find_packages(), - entry_points={'console_scripts': ['misp-modules = misp_modules:main']}, - scripts=['tools/update_misp_modules.sh'], - test_suite="tests", - classifiers=[ - 'License :: OSI Approved :: GNU Affero General Public License v3', - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Science/Research', - 'Programming Language :: Python :: 3', - 'Topic :: Security', - ], - install_requires=[ - 'tornado', - 'psutil', - 'redis>=3', - 'pyparsing==2.4.7' - ], -) diff --git a/tests/bodysourcecache.json b/tests/bodysourcecache.json index 327394aa..3bc6b8d7 100644 --- a/tests/bodysourcecache.json +++ b/tests/bodysourcecache.json @@ -1 +1 @@ -{"module": "sourcecache", "link": "http://cve.circl.lu/" } +{"module": "sourcecache", "link": "http://vulnerability.circl.lu/" } diff --git a/tests/test.py b/tests/test.py index 37abcc36..ceac94e7 100644 --- a/tests/test.py +++ b/tests/test.py @@ -14,6 +14,10 @@ from email.mime.application import MIMEApplication from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.header import Header +from pathlib import Path +import importlib.util +import sys + class TestModules(unittest.TestCase): @@ -27,12 +31,97 @@ class TestModules(unittest.TestCase): print(response.json()) response.connection.close() + def test_introspection_module_init(self): + """checks if all modules are offered through the misp-modules service""" + try: + response = requests.get(self.url + "modules") + modules_api = [module["name"] for module in response.json()] + issues_found = [] + root_path = Path(__file__).resolve().parent.parent + modules_path = root_path / 'misp_modules' / 'modules' + for d in os.listdir(modules_path): + if d.startswith('__'): + continue + mod_d_path = modules_path / d + module_files = [file[:-3] for file in os.listdir(mod_d_path) if file.endswith(".py") if file not in ['__init__.py', 'testimport.py']] + for module in module_files: + if module not in modules_api: + issues_found.append(f"Missing module {module} in {d}/__init__.py.") + + error_message = '\n- '.join(issues_found) + self.assertEqual(issues_found, [], f"Found issues: \n{error_message}") + finally: + response.connection.close() + + def test_introspection_module_structure(self): + moduleinfo_template = { + 'version': '1.0', + 'author': '', + 'module-type': [], + 'name': '', + 'description': '', + 'logo': '', + 'requirements': [], + 'features': '', + 'references': [], + 'input': '', + 'output': '' + } + root_path = Path(__file__).resolve().parent.parent + modules_path = root_path / 'misp_modules' / 'modules' + issues_found = [] + + for d in os.listdir(modules_path): + if d.startswith('__'): + continue + + d_module = importlib.import_module(f"misp_modules.modules.{d}") + for module_name in d_module.__all__: + try: + module_package_name = f"misp_modules.modules.{d}.{module_name}" + module = importlib.import_module(module_package_name) + moduleinfo = module.version() + for k in moduleinfo_template.keys(): + if k not in moduleinfo: + issues_found.append(f"Module {d}.{module_name}: Key {k} not in moduleinfo.") + # sys.path.remove(str(m.parent)) + except Exception as e: + issues_found.append(f"Error loading {module_name}: {e}") + continue + + sys.path.remove(str(root_path / 'misp_modules' / 'lib')) + error_message = '\n- '.join(issues_found) + self.assertEqual(issues_found, [], f"Found issues: \n{error_message}") + def test_cve(self): with open('tests/bodycve.json', 'r') as f: response = requests.post(self.url + "query", data=f.read()) + expected_response = { + 'results': [ + { + 'types': ['text'], + 'values': 'Stack-based buffer overflow in Microsoft Office XP SP3, Office 2003 SP3, Office 2007 SP2, Office 2010, Office 2004 and 2008 for Mac, Office for Mac 2011, and Open XML File Format Converter for Mac allows remote attackers to execute arbitrary code via crafted RTF data, aka "RTF Stack Buffer Overflow Vulnerability."' + } + ] + } + self.assertDictEqual(response.json(), expected_response) print(response.json()) response.connection.close() + def test_invalid_cve(self): + response = requests.post(self.url + "query", data='{"module": "cve", "vulnerability": "CVE-INVALID"}') + expected_response = { + 'results': [ + { + 'types': ['text'], + 'values': 'Non existing CVE' + } + ] + } + self.assertDictEqual(response.json(), expected_response) + print(response.json()) + response.connection.close() + def test_dns(self): with open('tests/body.json', 'r') as f: response = requests.post(self.url + "query", data=f.read()) @@ -54,8 +143,8 @@ class TestModules(unittest.TestCase): print("OpenIOC :: {}".format(response)) values = [x["values"][0] for x in response["results"]] - assert("mrxcls.sys" in values) - assert("mdmcpq3.PNF" in values) + assert ("mrxcls.sys" in values) + assert ("mdmcpq3.PNF" in values) @unittest.skip("Need Rewrite") def test_email_headers(self): @@ -162,7 +251,6 @@ class TestModules(unittest.TestCase): self.assertEqual(attch_data, b'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-') - @unittest.skip("Need Rewrite") def test_email_dont_unpack_compressed_doc_attachments(self): """Ensures that compressed @@ -322,7 +410,7 @@ class TestModules(unittest.TestCase): @unittest.skip("Need Rewrite") def test_email_body_encoding(self): - query = {"module":"email_import"} + query = {"module": "email_import"} query["config"] = {"unzip_attachments": None, "guess_zip_attachment_passwords": None, "extract_urls": None} @@ -340,10 +428,9 @@ class TestModules(unittest.TestCase): self.assertNotIn('error', response, response.get('error', "")) self.assertIn('results', response, "No server results found.") - @unittest.skip("Need Rewrite") def test_email_header_proper_encoding(self): - query = {"module":"email_import"} + query = {"module": "email_import"} query["config"] = {"unzip_attachments": None, "guess_zip_attachment_passwords": None, "extract_urls": None} @@ -408,7 +495,7 @@ class TestModules(unittest.TestCase): @unittest.skip("Need Rewrite") def test_email_header_malformed_encoding(self): - query = {"module":"email_import"} + query = {"module": "email_import"} query["config"] = {"unzip_attachments": None, "guess_zip_attachment_passwords": None, "extract_urls": None} @@ -476,7 +563,7 @@ class TestModules(unittest.TestCase): @unittest.skip("Need Rewrite") def test_email_header_CJK_encoding(self): - query = {"module":"email_import"} + query = {"module": "email_import"} query["config"] = {"unzip_attachments": None, "guess_zip_attachment_passwords": None, "extract_urls": None} @@ -504,7 +591,7 @@ class TestModules(unittest.TestCase): @unittest.skip("Need Rewrite") def test_email_malformed_header_CJK_encoding(self): - query = {"module":"email_import"} + query = {"module": "email_import"} query["config"] = {"unzip_attachments": None, "guess_zip_attachment_passwords": None, "extract_urls": None} @@ -535,7 +622,7 @@ class TestModules(unittest.TestCase): @unittest.skip("Need Rewrite") def test_email_malformed_header_emoji_encoding(self): - query = {"module":"email_import"} + query = {"module": "email_import"} query["config"] = {"unzip_attachments": None, "guess_zip_attachment_passwords": None, "extract_urls": None} @@ -576,8 +663,8 @@ class TestModules(unittest.TestCase): with open("tests/EICAR.com", "rb") as fp: eicar_mime = MIMEApplication(fp.read(), 'com') eicar_mime.add_header('Content-Disposition', - 'attachment', - filename="Emoji Test 👍 checking this") + 'attachment', + filename="Emoji Test 👍 checking this") message.attach(eicar_mime) query['data'] = decode_email(message) data = json.dumps(query) @@ -591,7 +678,6 @@ class TestModules(unittest.TestCase): attch_data = base64.b64decode(i["data"]) self.assertEqual(attch_data, b'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-') - @unittest.skip("Need Rewrite") def test_email_attachment_password_in_subject(self): query = {"module": "email_import"} diff --git a/tests/test_actions.py b/tests/test_actions.py new file mode 100644 index 00000000..56f16cb3 --- /dev/null +++ b/tests/test_actions.py @@ -0,0 +1,30 @@ +import os +import unittest +import requests + + +class TestActions(unittest.TestCase): + """Unittest module for action modules""" + def setUp(self): + self.headers = {'Content-Type': 'application/json'} + self.url = "http://127.0.0.1:6666/" + + def test_introspection(self): + """checks if all action modules are offered through the misp-modules service""" + try: + response = requests.get(self.url + "modules") + modules = [module["name"] for module in response.json()] + # list modules in the export_mod folder + export_mod_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'misp_modules', 'modules', "action_mod") + module_files = [file[:-3] for file in os.listdir(export_mod_path) if file.endswith(".py") if file not in ['__init__.py']] + missing = [] + for module in module_files: + if module not in modules: + missing.append(module) + self.assertEqual(missing, [], f"Missing modules in __init__: {missing}") + finally: + response.connection.close() + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_expansions.py b/tests/test_expansions.py index 96017249..e091b048 100644 --- a/tests/test_expansions.py +++ b/tests/test_expansions.py @@ -10,6 +10,7 @@ import os LiveCI = True + class TestExpansions(unittest.TestCase): def setUp(self): @@ -87,12 +88,28 @@ class TestExpansions(unittest.TestCase): return values[0] if isinstance(values, list) else values return data['results'][0]['values'] + def test_introspection(self): + """checks if all expansion modules are offered through the misp-modules service""" + try: + response = requests.get(self.url + "modules") + modules = [module["name"] for module in response.json()] + # list modules in the export_mod folder + export_mod_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'misp_modules', 'modules', "expansion") + module_files = [file[:-3] for file in os.listdir(export_mod_path) if file.endswith(".py") if file not in ['__init__.py']] + missing = [] + for module in module_files: + if module not in modules: + missing.append(module) + self.assertEqual(missing, [], f"Missing modules in __init__: {missing}") + finally: + response.connection.close() + def test_apiosintds(self): self.skipTest("apiosintds is probably broken") query = {'module': 'apiosintds', 'ip-dst': '10.10.10.10'} response = self.misp_modules_post(query) - + try: self.assertTrue(self.get_values(response).startswith('IoC 10.10.10.10')) except AssertionError: @@ -116,18 +133,6 @@ class TestExpansions(unittest.TestCase): response = self.misp_modules_post(query) self.assertEqual(self.get_errors(response), 'An API key for APIVoid is required.') - def test_bgpranking(self): - query = { - "module": "bgpranking", - "attribute": { - "type": "AS", - "value": "13335", - "uuid": "ea89a33b-4ab7-4515-9f02-922a0bee333d" - } - } - response = self.misp_modules_post(query) - self.assertEqual(self.get_first_object_type(response), 'asn') - def test_btc_steroids(self): if LiveCI: return True @@ -192,7 +197,7 @@ class TestExpansions(unittest.TestCase): self.assertIn(self.get_values(response), results) def test_cve(self): - query = {"module": "cve", "vulnerability": "CVE-2010-4444", "config": {"custom_API": "https://cve.circl.lu/api/cve/"}} + query = {"module": "cve", "vulnerability": "CVE-2010-4444", "config": {"custom_API": "https://vulnerability.circl.lu/api/cve/"}} response = self.misp_modules_post(query) self.assertTrue(self.get_values(response).startswith("Unspecified vulnerability in Oracle Sun Java System Access Manager")) @@ -235,10 +240,10 @@ class TestExpansions(unittest.TestCase): def test_censys(self): module_name = "censys_enrich" query = { - "attribute": {"type" : "ip-dst", "value": "8.8.8.8", "uuid": ""}, - "module": module_name, - "config": {} - } + "attribute": {"type": "ip-dst", "value": "8.8.8.8", "uuid": ""}, + "module": module_name, + "config": {} + } if module_name in self.configs: query['config'] = self.configs[module_name] response = self.misp_modules_post(query) @@ -340,7 +345,6 @@ class TestExpansions(unittest.TestCase): response = self.misp_modules_post(query) self.assertEqual(self.get_errors(response), 'IPQualityScore apikey is missing') - def test_macaddess_io(self): module_name = 'macaddress_io' query = {"module": module_name, "mac-address": "44:38:39:ff:ef:57"} @@ -548,6 +552,7 @@ class TestExpansions(unittest.TestCase): query = {"module": "stix2_pattern_syntax_validator", "stix2-pattern": "[ipv4-addr:value = '8.8.8.8']"} response = self.misp_modules_post(query) self.assertEqual(self.get_values(response), 'Syntax valid') + def test_threatcrowd(self): if LiveCI: return True @@ -589,6 +594,7 @@ class TestExpansions(unittest.TestCase): response = self.misp_modules_post(query) self.assertTrue(self.get_values(response), result) + @unittest.skip("Service doesn't work") def test_urlhaus(self): query_types = ('domain', 'ip-src', 'sha256', 'url') query_values = ('www.bestwpdesign.com', '79.118.195.239', @@ -768,7 +774,9 @@ class TestExpansions(unittest.TestCase): def test_yara_query(self): query = {"module": "yara_query", "md5": "b2a5abfeef9e36964281a31e17b57c97"} response = self.misp_modules_post(query) - self.assertEqual(self.get_values(response), 'import "hash"\r\nrule MD5 {\r\n\tcondition:\r\n\t\thash.md5(0, filesize) == "b2a5abfeef9e36964281a31e17b57c97"\r\n}') + expected_result = 'import "hash"\r\nrule MD5 {\r\n\tcondition:\r\n\t\thash.md5(0, filesize) == "b2a5abfeef9e36964281a31e17b57c97"\r\n}' + + self.assertEqual(self.get_values(response), expected_result) def test_yara_validator(self): query = {"module": "yara_syntax_validator", "yara": 'import "hash"\r\nrule MD5 {\r\n\tcondition:\r\n\t\thash.md5(0, filesize) == "b2a5abfeef9e36964281a31e17b57c97"\r\n}'} diff --git a/tests/test_exports.py b/tests/test_exports.py new file mode 100644 index 00000000..785123be --- /dev/null +++ b/tests/test_exports.py @@ -0,0 +1,86 @@ +import base64 +import csv +import io +import json +import os +import unittest +import requests +from urllib.parse import urljoin + + +class TestExports(unittest.TestCase): + """Unittest module for export modules""" + def setUp(self): + self.headers = {'Content-Type': 'application/json'} + self.url = "http://127.0.0.1:6666/" + input_event_path = "%s/test_files/misp_event.json" % os.path.dirname(os.path.realpath(__file__)) + with open(input_event_path, "r") as ifile: + self.event = json.load(ifile) + + def misp_modules_post(self, query): + return requests.post(urljoin(self.url, "query"), headers=self.headers, json=query) + + @staticmethod + def get_values(response): + data = response.json() + if 'data' in data: + return base64.b64decode(data['data']).decode("utf-8") + + def test_introspection(self): + """checks if all export modules are offered through the misp-modules service""" + try: + response = requests.get(self.url + "modules") + modules = [module["name"] for module in response.json()] + # list modules in the export_mod folder + export_mod_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'misp_modules', 'modules', "export_mod") + module_files = [file[:-3] for file in os.listdir(export_mod_path) if file.endswith(".py") if file not in ['__init__.py', 'testexport.py']] + missing = [] + for module in module_files: + if module not in modules: + missing.append(module) + self.assertEqual(missing, [], f"Missing modules in __init__: {missing}") + finally: + response.connection.close() + + def test_threat_connect_export(self): + """Test an event export""" + test_source = "Test Export" + query = { + "module": 'threat_connect_export', + "data": [self.event], + "config": { + "Default_Source": test_source + } + } + + try: + response = self.misp_modules_post(query) + data = base64.b64decode(response.json()["data"]).decode("utf-8") + csvfile = io.StringIO(data) + reader = csv.DictReader(csvfile) + + values = [field["Value"] for field in reader] + assert "google.com" in values + assert "127.0.0.1" in values + + # resetting file pointer to read through again and extract sources + csvfile.seek(0) + # use a set comprehension to deduplicate sources + sources = {field["Source"] for field in reader} + assert test_source in sources + finally: + response.connection.close() + + def test_yara_export(self): + query = { + "module": "yara_export", + "data": [self.event], + } + response = self.misp_modules_post(query) + expected_result = 'rule MISP_e625_MetadataExample\n{\n meta:\n my_identifier_1 = "Some string data"\n my_identifier_2 = 24\n my_identifier_3 = true\n\n strings:\n $my_text_string = "text here"\n $my_hex_string = { E2 34 A1 C8 23 FB }\n\n condition:\n $my_text_string or $my_hex_string\n}\n\n' + result = self.get_values(response) + self.assertEqual(result, expected_result) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_files/misp_event.json b/tests/test_files/misp_event.json index ce0db0ae..9269844b 100644 --- a/tests/test_files/misp_event.json +++ b/tests/test_files/misp_event.json @@ -69,6 +69,22 @@ "value": "google.com|127.0.0.1", "AttributeTag": [], "ShadowAttribute": [] + }, { + "id": "164192", + "type": "yara", + "category": "Artifacts dropped", + "to_ids": false, + "uuid": "59430251-e6a4-4900-b78b-060dc0a81112", + "event_id": "625", + "distribution": "5", + "timestamp": "1497563729", + "comment": "Test data", + "sharing_group_id": "0", + "deleted": false, + "disable_correlation": false, + "value": "rule MetadataExample\n{\n meta:\n my_identifier_1 = \"Some string data\"\n my_identifier_2 = 24\n my_identifier_3 = true\n\n strings:\n $my_text_string = \"text here\"\n $my_hex_string = { E2 34 A1 C8 23 FB }\n\n condition:\n $my_text_string or $my_hex_string\n}", + "AttributeTag": [], + "ShadowAttribute": [] }], "ShadowAttribute": [], "EventTag": [{ diff --git a/tests/test_imports.py b/tests/test_imports.py new file mode 100644 index 00000000..725e4e78 --- /dev/null +++ b/tests/test_imports.py @@ -0,0 +1,30 @@ +import os +import unittest +import requests + + +class TestImports(unittest.TestCase): + """Unittest module for import modules""" + def setUp(self): + self.headers = {'Content-Type': 'application/json'} + self.url = "http://127.0.0.1:6666/" + + def test_introspection(self): + """checks if all import modules are offered through the misp-modules service""" + try: + response = requests.get(self.url + "modules") + modules = [module["name"] for module in response.json()] + # list modules in the export_mod folder + export_mod_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'misp_modules', 'modules', "import_mod") + module_files = [file[:-3] for file in os.listdir(export_mod_path) if file.endswith(".py") if file not in ['__init__.py', 'testimport.py']] + missing = [] + for module in module_files: + if module not in modules: + missing.append(module) + self.assertEqual(missing, [], f"Missing modules in __init__: {missing}") + finally: + response.connection.close() + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_yara.py b/tests/test_yara.py new file mode 100644 index 00000000..4d0bf64f --- /dev/null +++ b/tests/test_yara.py @@ -0,0 +1,34 @@ + +import json +import os +import unittest +import sys +try: + import yara +except (OSError, ImportError): + sys.exit("yara is missing, use 'pip3 install -I -r REQUIREMENTS' from the root of this repository to install it.") + + +class TestYara(unittest.TestCase): + """Unittest module for yara related modules""" + def setUp(self): + self.headers = {'Content-Type': 'application/json'} + self.url = "http://127.0.0.1:6666/" + self.module = "threat_connect_export" + input_event_path = "%s/test_files/misp_event.json" % os.path.dirname(os.path.realpath(__file__)) + with open(input_event_path, "r") as ifile: + self.event = json.load(ifile) + + def test_install(self): + files = ['tests/yara_hash_module_test.yara', 'tests/yara_pe_module_test.yara'] + + for file_ in files: + try: + rule = yara.compile(file_) + self.assertIsInstance(rule, yara.Rules) + except Exception as e: + raise Exception("Error in file: {} with error: {}".format(file_, e)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/threatconnect_export_test.py b/tests/threatconnect_export_test.py deleted file mode 100644 index 92a3c9a2..00000000 --- a/tests/threatconnect_export_test.py +++ /dev/null @@ -1,60 +0,0 @@ -"""Test module for the ThreatConnect Export module""" -import base64 -import csv -import io -import json -import os -import unittest -import requests - - -class TestModules(unittest.TestCase): - """Unittest module for threat_connect_export.py""" - def setUp(self): - self.headers = {'Content-Type': 'application/json'} - self.url = "http://127.0.0.1:6666/" - self.module = "threat_connect_export" - input_event_path = "%s/test_files/misp_event.json" % os.path.dirname(os.path.realpath(__file__)) - with open(input_event_path, "r") as ifile: - self.event = json.load(ifile) - - def test_01_introspection(self): - """Taken from test.py""" - try: - response = requests.get(self.url + "modules") - modules = [module["name"] for module in response.json()] - assert self.module in modules - finally: - response.connection.close() - - def test_02_export(self): - """Test an event export""" - test_source = "Test Export" - query = { - "module": self.module, - "data": [self.event], - "config": { - "Default_Source": test_source - } - } - - try: - response = requests.post(self.url + "query", headers=self.headers, data=json.dumps(query)) - data = base64.b64decode(response.json()["data"]).decode("utf-8") - csvfile = io.StringIO(data) - reader = csv.DictReader(csvfile) - - values = [field["Value"] for field in reader] - assert "google.com" in values - assert "127.0.0.1" in values - - # resetting file pointer to read through again and extract sources - csvfile.seek(0) - # use a set comprehension to deduplicate sources - sources = {field["Source"] for field in reader} - assert test_source in sources - finally: - response.connection.close() - -if __name__ == "__main__": - unittest.main() diff --git a/tests/yara_test.py b/tests/yara_test.py deleted file mode 100644 index ea88f032..00000000 --- a/tests/yara_test.py +++ /dev/null @@ -1,22 +0,0 @@ -import sys -try: - import yara -except (OSError, ImportError): - sys.exit("yara is missing, use 'pip3 install -I -r REQUIREMENTS' from the root of this repository to install it.") - -# Usage: python3 yara_test.py [yara files] -# with any yara file(s) in order to test if yara library is correctly installed. -# (it is also validating yara syntax) -# -# If no argument is given, this script takes the 2 yara test rules in the same directory -# in order to test if both yara modules we need work properly. - -files = sys.argv[1:] if len(sys.argv) > 1 else ['yara_hash_module_test.yara', 'yara_pe_module_test.yara'] - -for file_ in files: - try: - yara.compile(file_) - status = "Valid syntax" - except Exception as e: - status = e - print("{}: {}".format(file_, status)) diff --git a/tools/update_misp_modules.sh b/tools/update_misp_modules.sh deleted file mode 100755 index 372d1466..00000000 --- a/tools/update_misp_modules.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x - -# Updates the MISP Modules while respecting the current permissions -# It aims to support the two following installation methods: -# * Everything is runinng on the same machine following the MISP installation guide. -# * The modules are installed using pipenv on a different machine from the one where MISP is running. - -if [ -d "/var/www/MISP" ] && [ -d "/usr/local/src/misp-modules" ] -then - echo "MISP is installed on the same machine, following the recommanded install script. Using MISP virtualenv." - PATH_TO_MISP="/var/www/MISP" - PATH_TO_MISP_MODULES="/usr/local/src/misp-modules" - - pushd ${PATH_TO_MISP_MODULES} - USER=`stat -c "%U" .` - sudo -H -u ${USER} git pull - sudo -H -u ${USER} ${PATH_TO_MISP}/venv/bin/pip install -U -r REQUIREMENTS - sudo -H -u ${USER} ${PATH_TO_MISP}/venv/bin/pip install -U -e . - - service misp-modules restart - - popd -else - if ! [ -x "$(command -v pipenv)" ]; then - echo 'Error: pipenv not available, unable to automatically update.' >&2 - exit 1 - fi - - echo "Standalone mode, use pipenv from the current directory." - git pull - pipenv install -fi - - diff --git a/website/README.md b/website/README.md index f79774bc..5b3e608f 100644 --- a/website/README.md +++ b/website/README.md @@ -19,6 +19,8 @@ git submodule init && git submodule update ## Initialize misp-objects submodul python3 app.py -i ## Initialize db ``` +Don't forget to install **misp-modules**... + ## Config Edit `config.py` @@ -35,8 +37,6 @@ Edit `config.py` - `ADMIN_PASSWORD`: Password for Admin user if `ADMIN_USER` is True - - Rename `config.cfg.sample` to `config.cfg` then edit it: - `ADMIN_USER`: If True, config page will not be accessible diff --git a/website/app/__init__.py b/website/app/__init__.py index 6cf0a3cf..4543376d 100644 --- a/website/app/__init__.py +++ b/website/app/__init__.py @@ -34,9 +34,12 @@ def create_app(): from .home import home_blueprint from .history.history import history_blueprint from .account.account import account_blueprint + from .external_tools.external_tools import external_tools_blueprint app.register_blueprint(home_blueprint, url_prefix="/") app.register_blueprint(history_blueprint, url_prefix="/") app.register_blueprint(account_blueprint, url_prefix="/") + app.register_blueprint(external_tools_blueprint, url_prefix="/") + csrf.exempt(home_blueprint) return app diff --git a/website/app/db_class/db.py b/website/app/db_class/db.py index 924b0fc6..c83660d7 100644 --- a/website/app/db_class/db.py +++ b/website/app/db_class/db.py @@ -38,7 +38,7 @@ class Session_db(db.Model): "id": self.id, "uuid": self.uuid, "modules": json.loads(self.modules_list), - "query_enter": self.query_enter, + "query_enter": json.loads(self.query_enter), "input_query": self.input_query, "config_module": json.loads(self.config_module), "result": json.loads(self.result), @@ -51,7 +51,7 @@ class Session_db(db.Model): json_dict = { "uuid": self.uuid, "modules": json.loads(self.modules_list), - "query": self.query_enter, + "query": json.loads(self.query_enter), "input": self.input_query, "query_date": self.query_date.strftime('%Y-%m-%d %H:%M') } @@ -91,6 +91,22 @@ class User(UserMixin, db.Model): "last_name": self.last_name, "email": self.email } + +class ExternalTools(db.Model): + id = db.Column(db.Integer, primary_key=True, autoincrement=True) + name = db.Column(db.String(64), index=True) + url = db.Column(db.String) + api_key = db.Column(db.String(60), index=True) + is_active = db.Column(db.Boolean) + + def to_json(self): + return { + "id": self.id, + "url": self.url, + "name": self.name, + "api_key": self.api_key, + "is_active": self.is_active + } class AnonymousUser(AnonymousUserMixin): def is_admin(self): diff --git a/website/app/external_tools/external_tools.py b/website/app/external_tools/external_tools.py new file mode 100644 index 00000000..843e91d6 --- /dev/null +++ b/website/app/external_tools/external_tools.py @@ -0,0 +1,74 @@ +import json +from flask import Blueprint, render_template, request, jsonify, redirect, session as sess +from ..utils.utils import admin_user_active +from . import external_tools_core as ToolModel +from .form import ExternalToolForm + +external_tools_blueprint = Blueprint( + 'external_tools', + __name__, + template_folder='templates', + static_folder='static' +) + + +@external_tools_blueprint.route("/external_tools", methods=["GET"]) +def external_tools(): + """View config page for external tools""" + sess["admin_user"] = admin_user_active() + return render_template("external_tools/external_tools_index.html") + +@external_tools_blueprint.route("/external_tools/list", methods=['GET']) +def analyzers_data(): + """List all tools""" + return [tool.to_json() for tool in ToolModel.get_tools()] + +@external_tools_blueprint.route("/add_external_tool", methods=['GET', 'POST']) +def add_external_tool(): + """Add a new tool""" + form = ExternalToolForm() + if form.validate_on_submit(): + if ToolModel.add_tool_core(ToolModel.form_to_dict(form)): + return redirect("/external_tools") + return render_template("external_tools/add_external_tool.html", form=form) + + +@external_tools_blueprint.route("/external_tools//delete_tool", methods=['GET', 'POST']) +def delete_tool(tid): + """Delete a tool""" + if ToolModel.get_tool(tid): + if ToolModel.delete_tool(tid): + return {"message": "Tool deleted", "toast_class": "success-subtle"}, 200 + return {"message": "Error tool deleted", 'toast_class': "danger-subtle"}, 400 + return {"message": "Tool not found", 'toast_class': "danger-subtle"}, 404 + + + +@external_tools_blueprint.route("/external_tools/change_status", methods=['GET', 'POST']) +def change_status(): + """Active or disabled a tool""" + if "tool_id" in request.args: + res = ToolModel.change_status_core(request.args.get("tool_id")) + if res: + return {'message': 'Tool status changed', 'toast_class': "success-subtle"}, 200 + return {'message': 'Something went wrong', 'toast_class': "danger-subtle"}, 400 + return {'message': 'Need to pass "tool_id"', 'toast_class': "warning-subtle"}, 400 + + +@external_tools_blueprint.route("/external_tools/change_config", methods=['GET', 'POST']) +def change_config(): + """Change configuration for a tool""" + if "tool_id" in request.json["result_dict"] and request.json["result_dict"]["tool_id"]: + if "tool_name" in request.json["result_dict"] and request.json["result_dict"]["tool_name"]: + if "tool_url" in request.json["result_dict"] and request.json["result_dict"]["tool_url"]: + if "tool_api_key" in request.json["result_dict"] and request.json["result_dict"]["tool_api_key"]: + res = ToolModel.change_config_core(request.json["result_dict"]) + if res: + return {'message': 'Config changed', 'toast_class': "success-subtle"}, 200 + return {'message': 'Something went wrong', 'toast_class': "danger-subtle"}, 400 + return {'message': 'Need to pass "tool_api_key"', 'toast_class': "warning-subtle"}, 400 + return {'message': 'Need to pass "tool_url"', 'toast_class': "warning-subtle"}, 400 + return {'message': 'Need to pass "tool_name"', 'toast_class': "warning-subtle"}, 400 + return {'message': 'Need to pass "tool_id"', 'toast_class': "warning-subtle"}, 400 + + diff --git a/website/app/external_tools/external_tools_core.py b/website/app/external_tools/external_tools_core.py new file mode 100644 index 00000000..a53c1b5b --- /dev/null +++ b/website/app/external_tools/external_tools_core.py @@ -0,0 +1,61 @@ +from .. import db +from ..db_class.db import * + + +def get_tool(tool_id): + """Return a tool by id""" + return ExternalTools.query.get(tool_id) + +def get_tools(): + """Return all External tools""" + return ExternalTools.query.all() + +def change_status_core(tool_id): + """Active or disabled a tool""" + an = get_tool(tool_id) + if an: + an.is_active = not an.is_active + db.session.commit() + return True + return False + +def change_config_core(request_json): + """Change config for a tool""" + tool = get_tool(request_json["tool_id"]) + if tool: + tool.name = request_json["tool_name"] + tool.url = request_json["tool_url"] + tool.api_key = request_json["tool_api_key"] + db.session.commit() + return True + return False + + +def add_tool_core(form_dict): + tool = ExternalTools( + name=form_dict["name"], + url = form_dict["url"], + api_key = form_dict["api_key"], + is_active=True + ) + db.session.add(tool) + db.session.commit() + return True + +def delete_tool(tool_id): + tool = get_tool(tool_id) + if tool: + db.session.delete(tool) + return True + return False + +def form_to_dict(form): + loc_dict = dict() + for field in form._fields: + if field == "files_upload": + loc_dict[field] = dict() + loc_dict[field]["data"] = form._fields[field].data + loc_dict[field]["name"] = form._fields[field].name + elif not field == "submit" and not field == "csrf_token": + loc_dict[field] = form._fields[field].data + return loc_dict diff --git a/website/app/external_tools/form.py b/website/app/external_tools/form.py new file mode 100644 index 00000000..4157817c --- /dev/null +++ b/website/app/external_tools/form.py @@ -0,0 +1,13 @@ +from flask_wtf import FlaskForm +from wtforms.fields import ( + StringField, + SubmitField, +) +from wtforms.validators import InputRequired, Length + + +class ExternalToolForm(FlaskForm): + name = StringField('Name', validators=[InputRequired(), Length(1, 64)]) + url = StringField('Url', validators=[InputRequired()]) + api_key = StringField('API key', validators=[InputRequired(), Length(1, 60)]) + submit = SubmitField('Create') \ No newline at end of file diff --git a/website/app/history/history_core.py b/website/app/history/history_core.py index baa2b1ef..200a96b1 100644 --- a/website/app/history/history_core.py +++ b/website/app/history/history_core.py @@ -146,8 +146,8 @@ def util_remove_node_session(node_uuid, parent, parent_path): child = parent["children"][i] if child["uuid"] == node_uuid: del parent_path["children"][i] - return - elif child["children"]: + return True + elif "children" in child and child["children"]: return util_remove_node_session(node_uuid, child, parent_path["children"][i]) def remove_node_session(node_uuid): @@ -160,7 +160,9 @@ def remove_node_session(node_uuid): loc = i break elif q_value["children"]: - return util_remove_node_session(node_uuid, q_value, sess[keys_list[i]]) + if util_remove_node_session(node_uuid, q_value, sess[keys_list[i]]): + loc = i + break if loc: del sess[keys_list[i]] diff --git a/website/app/home.py b/website/app/home.py index 6c4e669d..7b18a1bc 100644 --- a/website/app/home.py +++ b/website/app/home.py @@ -1,9 +1,12 @@ +import ast import json from flask import Blueprint, render_template, request, jsonify, session as sess from flask_login import current_user +import requests from . import session_class as SessionModel from . import home_core as HomeModel from .utils.utils import admin_user_active +from .external_tools import external_tools_core as ToolModel home_blueprint = Blueprint( 'home', @@ -13,18 +16,35 @@ home_blueprint = Blueprint( ) -@home_blueprint.route("/") +@home_blueprint.route("/", methods=["GET", "POST"]) def home(): + try: + del sess["query"] + except: + pass sess["admin_user"] = bool(admin_user_active()) if "query" in request.args: - return render_template("home.html", query=request.args.get("query")) + sess["query"] = ast.literal_eval(request.args.get("query")) + if "query" in request.form: + sess["query"] = json.loads(request.form.get("query")) return render_template("home.html") +@home_blueprint.route("/get_query", methods=['GET', 'POST']) +def get_query(): + """Get result from flowintel""" + if "query" in sess: + return {"query": sess.get("query")} + return {"message": "No query"} + @home_blueprint.route("/home/", methods=["GET", "POST"]) def home_query(sid): + try: + del sess["query"] + except: + pass sess["admin_user"] = admin_user_active() if "query" in request.args: - query = request.args.get("query") + sess["query"] = [request.args.get("query")] return render_template("home.html", query=query, sid=sid) return render_template("404.html") @@ -33,21 +53,28 @@ def query(sid): sess["admin_user"] = admin_user_active() session = HomeModel.get_session(sid) flag=False + modules_list = [] if session: flag = True - query_loc = session.query_enter + query_loc = json.loads(session.query_enter) + modules_list = json.loads(session.modules_list) else: for s in SessionModel.sessions: if s.uuid == sid: flag = True query_loc = s.query session=s + modules_list = session.modules_list + query_str = ", ".join(query_loc) + if len(query_str) > 40: + query_str = query_str[0:40] + "..." if flag: return render_template("query.html", query=query_loc, + query_str=query_str, sid=sid, input_query=session.input_query, - modules=json.loads(session.modules_list), + modules=modules_list, query_date=session.query_date.strftime('%Y-%m-%d %H:%M')) return render_template("404.html") @@ -60,18 +87,20 @@ def get_query_info(sid): flag=False if session: flag = True - query_loc = session.query_enter + query_loc = json.loads(session.query_enter) + modules_list = json.loads(session.modules_list) else: for s in SessionModel.sessions: if s.uuid == sid: flag = True query_loc = s.query + modules_list = s.modules_list session=s if flag: loc_dict = { "query": query_loc, "input_query": session.input_query, - "modules": json.loads(session.modules_list), + "modules": modules_list, "query_date": session.query_date.strftime('%Y-%m-%d %H:%M') } return loc_dict @@ -150,8 +179,10 @@ def download(sid): if sess: loc = json.loads(sess.result) module = request.args.get("module") - if module in loc: - return jsonify(loc[module]), 200, {'Content-Disposition': f'attachment; filename={sess.query_enter.replace(".", "_")}-{module}.json'} + query = request.args.get("query") + if query in loc: + if module in loc[query]: + return jsonify(loc[query][module]), 200, {'Content-Disposition': f'attachment; filename={query}-{module}.json'} return {"message": "Module not in result", "toast_class": "danger-subtle"}, 400 else: for s in SessionModel.sessions: @@ -159,7 +190,7 @@ def download(sid): module = request.args.get("module") if module in s.result: return jsonify(s.result[module]), 200, {'Content-Disposition': f'attachment; filename={s.query}-{module}.json'} - return {"message": "Module not in result", "toast_class": "danger-subtle"}, 400 + return {"message": "Module not in result ", "toast_class": "danger-subtle"}, 400 return {"message": "Session not found", 'toast_class': "danger-subtle"}, 404 return {"message": "Need to pass a module", "toast_class": "warning-subtle"}, 400 @@ -227,3 +258,20 @@ def change_status(): return {'message': 'Something went wrong', 'toast_class': "danger-subtle"}, 400 return {'message': 'Need to pass "module_id"', 'toast_class': "warning-subtle"}, 400 return {'message': 'Permission denied', 'toast_class': "danger-subtle"}, 403 + + +@home_blueprint.route("/submit_external_tool", methods=["GET", "POST"]) +def submit_external_tool(): + """Submit result to an external tool""" + sess["admin_user"] = admin_user_active() + flag = True + if sess.get("admin_user"): + if not current_user.is_authenticated: + flag = False + # if admin is active and user is logon or if admin is not active + if flag: + ext = ToolModel.get_tool(request.json["external_tool_id"]) + if HomeModel.submit_external_tool(request.json["results"], ext): + return {'message': f'Send to {ext.name} successfully', 'toast_class': "success-subtle"}, 200 + return {'message': 'Something went wrong', 'toast_class': "danger-subtle"}, 400 + return {'message': 'Permission denied', 'toast_class': "danger-subtle"}, 403 diff --git a/website/app/home_core.py b/website/app/home_core.py index 1221fe54..6b8cf6d0 100644 --- a/website/app/home_core.py +++ b/website/app/home_core.py @@ -1,4 +1,6 @@ import json + +import requests from .utils.utils import isUUID, query_get_module from . import db from .db_class.db import History, Module, Config, Module_Config, Session_db, History_Tree @@ -113,6 +115,13 @@ def change_status_core(module_id): db.session.commit() return True +def submit_external_tool(results, ext_tool): + headers = {'Content-Type': 'application/json', "X-API-KEY": ext_tool.api_key, "Origin": "misp-module"} + response = requests.post(ext_tool.url, json={"results":results}, headers=headers) + if response.status_code == 200: + return True + return False + ############## @@ -163,7 +172,7 @@ def create_new_session_tree(current_session, parent_id): loc_json = { "uuid": loc_session.uuid, "modules": json.loads(loc_session.modules_list), - "query": loc_session.query_enter, + "query": json.loads(loc_session.query_enter), "input": loc_session.input_query, "query_date": loc_session.query_date.strftime('%Y-%m-%d %H:%M'), "config": json.loads(loc_session.config_module), diff --git a/website/app/session_class.py b/website/app/session_class.py index 2e32cab2..10b07f25 100644 --- a/website/app/session_class.py +++ b/website/app/session_class.py @@ -64,9 +64,12 @@ class Session_class: def start(self): """Start all worker""" - for i in range(len(self.modules_list)): - #need the index and the url in each queue item. - self.jobs.put((i, self.modules_list[i])) + cp = 0 + for i in self.query: + for j in self.modules_list: + self.jobs.put((cp, i, j)) + cp += 1 + #need the index and the url in each queue item. for _ in range(self.thread_count): worker = Thread(target=self.process) worker.daemon = True @@ -111,44 +114,44 @@ class Session_class: modules = query_get_module() loc_query = {} + self.result[work[1]] = dict() # If Misp format for module in modules: - if module["name"] == work[1]: + if module["name"] == work[2]: if "format" in module["mispattributes"]: loc_query = { "type": self.input_query, - "value": self.query, + "value": work[1], "uuid": str(uuid.uuid4()) } break loc_config = {} - if work[1] in self.config_module: - loc_config = self.config_module[work[1]] + if work[2] in self.config_module: + loc_config = self.config_module[work[2]] if loc_query: - send_to = {"module": work[1], "attribute": loc_query, "config": loc_config} + send_to = {"module": work[2], "attribute": loc_query, "config": loc_config} else: - send_to = {"module": work[1], self.input_query: self.query, "config": loc_config} + send_to = {"module": work[2], self.input_query: work[1], "config": loc_config} res = query_post_query(send_to) ## Sort attr in object by ui-priority - if "results" in res: - if "Object" in res["results"]: - for obj in res["results"]["Object"]: - loc_obj = get_object(obj["name"]) - if loc_obj: - for attr in obj["Attribute"]: - attr["ui-priority"] = loc_obj["attributes"][attr["object_relation"]]["ui-priority"] - - # After adding 'ui-priority' - obj["Attribute"].sort(key=lambda x: x["ui-priority"], reverse=True) + if res: + if "results" in res: + if "Object" in res["results"]: + for obj in res["results"]["Object"]: + loc_obj = get_object(obj["name"]) + if loc_obj: + for attr in obj["Attribute"]: + attr["ui-priority"] = loc_obj["attributes"][attr["object_relation"]]["ui-priority"] + + # After adding 'ui-priority' + obj["Attribute"].sort(key=lambda x: x["ui-priority"], reverse=True) - - # print(res) - if "error" in res: + if res and "error" in res: self.nb_errors += 1 - self.result[work[1]] = res + self.result[work[1]][work[2]] = res self.jobs.task_done() return True @@ -161,7 +164,7 @@ class Session_class: s = Session_db( uuid=str(self.uuid), modules_list=json.dumps(self.modules_list), - query_enter=self.query, + query_enter=json.dumps(self.query), input_query=self.input_query, config_module=json.dumps(self.config_module), result=json.dumps(self.result), diff --git a/website/app/static/js/history/history_tree_query.js b/website/app/static/js/history/history_tree_query.js index 022a3b56..8140c0c5 100644 --- a/website/app/static/js/history/history_tree_query.js +++ b/website/app/static/js/history/history_tree_query.js @@ -6,7 +6,7 @@ export default { }, template: ` -
  • [[history.query]]
  • +
  • [[history.query.join(", ")]]
    • + +
      + + +
      - -
      + +

      Config

      [[module.name]]

      @@ -86,14 +96,37 @@ const progress = ref(0) - const current_query = ref() + const current_query = ref([]) const status_site = ref() const config_query = ref([]) + const cp_entries = ref(1) + const queries = ref() + + let own_config_bool = false + + + async function fetchQuery(){ + const res = await fetch('/get_query') + let loc = await res.json() + if("message" in loc){ + queries.value = false + }else{ + queries.value = loc["query"] + cp_entries.value = queries.value.length + } + } + fetchQuery() + async function actionQuery(){ - current_query.value = $("#process-query").val() + current_query.value = [] + for(let i=1;i<=cp_entries.value;i++){ + let loc_query_res = $("#process-query-"+i).val() + if(loc_query_res) + current_query.value.push(loc_query_res) + } if (!current_query.value) { status_site.value = '↖ You need to type something' window.scrollTo(0, 0); @@ -178,16 +211,6 @@ width: '50%' }) } - if (!$('.select2-expansion').hasClass("select2-hidden-accessible")) { - $('.select2-expansion').select2({ - theme: 'bootstrap-5' - }) - } - if (!$('.select2-hover').hasClass("select2-hidden-accessible")) { - $('.select2-hover').select2({ - theme: 'bootstrap-5' - }) - } $('#input_select').on('change.select2', async function (e) { attr_selected.value = $(this).select2('data').map(item => item.id)[0] @@ -199,7 +222,8 @@ if (!$('.select2-modules').hasClass("select2-hidden-accessible")) { $('.select2-modules').select2({ - theme: 'bootstrap-5' + theme: 'bootstrap-5', + closeOnSelect: false }) $('#modules_select').on('change.select2', async function (e) { let loc_list = $(this).select2('data').map(item => item.id) @@ -207,7 +231,10 @@ for(let el in loc_list){ for(let index in modules_list.value){ if(modules_list.value[index].name == loc_list[el]){ - if(modules_list.value[index].request_on_query){ + if (own_config_bool){ + config_query.value.push(modules_list.value[index]) + } + else if(modules_list.value[index].request_on_query){ config_query.value.push(modules_list.value[index]) } break @@ -215,7 +242,7 @@ } } }) - } + } }) $('#input_select').on('select2:open', function (e) { @@ -242,6 +269,43 @@ return loc } + function add_entry(){ + cp_entries.value += 1 + } + function delete_entry(){ + cp_entries.value -= 1 + } + + + function own_config(){ + own_config_bool = !own_config_bool + if(own_config_bool){ + let loc_list = $('#modules_select').val() + config_query.value = [] + for(let el in loc_list){ + for(let index in modules_list.value){ + if(modules_list.value[index].name == loc_list[el]){ + config_query.value.push(modules_list.value[index]) + break + } + } + } + }else{ + let loc_list = $('#modules_select').val() + config_query.value = [] + for(let el in loc_list){ + for(let index in modules_list.value){ + if(modules_list.value[index].name == loc_list[el]){ + if(modules_list.value[index].request_on_query){ + config_query.value.push(modules_list.value[index]) + } + break + } + } + } + } + } + return { message_list, @@ -251,10 +315,15 @@ attr_selected, status_site, config_query, + cp_entries, + queries, actionQuery, pairedList, checked_attr, - generateCoreFormatUI + add_entry, + delete_entry, + generateCoreFormatUI, + own_config } } }).mount('.container-fluid') diff --git a/website/app/templates/query.html b/website/app/templates/query.html index 2a6aad96..a9950fe9 100644 --- a/website/app/templates/query.html +++ b/website/app/templates/query.html @@ -8,20 +8,20 @@

      -

      {{query}}

      +

      {{query_str}}

      - New query + New query Query [[status_site]] +
      + + + +
      + @@ -71,7 +102,7 @@