├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── acce ├── MANIFEST.in ├── README.md ├── acce │ ├── __init__.py │ ├── acce.py │ └── acce.stoq └── setup.py ├── azure_blob ├── MANIFEST.in ├── README.md ├── azure_blob │ ├── __init__.py │ ├── azure_blob.py │ └── azure_blob.stoq ├── requirements.txt └── setup.py ├── b64decode ├── MANIFEST.in ├── README.md ├── b64decode │ ├── __init__.py │ ├── b64decode.py │ └── b64decode.stoq ├── setup.py └── tests │ ├── __init__.py │ └── test_b64decode.py ├── decompress ├── MANIFEST.in ├── README.md ├── decompress │ ├── __init__.py │ ├── decompress.py │ └── decompress.stoq └── setup.py ├── dirmon ├── MANIFEST.in ├── README.md ├── dirmon │ ├── __init__.py │ ├── dirmon.py │ └── dirmon.stoq ├── requirements.txt └── setup.py ├── entropy ├── MANIFEST.in ├── README.md ├── entropy │ ├── __init__.py │ ├── entropy.py │ └── entropy.stoq ├── setup.py └── tests │ ├── __init__.py │ └── test_entropy.py ├── es-search ├── MANIFEST.in ├── README.md ├── es-search │ ├── __init__.py │ ├── es-search.py │ └── es-search.stoq ├── requirements.txt └── setup.py ├── exif ├── MANIFEST.in ├── README.md ├── exif │ ├── __init__.py │ ├── exif.py │ └── exif.stoq ├── setup.py └── tests │ ├── __init__.py │ ├── data │ └── sample.pdf │ └── test_exif.py ├── falcon-sandbox ├── MANIFEST.in ├── README.md ├── falcon-sandbox │ ├── __init__.py │ ├── falcon-sandbox.py │ └── falcon-sandbox.stoq └── setup.py ├── filedir ├── MANIFEST.in ├── README.md ├── filedir │ ├── __init__.py │ ├── filedir.py │ └── filedir.stoq └── setup.py ├── gcs ├── MANIFEST.in ├── README.md ├── gcs │ ├── __init__.py │ ├── gcs.py │ └── gcs.stoq ├── requirements.txt └── setup.py ├── hash ├── MANIFEST.in ├── README.md ├── hash │ ├── __init__.py │ ├── hash.py │ └── hash.stoq ├── setup.py └── tests │ ├── __init__.py │ └── test_hash.py ├── hash_ssdeep ├── MANIFEST.in ├── README.md ├── hash_ssdeep │ ├── __init__.py │ ├── hash_ssdeep.py │ └── hash_ssdeep.stoq ├── requirements.txt ├── setup.py └── tests │ ├── __init__.py │ └── test_ssdeep.py ├── iocextract ├── MANIFEST.in ├── README.md ├── iocextract │ ├── __init__.py │ ├── iocextract.py │ ├── iocextract.stoq │ └── whitelist.txt ├── requirements.txt └── setup.py ├── javaclass ├── MANIFEST.in ├── README.md ├── javaclass │ ├── __init__.py │ ├── javaclass.py │ └── javaclass.stoq ├── requirements.txt ├── setup.py └── tests │ ├── __init__.py │ ├── data │ ├── TestJavaClass.class │ └── TestJavaClass.java │ └── test_javaclass.py ├── jinja ├── MANIFEST.in ├── README.md ├── jinja │ ├── __init__.py │ ├── jinja.py │ ├── jinja.stoq │ └── stoq.tpl ├── requirements.txt └── setup.py ├── kafka-queue ├── MANIFEST.in ├── README.md ├── kafka-queue │ ├── __init__.py │ ├── kafka-queue.py │ └── kafka-queue.stoq ├── requirements.txt └── setup.py ├── lief ├── MANIFEST.in ├── README.md ├── lief │ ├── __init__.py │ ├── lief.py │ └── lief.stoq ├── requirements.txt └── setup.py ├── mimetype ├── MANIFEST.in ├── README.md ├── mimetype │ ├── __init__.py │ ├── mimetype.py │ └── mimetype.stoq ├── requirements.txt ├── setup.py └── tests │ ├── __init__.py │ └── test_mimetype.py ├── mongodb ├── MANIFEST.in ├── README.md ├── mongodb │ ├── __init__.py │ ├── mongodb.py │ └── mongodb.stoq ├── requirements.txt └── setup.py ├── mraptor ├── MANIFEST.in ├── README.md ├── mraptor │ ├── __init__.py │ ├── mraptor.py │ └── mraptor.stoq ├── requirements.txt └── setup.py ├── ole ├── MANIFEST.in ├── README.md ├── ole │ ├── __init__.py │ ├── ole.py │ └── ole.stoq ├── requirements.txt └── setup.py ├── opswat ├── MANIFEST.in ├── README.md ├── opswat │ ├── __init__.py │ ├── opswat.py │ └── opswat.stoq ├── requirements.txt └── setup.py ├── pecarve ├── MANIFEST.in ├── README.md ├── pecarve │ ├── __init__.py │ ├── pecarve.py │ └── pecarve.stoq ├── requirements.txt └── setup.py ├── peinfo ├── MANIFEST.in ├── README.md ├── peinfo │ ├── __init__.py │ ├── peinfo.py │ └── peinfo.stoq ├── requirements.txt └── setup.py ├── pubsub ├── MANIFEST.in ├── README.md ├── pubsub │ ├── __init__.py │ ├── pubsub.py │ └── pubsub.stoq ├── requirements.txt └── setup.py ├── redis-queue ├── MANIFEST.in ├── README.md ├── redis-queue │ ├── __init__.py │ ├── redis-queue.py │ └── redis-queue.stoq ├── requirements.txt └── setup.py ├── rtf ├── MANIFEST.in ├── README.md ├── requirements.txt ├── rtf │ ├── __init__.py │ ├── rtf.py │ └── rtf.stoq └── setup.py ├── s3 ├── MANIFEST.in ├── README.md ├── requirements.txt ├── s3 │ ├── __init__.py │ ├── s3.py │ └── s3.stoq └── setup.py ├── sentinel ├── MANIFEST.in ├── README.md ├── requirements.txt ├── sentinel │ ├── __init__.py │ ├── sentinel.py │ └── sentinel.stoq └── setup.py ├── smtp ├── MANIFEST.in ├── README.md ├── requirements.txt ├── setup.py └── smtp │ ├── __init__.py │ ├── smtp.py │ └── smtp.stoq ├── stdout ├── MANIFEST.in ├── README.md ├── setup.py └── stdout │ ├── __init__.py │ ├── stdout.py │ └── stdout.stoq ├── swfcarve ├── MANIFEST.in ├── README.md ├── requirements.txt ├── setup.py └── swfcarve │ ├── __init__.py │ ├── swfcarve.py │ └── swfcarve.stoq ├── symhash ├── MANIFEST.in ├── README.md ├── requirements.txt ├── setup.py └── symhash │ ├── __init__.py │ ├── symhash.py │ └── symhash.stoq ├── tika ├── MANIFEST.in ├── README.md ├── setup.py └── tika │ ├── __init__.py │ ├── tika.py │ └── tika.stoq ├── tnef ├── MANIFEST.in ├── README.md ├── requirements.txt ├── setup.py └── tnef │ ├── __init__.py │ ├── tnef.py │ └── tnef.stoq ├── trid ├── MANIFEST.in ├── README.md ├── setup.py └── trid │ ├── __init__.py │ ├── trid.py │ └── trid.stoq ├── vtmis-filefeed ├── MANIFEST.in ├── README.md ├── setup.py └── vtmis-filefeed │ ├── __init__.py │ ├── vtmis-filefeed.py │ └── vtmis-filefeed.stoq ├── vtmis-search ├── MANIFEST.in ├── README.md ├── setup.py └── vtmis-search │ ├── __init__.py │ ├── vtmis-search.py │ └── vtmis-search.stoq ├── xdpcarve ├── MANIFEST.in ├── README.md ├── setup.py └── xdpcarve │ ├── __init__.py │ ├── xdpcarve.py │ └── xdpcarve.stoq ├── xordecode ├── MANIFEST.in ├── README.md ├── requirements.txt ├── setup.py ├── tests │ ├── __init__.py │ └── test_xordecode.py └── xordecode │ ├── __init__.py │ ├── xordecode.py │ └── xordecode.stoq ├── xorsearch ├── MANIFEST.in ├── README.md ├── setup.py ├── tests │ ├── __init__.py │ └── test_xorsearch.py └── xorsearch │ ├── __init__.py │ ├── terms.txt │ ├── xorsearch.py │ └── xorsearch.stoq ├── xyz ├── MANIFEST.in ├── README.md ├── setup.py └── xyz │ ├── __init__.py │ ├── xyz.py │ └── xyz.stoq └── yara ├── MANIFEST.in ├── README.md ├── requirements.txt ├── setup.py ├── tests ├── __init__.py ├── data │ ├── dispatch_rules.yar │ ├── invalid_rules.yar │ └── scan_rules.yar └── test_yara.py └── yarascan ├── __init__.py ├── rules ├── alienvault.yar ├── dispatcher.yar ├── fireeye.yar └── stoq.yar ├── yarascan.py └── yarascan.stoq /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | .vscode 4 | 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | env/ 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | .mypy_cache/ 30 | .python-version 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *,cover 51 | 52 | # Translations 53 | *.mo 54 | *.pot 55 | 56 | # Django stuff: 57 | *.log 58 | 59 | # Sphinx documentation 60 | docs/_build/ 61 | 62 | # PyBuilder 63 | target/ 64 | 65 | # jetbrains stuff 66 | .idea 67 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: linux 2 | dist: bionic 3 | language: python 4 | python: 5 | - 3.6 6 | - 3.7 7 | - 3.8 8 | - 3.9 9 | 10 | before_install: 11 | - sudo apt-get -yq install software-properties-common 12 | - sudo apt-add-repository -y multiverse 13 | - sudo apt-get -yq update 14 | - sudo apt-get -yq install automake build-essential libyaml-dev libmagic-dev cython autoconf libffi-dev libfuzzy-dev unzip libimage-exiftool-perl swig 15 | - pip install stoq-framework 16 | - wget -O /tmp/xorsearch.zip https://github.com/DidierStevens/FalsePositives/raw/master/XORSearch_V1_11_3.zip 17 | - unzip /tmp/xorsearch.zip -d /tmp 18 | - sudo gcc -o /usr/local/bin/xorsearch /tmp/XORSearch.c 19 | - sed -i "s@bin_path = xorsearch@bin_path = /usr/local/bin/xorsearch@" $(find . -name 'xorsearch.stoq') 20 | 21 | install: 22 | - pip install -r hash_ssdeep/requirements.txt 23 | - pip install -r javaclass/requirements.txt 24 | - pip install -r mimetype/requirements.txt 25 | - pip install -r xordecode/requirements.txt 26 | - pip install -r yara/requirements.txt 27 | 28 | script: 29 | - python b64decode/setup.py test 30 | - python entropy/setup.py test 31 | - python exif/setup.py test 32 | - python hash/setup.py test 33 | - python hash_ssdeep/setup.py test 34 | - python javaclass/setup.py test 35 | - python mimetype/setup.py test 36 | - python xordecode/setup.py test 37 | - python xorsearch/setup.py test 38 | - python yara/setup.py test 39 | -------------------------------------------------------------------------------- /acce/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft acce 2 | -------------------------------------------------------------------------------- /acce/acce/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /acce/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="acce", 5 | version="3.0.0", 6 | author="Cipher Tech Solutions (acce.support@ciphertechsolutions.com)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Scan payloads using ACCE (Automated Component and Configuration Extraction)", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /azure_blob/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft azure_blob -------------------------------------------------------------------------------- /azure_blob/README.md: -------------------------------------------------------------------------------- 1 | # Azure Blob Storage 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin saves results and archives payloads with [Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/blobs/#features). 4 | 5 | ## Plugin Classes 6 | 7 | - [Archiver](https://stoq-framework.readthedocs.io/en/latest/dev/archivers.html) 8 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 9 | 10 | ## Configuration 11 | 12 | All options below may be set by: 13 | 14 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 15 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 16 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 17 | 18 | ### Options 19 | 20 | - `conn_str` [str]: Azure Storage Connection string 21 | Instructions to find credentials [here](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-python#copy-your-credentials-from-the-azure-portal) 22 | 23 | #### Archiver 24 | 25 | - `archive_container` [str]: Blob container where payload will be archived 26 | 27 | - `use_sha` [True/False]: When archiving files, use the first five characters of the sha1 hash as the directory structure. 28 | > For example, if the sha1 hash of the payload is `da39a3ee5e6b4b0d3255bfef95601890afd80709`, the payload will be archived to `$archive_container/d/a/3/9/a/da39a3ee5e6b4b0d3255bfef95601890afd80709`. 29 | 30 | - `use_datetime` [True/False]: Use the currentt date (YYYY/MM/DD) as the directory structure 31 | 32 | #### Connector 33 | 34 | - `results_container` [str]: Blob container where response will be saved 35 | -------------------------------------------------------------------------------- /azure_blob/azure_blob/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /azure_blob/azure_blob/azure_blob.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = azure_blob 17 | Module = azure_blob 18 | 19 | [Documentation] 20 | Author = Kiran Pradhan (@kiranpradhan01) 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Save results and archive payloads with Azure Blob Storage 24 | 25 | [options] 26 | # Azure Storage Connection string 27 | # conn_str = 28 | 29 | # Blob container where payload will be archived 30 | # archive_container = 31 | 32 | # Blob container where response will be saved 33 | # results_container = 34 | 35 | # Use the first five characters of the sha1 hash as the directory structure 36 | # Note: This option will precede use_datetime if both are True 37 | # use_sha = True 38 | 39 | # Use the currentt date (YYYY/MM/DD) as the directory structure 40 | # Note: This option will be preceded by use_sha if both are True 41 | # use_datetime = False 42 | -------------------------------------------------------------------------------- /azure_blob/requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp~=3.7.4 2 | azure-storage-blob~=12.3.2 3 | -------------------------------------------------------------------------------- /azure_blob/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="azure_blob", 5 | version="3.0.0", 6 | author="Kiran Pradhan (@kiranpradhan01)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Save results and archive payloads with Azure Blob Storage", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) -------------------------------------------------------------------------------- /b64decode/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft b64decode 2 | -------------------------------------------------------------------------------- /b64decode/README.md: -------------------------------------------------------------------------------- 1 | # b64decode 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that decodes base64 encoded payloads 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | -------------------------------------------------------------------------------- /b64decode/b64decode/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2015 PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /b64decode/b64decode/b64decode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ 18 | Overview 19 | ======== 20 | 21 | Decode base64 encoded payloads 22 | 23 | """ 24 | 25 | import base64 26 | 27 | from stoq.plugins import WorkerPlugin 28 | from stoq import ExtractedPayload, Payload, Request, WorkerResponse 29 | 30 | 31 | class B64Decode(WorkerPlugin): 32 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 33 | decoded_content = base64.b64decode(payload.content) 34 | extracted = [ExtractedPayload(decoded_content)] 35 | return WorkerResponse(extracted=extracted) 36 | -------------------------------------------------------------------------------- /b64decode/b64decode/b64decode.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = b64decode 17 | Module = b64decode 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Decode base64 encoded payloads 24 | -------------------------------------------------------------------------------- /b64decode/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="b64decode", 5 | version="3.0.0", 6 | author="Marcus LaFerrera <@mlaferrera>", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Decode base64 encoded payloads", 10 | packages=find_packages(exclude=['tests']), 11 | include_package_data=True, 12 | test_suite='tests', 13 | tests_require=['asynctest>=0.13.0'], 14 | ) 15 | -------------------------------------------------------------------------------- /b64decode/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/b64decode/tests/__init__.py -------------------------------------------------------------------------------- /b64decode/tests/test_b64decode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import os 18 | import base64 19 | import asynctest 20 | 21 | from pathlib import Path 22 | 23 | from stoq import RequestMeta, Stoq, Payload 24 | from stoq.data_classes import WorkerResponse 25 | 26 | 27 | class TestCore(asynctest.TestCase): 28 | def setUp(self) -> None: 29 | self.plugin_name = 'b64decode' 30 | self.base_dir = Path(os.path.realpath(__file__)).parent 31 | self.data_dir = self.base_dir.joinpath('data') 32 | self.plugin_dir = self.base_dir.parent.joinpath(self.plugin_name) 33 | self.generic_data = b'This is a payload to decode' 34 | 35 | def tearDown(self) -> None: 36 | pass 37 | 38 | async def test_scan(self) -> None: 39 | s = Stoq(plugin_dir_list=[str(self.plugin_dir)]) 40 | plugin = s.load_plugin(self.plugin_name) 41 | payload = Payload(base64.b64encode(self.generic_data)) 42 | response = await plugin.scan(payload, RequestMeta()) 43 | self.assertIsInstance(response, WorkerResponse) 44 | self.assertEqual(1, len(response.extracted)) 45 | self.assertEqual(self.generic_data, response.extracted[0].content) 46 | -------------------------------------------------------------------------------- /decompress/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft decompress 2 | -------------------------------------------------------------------------------- /decompress/decompress/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /decompress/decompress/decompress.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = decompress 17 | Module = decompress 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.3 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Extract content from a multitude of archive formats 24 | 25 | [options] 26 | min_stoq_version = 3.0.0 27 | 28 | # Passwords to iterate over when decompressing a file 29 | # Default: - 30 | # passwords = -,infected,password 31 | 32 | # Maximum size of payloads to process (original compressed file and extracted files) 33 | # Default: 50MB 34 | # maximum_size = 50000000 35 | 36 | # How long (in seconds) to wait for decompression to finish 37 | # Default: 45 38 | # timeout = 45 39 | # 40 | # Always dispatch extracted files to these plugins 41 | # Default: Empty List 42 | # always_dispatch = yara, exif 43 | # 44 | # Always erchive extracted files 45 | # Default: True 46 | # archive_extracted = True 47 | -------------------------------------------------------------------------------- /decompress/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="decompress", 5 | version="3.0.3", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Extract content from a multitude of archive formats", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /dirmon/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft dirmon 2 | -------------------------------------------------------------------------------- /dirmon/README.md: -------------------------------------------------------------------------------- 1 | # Dirmon 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin monitors a directory for newly created files then provides the content of the file to `stoQ` for processing. 4 | 5 | ## Plugin Classes 6 | 7 | - [Provider](https://stoq-framework.readthedocs.io/en/latest/dev/providers.html) 8 | 9 | ## Configuration 10 | 11 | All options below may be set by: 12 | 13 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 14 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 15 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 16 | 17 | ### Options 18 | 19 | - `source_dir` [str]: Directory to monitor for new files 20 | 21 | > Paths may be relative to the module, or a full path. 22 | -------------------------------------------------------------------------------- /dirmon/dirmon/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /dirmon/dirmon/dirmon.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2018 PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = dirmon 17 | Module = dirmon 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Monitor a directory for newly created files for processing 24 | 25 | [options] 26 | min_stoq_version = 3.0 27 | # Source directory to monitor for newly created files 28 | # source_dir: 29 | -------------------------------------------------------------------------------- /dirmon/requirements.txt: -------------------------------------------------------------------------------- 1 | watchgod~=0.5 2 | -------------------------------------------------------------------------------- /dirmon/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="dirmon", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Monitor a directory for newly created files for processing", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /entropy/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft entropy 2 | -------------------------------------------------------------------------------- /entropy/README.md: -------------------------------------------------------------------------------- 1 | # Entropy 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that calculates the shannon entropy of a payload 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | -------------------------------------------------------------------------------- /entropy/entropy/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /entropy/entropy/entropy.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ 16 | Overview 17 | ======== 18 | 19 | Calculate shannon entropy of a payload 20 | 21 | """ 22 | 23 | import math 24 | from typing import Dict 25 | from collections import Counter 26 | 27 | from stoq.plugins import WorkerPlugin 28 | from stoq import Payload, Request, WorkerResponse 29 | 30 | 31 | class Hash(WorkerPlugin): 32 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 33 | entropy: float = 0.0 34 | results: Dict[str, float] = {} 35 | if payload.content: 36 | occurences = Counter(bytearray(payload.content)) 37 | for bc in occurences.values(): 38 | b = float(bc) / len(payload.content) 39 | entropy -= b * math.log(b, 2) 40 | results['entropy'] = entropy 41 | return WorkerResponse(results=results) 42 | -------------------------------------------------------------------------------- /entropy/entropy/entropy.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = entropy 17 | Module = entropy 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Calculate shannon entropy of a payload 24 | 25 | -------------------------------------------------------------------------------- /entropy/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="entropy", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Calculate shannon entropy of a payload", 10 | packages=find_packages(exclude=['tests']), 11 | include_package_data=True, 12 | test_suite='tests', 13 | tests_require=['asynctest>=0.13.0'], 14 | ) 15 | -------------------------------------------------------------------------------- /entropy/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/entropy/tests/__init__.py -------------------------------------------------------------------------------- /entropy/tests/test_entropy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import os 18 | import asynctest 19 | from pathlib import Path 20 | 21 | from stoq import RequestMeta, Stoq, Payload 22 | from stoq.data_classes import WorkerResponse 23 | 24 | 25 | class TestCore(asynctest.TestCase): 26 | def setUp(self) -> None: 27 | self.plugin_name = 'entropy' 28 | self.base_dir = Path(os.path.realpath(__file__)).parent 29 | self.data_dir = os.path.join(self.base_dir, 'data') 30 | self.plugin_dir = os.path.join(self.base_dir.parent, self.plugin_name) 31 | self.entropy_nil = b'a' * 256 32 | self.entropy_not_nil = b'abc' * 256 33 | 34 | def tearDown(self) -> None: 35 | pass 36 | 37 | async def test_scan_nil(self) -> None: 38 | s = Stoq(plugin_dir_list=[self.plugin_dir]) 39 | plugin = s.load_plugin(self.plugin_name) 40 | payload = Payload(self.entropy_nil) 41 | response = await plugin.scan(payload, RequestMeta()) 42 | self.assertIsInstance(response, WorkerResponse) 43 | self.assertEqual(0.0, response.results['entropy']) 44 | 45 | async def test_scan_notnil(self) -> None: 46 | s = Stoq(plugin_dir_list=[self.plugin_dir]) 47 | plugin = s.load_plugin(self.plugin_name) 48 | payload = Payload(self.entropy_not_nil) 49 | response = await plugin.scan(payload, RequestMeta()) 50 | self.assertIsInstance(response, WorkerResponse) 51 | self.assertEqual(1.584962500721156, response.results['entropy']) 52 | -------------------------------------------------------------------------------- /es-search/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft es-search 2 | -------------------------------------------------------------------------------- /es-search/README.md: -------------------------------------------------------------------------------- 1 | # ElasticSearch 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that saves results to [ElasticSearch](https://www.elastic.co/products/elasticsearch) 4 | 5 | > Note: For larger deployments, it is highly recommended that the [`filedir`](../filedir/) plugin and [Filebeat](https://www.elastic.co/products/beats/filebeat) be used instead of this plugin. 6 | 7 | ## Plugin Classes 8 | 9 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 10 | 11 | ## Configuration 12 | 13 | All options below may be set by: 14 | 15 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 16 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 17 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 18 | 19 | ### Options 20 | 21 | - `es_host` [str]: Comma separated list of ElasticSearch nodes 22 | 23 | - `es_options` [json]: ElasticSearch options as outlined in the the [documentation](http://elasticsearch-py.readthedocs.org/en/latest/api.html) 24 | 25 | > Example: `es_options = {"port": 443, "use_ssl": true, "verify_certs": true}` 26 | 27 | - `es_index` [str]: Index name to use for saving results 28 | 29 | - `es_timeout` [int]: Time to wait for ES operations to complete before timing out 30 | 31 | - `es_retry` [True/False]: Should the plugin try again if the operation failes? 32 | 33 | - `es_max_retries` [int]: Number of retries to attempt before a timeout occurrs 34 | 35 | - `index_by_month` [True/False]: Append `YYYY-MM` to index name 36 | -------------------------------------------------------------------------------- /es-search/es-search/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /es-search/es-search/es-search.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2018 PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = es-search 17 | Module = es-search 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Save results to ElasticSearch 24 | 25 | [options] 26 | # What is the hostname/ip and port of the ES server? 27 | # Note: Should be inline with Python Elasticsearch documentation at 28 | # http://elasticsearch-py.readthedocs.org/en/latest/api.html 29 | # 30 | # Examples: 31 | # 32 | # create connection that will automatically inspect the cluster to get 33 | # the list of active nodes. Start with nodes 'esnode1' and 'esnode2' 34 | # es_host = [esnode1, esnode2] 35 | # es_options = {"sniff_on_start": true, "sniff_on_connection_fail": true, "sniffer_timeout": 60} 36 | # 37 | # connect to a node using SSL on port 443 38 | # es_host = [localhost] 39 | # es_options = {"port": 443, "use_ssl": true, "verify_certs": true} 40 | # es_host = localhost 41 | # es_options = {"port": 9200} 42 | 43 | # Index name results should be inserted into 44 | # Default: stoq 45 | # es_index = stoq 46 | 47 | # How long should we wait for ES operations before it times out? 48 | # Default: 60 49 | # es_timeout = 60 50 | 51 | # Should we try again if an operation fails? 52 | # es_retry = True 53 | 54 | # How many time should we try an operation if a timeout occurs? 55 | # Default: 10 56 | # es_max_retries = 10 57 | 58 | # Should indexes be named by month (i.e., stoq-YYYY-MM) 59 | # Default: True 60 | # index_by_month = True 61 | -------------------------------------------------------------------------------- /es-search/requirements.txt: -------------------------------------------------------------------------------- 1 | elasticsearch~=7.0 2 | certifi 3 | -------------------------------------------------------------------------------- /es-search/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="es-search", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Save results to ElasticSearch", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /exif/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft exif 2 | -------------------------------------------------------------------------------- /exif/README.md: -------------------------------------------------------------------------------- 1 | # ExifTool 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that scans a payload using [ExifTool](https://www.sno.phy.queensu.ca/~phil/exiftool/) 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration 10 | 11 | All options below may be set by: 12 | 13 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 14 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 15 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 16 | 17 | ### Options 18 | 19 | - `bin` [str]: Path to xorsearch binary 20 | 21 | > Paths may be relative to the module, or a full path. 22 | 23 | ## Install Notes 24 | 25 | > Additional requirements may need to be installed for ExifTool to work properly. Please see the [ExifTool](https://www.sno.phy.queensu.ca/~phil/exiftool/) website for additional details. On debian based systems, minimum requirements are: `libimage-exiftool-perl` and the `exiftool` binary. 26 | -------------------------------------------------------------------------------- /exif/exif/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /exif/exif/exif.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ 16 | Overview 17 | ======== 18 | 19 | Processes a payload using ExifTool 20 | 21 | """ 22 | 23 | import json 24 | 25 | from typing import List 26 | from asyncio.subprocess import PIPE 27 | from asyncio import create_subprocess_exec 28 | 29 | from stoq.plugins import WorkerPlugin 30 | from stoq.helpers import StoqConfigParser 31 | from stoq import Error, Payload, Request, WorkerResponse 32 | 33 | 34 | class ExifToolPlugin(WorkerPlugin): 35 | def __init__(self, config: StoqConfigParser) -> None: 36 | super().__init__(config) 37 | self.bin = config.get('options', 'bin', fallback='exiftool') 38 | 39 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 40 | """ 41 | Scan a payload using Exiftool 42 | 43 | """ 44 | errors: List[Error] = [] 45 | try: 46 | p = await create_subprocess_exec( 47 | self.bin, '-j', '-n', '-', stdout=PIPE, stdin=PIPE, stderr=PIPE 48 | ) 49 | out, err = await p.communicate(input=payload.content) 50 | if err: 51 | self.log.debug(err) 52 | results = json.loads(out)[0] 53 | except Exception as err: 54 | errors.append( 55 | Error(err, plugin_name=self.plugin_name, payload_id=payload.payload_id) 56 | ) 57 | return WorkerResponse(results, errors=errors) 58 | -------------------------------------------------------------------------------- /exif/exif/exif.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = exif 17 | Module = exif 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.1.2 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Processes a payload using ExifTool 24 | 25 | [options] 26 | # Path to exiftool binary 27 | # bin = exiftool 28 | -------------------------------------------------------------------------------- /exif/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="exif", 5 | version="3.1.2", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Processes a payload using ExifTool", 10 | packages=find_packages(exclude=['tests']), 11 | include_package_data=True, 12 | test_suite='tests', 13 | tests_require=['asynctest>=0.13.0'], 14 | ) 15 | -------------------------------------------------------------------------------- /exif/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /exif/tests/data/sample.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/exif/tests/data/sample.pdf -------------------------------------------------------------------------------- /exif/tests/test_exif.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | import asynctest 17 | 18 | from pathlib import Path 19 | 20 | from stoq import Stoq, Payload, Request 21 | from stoq.data_classes import WorkerResponse 22 | 23 | 24 | class TestCore(asynctest.TestCase): 25 | def setUp(self) -> None: 26 | self.plugin_name = 'exif' 27 | self.base_dir = Path(os.path.realpath(__file__)).parent 28 | self.data_dir = os.path.join(self.base_dir, 'data') 29 | self.plugin_dir = os.path.join(self.base_dir.parent, self.plugin_name) 30 | 31 | def tearDown(self) -> None: 32 | pass 33 | 34 | async def test_scan(self) -> None: 35 | s = Stoq(plugin_dir_list=[self.plugin_dir]) 36 | plugin = s.load_plugin(self.plugin_name) 37 | with open(f'{self.data_dir}/sample.pdf', 'rb') as f: 38 | payload = Payload(f.read()) 39 | response = await plugin.scan(payload, Request()) 40 | self.assertIsInstance(response, WorkerResponse) 41 | self.assertIn('FileType', response.results) 42 | self.assertEqual('PDF', response.results['FileType']) 43 | self.assertEqual(6, response.results['PageCount']) 44 | -------------------------------------------------------------------------------- /falcon-sandbox/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft falcon-sandbox 2 | -------------------------------------------------------------------------------- /falcon-sandbox/README.md: -------------------------------------------------------------------------------- 1 | # CrowdStrike Falcon Sandbox 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that scans payloads using [Falcon Sandbox](https://www.crowdstrike.com/products/falcon-sandbox/) 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration 10 | 11 | All options below may be set by: 12 | 13 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 14 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 15 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 16 | 17 | ### Options 18 | 19 | - `sandbox_url` [str]: URL for Falcon Sandbox 20 | 21 | - `apikey` [str]: Falcon Sandbox API key 22 | 23 | - `useragent` [str]: User Agent to use for request 24 | 25 | - `wait_for_results` [`True`/`False`]: Wait for analysis to complete before returning results 26 | 27 | - `delay` [int]: Time in seconds to wait between checking for completed results 28 | 29 | - `max_attempts` [int]: Maximum amount of attempts to retrieve results 30 | 31 | - `environment_id` [int]: Analysis environment to use 32 | 33 | > Available environments ID: 34 | > 35 | > - 300: 'Linux (Ubuntu 16.04, 64 bit)', 36 | > - 200: 'Android Static Analysis’, 37 | > - 160: 'Windows 10 64 bit’, 38 | > - 110: 'Windows 7 64 bit’, 39 | > - 100: ‘Windows 7 32 bit’ 40 | -------------------------------------------------------------------------------- /falcon-sandbox/falcon-sandbox/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /falcon-sandbox/falcon-sandbox/falcon-sandbox.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2018 PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = falcon-sandbox 17 | Module = falcon-sandbox 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Scan payloads using Falcon Sandbox 24 | 25 | [options] 26 | sandbox_url = 27 | apikey = 28 | # User agent to use for request 29 | # Default: Falcon Sandbox 30 | useragent = Falcon Sandbox 31 | 32 | # Wait for results to complete 33 | # Default: True 34 | wait_for_results = True 35 | 36 | # Time in seconds to wait between checking for completed results 37 | # Default: 30 38 | delay = 30 39 | 40 | # Maximum amount of attempts to retrieve results 41 | # Default: 10 42 | max_attempts = 10 43 | 44 | # Available environments ID: 45 | # 300: 'Linux (Ubuntu 16.04, 64 bit)', 46 | # 200: 'Android Static Analysis’, 47 | # 160: 'Windows 10 64 bit’, 48 | # 110: 'Windows 7 64 bit’, 49 | # 100: ‘Windows 7 32 bit’ 50 | # Default: 160 51 | environment_id = 160 52 | -------------------------------------------------------------------------------- /falcon-sandbox/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="falcon-sandbox", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Scan payloads using Falcon Sandbox", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /filedir/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft filedir 2 | -------------------------------------------------------------------------------- /filedir/README.md: -------------------------------------------------------------------------------- 1 | # Filedir 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that processes a directory/file for processing, saves results, and handles archiving of payloads. 4 | 5 | ## Plugin Classes 6 | 7 | - [Archiver](https://stoq-framework.readthedocs.io/en/latest/dev/archivers.html) 8 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 9 | - [Provider](https://stoq-framework.readthedocs.io/en/latest/dev/providers.html) 10 | 11 | ## Configuration 12 | 13 | All options below may be set by: 14 | 15 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 16 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 17 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 18 | 19 | ### Options 20 | 21 | - `archive_dir` [str]: Directory to read/save archived files from/to 22 | 23 | - `use_sha` [`True`/`False`]: When archiving files, should archived files be saved in a directory structure based on the first five characters of the sha1 hash. 24 | 25 | > For example, if the sha1 hash of the payload is `da39a3ee5e6b4b0d3255bfef95601890afd80709`, the payload will be archived to `$archive_dir/d/a/3/9/a/da39a3ee5e6b4b0d3255bfef95601890afd80709`. 26 | 27 | - `results_dir` [str]: Directory where results will be saved to 28 | 29 | - `compactly` [`True`/`False`]: Save results compacted (without newlines or indents) 30 | 31 | - `date_mode` [`True`/`False`]: Save results/archive payloads to a directory structure using `date_format` 32 | 33 | - `date_format` [str]: If date_mode is True, use this datetime formatter in the path. Defaults to `%%Y/%%m/%%d` 34 | 35 | - `source_dir` [str]: Directory to ingest files from 36 | 37 | - `recursive` [`True`/`False`]: Scan `source_dir` recursviely 38 | 39 | > Paths may be relative to the module, or a full path. 40 | -------------------------------------------------------------------------------- /filedir/filedir/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /filedir/filedir/filedir.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = filedir 17 | Module = filedir 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.2 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Handle file and directory interactions 24 | 25 | [options] 26 | # Should directories be scanned recursively? 27 | # recursive = False 28 | 29 | # Default directory for ingesting content 30 | # source_dir = 31 | 32 | # Where should results be saved to? 33 | # results_dir = ./results 34 | 35 | # Save results/archive files to a directory structure using date_format 36 | # date_mode = False 37 | 38 | # If date_mode is True, use this datetime formatter in the path 39 | # date_format = %%Y/%%m/%%d 40 | 41 | # Save results compacted (without newlines or indents) 42 | # Default: True 43 | # compactly = True 44 | 45 | # Where should archived files be saved/read from? 46 | # archive_dir = ./archive 47 | 48 | # Should archived files be saved in a directory structure 49 | # based on the first 5 characters of the sha1 hash? 50 | # use_sha = True 51 | -------------------------------------------------------------------------------- /filedir/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="filedir", 5 | version="3.0.2", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Handle file and directory interactions ", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /gcs/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft gcs 2 | -------------------------------------------------------------------------------- /gcs/README.md: -------------------------------------------------------------------------------- 1 | # GCS 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugins that reads and writes data to Google Cloud Storage buckets. 4 | 5 | ## Plugin Classes 6 | 7 | - [Archiver](https://stoq-framework.readthedocs.io/en/latest/dev/archivers.html) 8 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 9 | 10 | ## Configuration 11 | 12 | All options below may be set by: 13 | 14 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 15 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 16 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 17 | 18 | ### Options 19 | 20 | - `project_id` [str]: Google Cloud project ID 21 | 22 | #### Archiver 23 | 24 | - `archive_bucket` [str]: GCS Bucket to read/save archived files from 25 | 26 | - `use_sha` [`True`/`False`]: When archiving files, should archived files be saved in a directory structure based on the first five characters of the sha1 hash. 27 | > For example, if the sha1 hash of the payload is `da39a3ee5e6b4b0d3255bfef95601890afd80709`, the payload will be archived to `gs://$archive_bucket/d/a/3/9/a/da39a3ee5e6b4b0d3255bfef95601890afd80709`. 28 | 29 | #### Connector 30 | 31 | - `connector_bucket` [str]: GCS Bucket where results will be saved to 32 | 33 | -------------------------------------------------------------------------------- /gcs/gcs/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /gcs/gcs/gcs.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2018-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = gcs 17 | Module = gcs 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Read and write data to Google Cloud Storage 24 | 25 | [options] 26 | # Google Cloud Project ID 27 | # project_id = 28 | 29 | # Bucket name to save archived content in GCS 30 | # archive_bucket = 31 | 32 | # Bucket name to save stoQ results to in GCS 33 | # connector_bucket = 34 | 35 | # Use the first 5 characters of the payloads SHA1 hash as the directory structure 36 | # Note: This option will precede use_datetime if both are True 37 | # use_sha = True 38 | 39 | # Use the curremt date (YYYY/MM/DD) as the directory structure 40 | # Note: This option will be preceded by use_sha if both are True 41 | # use_datetime = False 42 | 43 | # How many times should we retry uploading/downloading from GCS if there is a failure? 44 | # max_retries = 5 45 | # Should CloudKMS be used to encrypt and decrypt data 46 | # use_encryption = False 47 | # If `use_encryption` is set to True, the below settings *MUST* be defined 48 | # crypto_id = 49 | # keyring_id = 50 | # location_id = 51 | # 52 | # 53 | -------------------------------------------------------------------------------- /gcs/requirements.txt: -------------------------------------------------------------------------------- 1 | google-cloud-storage>=1.13.2,<1.17.0 2 | google-api-python-client~=1.7.7 3 | google-auth-httplib2~=0.0.3 4 | google-auth~=1.6.2 5 | -------------------------------------------------------------------------------- /gcs/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="gcs", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Read and write data to Google Cloud Storage", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /hash/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft hash 2 | -------------------------------------------------------------------------------- /hash/README.md: -------------------------------------------------------------------------------- 1 | # Hash 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that generates the md5, sha1, and sha256 hashes of a payload 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | -------------------------------------------------------------------------------- /hash/hash/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2015 PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /hash/hash/hash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ 18 | Overview 19 | ======== 20 | 21 | Hash a payload 22 | 23 | """ 24 | 25 | from hashlib import md5, sha1, sha256 26 | 27 | from stoq.plugins import WorkerPlugin 28 | from stoq import Payload, Request, WorkerResponse 29 | 30 | 31 | class Hash(WorkerPlugin): 32 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 33 | return WorkerResponse( 34 | results={ 35 | 'sha256': sha256(payload.content).hexdigest(), 36 | 'md5': md5(payload.content).hexdigest(), 37 | 'sha1': sha1(payload.content).hexdigest(), 38 | } 39 | ) 40 | -------------------------------------------------------------------------------- /hash/hash/hash.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = hash 17 | Module = hash 18 | 19 | [Documentation] 20 | Author = Wesley Shields, Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Hash content 24 | 25 | -------------------------------------------------------------------------------- /hash/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="hash", 5 | version="3.0.0", 6 | author="Wesley Shields , Marcus LaFerrera <@mlaferrera>", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Hash content", 10 | packages=find_packages(exclude=['tests']), 11 | include_package_data=True, 12 | test_suite='tests', 13 | tests_require=['asynctest>=0.13.0'], 14 | ) 15 | -------------------------------------------------------------------------------- /hash/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/hash/tests/__init__.py -------------------------------------------------------------------------------- /hash/tests/test_hash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import os 18 | import logging 19 | import asynctest 20 | 21 | from pathlib import Path 22 | 23 | from stoq import RequestMeta, Stoq, Payload 24 | from stoq.data_classes import WorkerResponse 25 | 26 | 27 | class TestCore(asynctest.TestCase): 28 | def setUp(self) -> None: 29 | self.plugin_name = 'hash' 30 | self.base_dir = Path(os.path.realpath(__file__)).parent 31 | self.data_dir = os.path.join(self.base_dir, 'data') 32 | self.plugin_dir = os.path.join(self.base_dir.parent, self.plugin_name) 33 | self.generic_data = b'This is a payload to hash' 34 | 35 | def tearDown(self) -> None: 36 | pass 37 | 38 | async def test_scan(self) -> None: 39 | s = Stoq(plugin_dir_list=[self.plugin_dir]) 40 | plugin = s.load_plugin(self.plugin_name) 41 | payload = Payload(self.generic_data) 42 | response = await plugin.scan(payload, RequestMeta()) 43 | self.assertIsInstance(response, WorkerResponse) 44 | self.assertEqual('cfe671457bc475ef2f51cf12b1457475', response.results['md5']) 45 | self.assertEqual( 46 | 'f610f70b1464d97f7897fefd6420ffc904df5e4f', response.results['sha1'] 47 | ) 48 | self.assertEqual( 49 | '2fa284e62b11fea1226b35cdd726a7a56090853ed135240665ceb3939f631af7', 50 | response.results['sha256'], 51 | ) 52 | -------------------------------------------------------------------------------- /hash_ssdeep/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft hash_ssdeep 2 | -------------------------------------------------------------------------------- /hash_ssdeep/README.md: -------------------------------------------------------------------------------- 1 | # SSDeep Hash 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that generates an ssdeep hash of a payload. 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | 13 | ## Install Notes 14 | 15 | > Depending on the system, some additional requirements may need to be installed for ssdeep to work properly. Please see the [ssdeep installation](https://python-ssdeep.readthedocs.io/en/latest/installation.html) instructions for additional details. On debian based systems, minimum requirements are: `build-essential`, `libffi-dev`, `python3`, `python3-dev`, `python3-pip`, `libfuzzy-dev` 16 | -------------------------------------------------------------------------------- /hash_ssdeep/hash_ssdeep/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /hash_ssdeep/hash_ssdeep/hash_ssdeep.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ 18 | Overview 19 | ======== 20 | 21 | Generate a ssdeep hash of payload 22 | 23 | """ 24 | 25 | import ssdeep 26 | 27 | from stoq.plugins import WorkerPlugin 28 | from stoq import Payload, Request, WorkerResponse 29 | 30 | 31 | class HashSsdeep(WorkerPlugin): 32 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 33 | return WorkerResponse(results={'ssdeep': ssdeep.hash(payload.content)}) 34 | -------------------------------------------------------------------------------- /hash_ssdeep/hash_ssdeep/hash_ssdeep.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = hash_ssdeep 17 | Module = hash_ssdeep 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Generate a ssdeep hash of payload 24 | -------------------------------------------------------------------------------- /hash_ssdeep/requirements.txt: -------------------------------------------------------------------------------- 1 | ssdeep~=3.3 -------------------------------------------------------------------------------- /hash_ssdeep/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='hash_ssdeep', 5 | version='3.0.0', 6 | author='Marcus LaFerrera (@mlaferrera)', 7 | url='https://github.com/PUNCH-Cyber/stoq-plugins-public', 8 | license='Apache License 2.0', 9 | description='Generate a ssdeep hash of payload', 10 | packages=find_packages(exclude=['tests']), 11 | include_package_data=True, 12 | test_suite='tests', 13 | tests_require=['asynctest>=0.13.0'], 14 | ) 15 | -------------------------------------------------------------------------------- /hash_ssdeep/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/hash_ssdeep/tests/__init__.py -------------------------------------------------------------------------------- /hash_ssdeep/tests/test_ssdeep.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import os 18 | import logging 19 | import asynctest 20 | 21 | from pathlib import Path 22 | 23 | from stoq import Request, Stoq, Payload 24 | from stoq.data_classes import WorkerResponse 25 | 26 | 27 | class TestCore(asynctest.TestCase): 28 | def setUp(self) -> None: 29 | self.plugin_name = 'hash_ssdeep' 30 | self.base_dir = Path(os.path.realpath(__file__)).parent 31 | self.data_dir = os.path.join(self.base_dir, 'data') 32 | self.plugin_dir = os.path.join(self.base_dir.parent, self.plugin_name) 33 | self.generic_data = b'This is a payload to hash' 34 | 35 | def tearDown(self) -> None: 36 | pass 37 | 38 | async def test_scan(self) -> None: 39 | s = Stoq(plugin_dir_list=[self.plugin_dir]) 40 | plugin = s.load_plugin(self.plugin_name) 41 | payload = Payload(self.generic_data) 42 | response = await plugin.scan(payload, Request()) 43 | self.assertIsInstance(response, WorkerResponse) 44 | self.assertEqual('3:hMCE7pr3Kn:huJ6', response.results['ssdeep']) 45 | -------------------------------------------------------------------------------- /iocextract/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft iocextract 2 | -------------------------------------------------------------------------------- /iocextract/iocextract/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /iocextract/iocextract/iocextract.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = iocextract 17 | Module = iocextract 18 | 19 | [Documentation] 20 | Author = Mike Geide, Marcus LaFerrera 21 | Version = 3.0.2 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Regex routines to extract and normalize IOC's from a payload 24 | 25 | [options] 26 | # Where is the IANA TLD file? located locally? 27 | # iana_tld_file = tlds-alpha-by-domain.txt 28 | 29 | # What is the URL for the IANA TLD file? 30 | # iana_url = https://data.iana.org/TLD/tlds-alpha-by-domain.txt 31 | 32 | # List of files that contain whitelisted IOC's, separated by a comma 33 | # whitelist_file = whitelist.txt 34 | -------------------------------------------------------------------------------- /iocextract/requirements.txt: -------------------------------------------------------------------------------- 1 | requests~=2.20.0 2 | -------------------------------------------------------------------------------- /iocextract/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="iocextract", 5 | version="3.0.1", 6 | author="Mike Geide, Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Regex routines to extract and normalize IOC's from a payload", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /javaclass/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft javaclass 2 | -------------------------------------------------------------------------------- /javaclass/README.md: -------------------------------------------------------------------------------- 1 | # Javaclass 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that decodes and extracts information from Java Class files. 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | 13 | ## Install Notes 14 | 15 | > M2Crypto may fail to install. If so, please review the [M2Crypto installation instructions](https://github.com/mcepl/M2Crypto/blob/master/INSTALL.rst) to ensure proper installation. On debian based systems, minimum requirements are: `build-essential`, `python3-dev`, `libssl-dev`, `swig (>2.0.4)` 16 | -------------------------------------------------------------------------------- /javaclass/javaclass/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /javaclass/javaclass/javaclass.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ 16 | Overview 17 | ======== 18 | 19 | Decodes and extracts information from Java Class files 20 | 21 | """ 22 | 23 | from typing import Dict 24 | from javatools import unpack_class, ClassUnpackException 25 | 26 | from stoq.plugins import WorkerPlugin 27 | from stoq.exceptions import StoqPluginException 28 | from stoq import Payload, Request, WorkerResponse 29 | 30 | 31 | class JavaClassPlugin(WorkerPlugin): 32 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 33 | """ 34 | Decodes and extracts information from Java Class files 35 | 36 | """ 37 | 38 | results: Dict = {} 39 | 40 | try: 41 | content = unpack_class(payload.content) 42 | except ClassUnpackException as err: 43 | raise StoqPluginException(f'Unable to parse payload: {err}') 44 | 45 | try: 46 | results = { 47 | 'provided': content.get_provides(), 48 | 'required': content.get_requires(), 49 | 'constants': [], 50 | } 51 | for obj, _, data in content.cpool.pretty_constants(): 52 | if len(data) <= 6: 53 | continue 54 | constants = {} 55 | constants['id'] = obj 56 | constants['data'] = data 57 | results['constants'].append(constants) 58 | except Exception as err: 59 | raise StoqPluginException(f'Unable to analyze Java Class {err}') 60 | 61 | return WorkerResponse(results) 62 | -------------------------------------------------------------------------------- /javaclass/javaclass/javaclass.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = javaclass 17 | Module = javaclass 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Decodes and extracts information from Java Class files 24 | -------------------------------------------------------------------------------- /javaclass/requirements.txt: -------------------------------------------------------------------------------- 1 | javatools~=1.4.0 2 | -------------------------------------------------------------------------------- /javaclass/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="javaclass", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Decodes and extracts information from Java Class files", 10 | packages=find_packages(exclude=['tests']), 11 | include_package_data=True, 12 | test_suite="tests", 13 | tests_require=['asynctest>=0.13.0'], 14 | ) 15 | -------------------------------------------------------------------------------- /javaclass/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/javaclass/tests/__init__.py -------------------------------------------------------------------------------- /javaclass/tests/data/TestJavaClass.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/javaclass/tests/data/TestJavaClass.class -------------------------------------------------------------------------------- /javaclass/tests/data/TestJavaClass.java: -------------------------------------------------------------------------------- 1 | public class TestJavaClass extends Object { 2 | private String test_string = null; 3 | protected static String test_string_two = null; 4 | protected static String test_string_three = null; 5 | public static final String TEST_NAME = "StoqJavaTest"; 6 | public TestJavaClass() { 7 | this(TEST_NAME); 8 | } 9 | public TestJavaClass(String test_string) { 10 | this.test_string = test_string; 11 | this.test_string_two = test_string; 12 | this.test_string_three = test_string_two; 13 | } 14 | public String getTest() { 15 | return test_string; 16 | } 17 | public static String getTestTwo() { 18 | return test_string_two; 19 | } 20 | public static String getTestThree() { 21 | return test_string_three; 22 | } 23 | } -------------------------------------------------------------------------------- /jinja/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft jinja 2 | -------------------------------------------------------------------------------- /jinja/README.md: -------------------------------------------------------------------------------- 1 | # Jinja 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin decorates results using a template. 4 | 5 | ## Plugin Classes 6 | 7 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 8 | - [Decorator](https://stoq-framework.readthedocs.io/en/latest/dev/decorators.html) 9 | 10 | ## Configuration 11 | 12 | All options below may be set by: 13 | 14 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 15 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 16 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 17 | 18 | ### Options 19 | 20 | - `template` [str]: Jinja2 template file to use for results 21 | 22 | ## Usage 23 | 24 | Scan a payload and display results using default template 25 | 26 | $ stoq scan /tmp/badfile.exe -s hash -D jinja -C jinja 27 | 28 | stoQ Scan Results 29 | ----------------- 30 | 31 | ScanID: 0d98a884-2c47-409f-bbee-cd45fe27d493 32 | Date: XXXX 33 | Request Metadata: 34 | - Archive Payload: True 35 | Errors: 36 | 37 | Payloads: 38 | 39 | --------------------------------------------------- 40 | Payload ID: f2a0d66e-867a-4220-aada-83e58ceff0e9 41 | Size: 507904 42 | Extracted From: None 43 | Extracted By: None 44 | Metadata: 45 | - Archive Payload: 46 | - Dispatch To: 47 | - filename: b'badfile.exe' 48 | Archivers: 49 | Worker Results: 50 | hash: 51 | - {'sha256': '47c6e9b02324ea6c54dd95ad3fdf4b48b18775053b105e241a371a3731488c0', 'md5': '16d9f6e5491d99beb46d7ab3500c1799', 'sha1': '9e6414bf2802c98fbd13172817db80389c5eeb6a'} 52 | -------------------------------------------------------------------------------- /jinja/jinja/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /jinja/jinja/jinja.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = jinja 17 | Module = jinja 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Decorate results using a template 24 | 25 | [options] 26 | # template = stoq.tpl 27 | -------------------------------------------------------------------------------- /jinja/jinja/stoq.tpl: -------------------------------------------------------------------------------- 1 | stoQ Scan Results 2 | ----------------- 3 | 4 | ScanID: {{ response['scan_id'] }} 5 | Date: {{ response['time'] }} 6 | Request Metadata: 7 | - Archive Payload: {{ response['request_meta']['archive_payloads'] }} 8 | {% for k, v in response['request_meta']['extra_data'] %} 9 | - {{ k }}: {{ v }} 10 | Total Payloads: {{ response['results']|length }} 11 | {% endfor %} 12 | Errors: 13 | {% for error in response['errors'] %} 14 | - {{ error }} 15 | {% endfor %} 16 | 17 | Payloads: 18 | {% for payload in response['results'] %} 19 | 20 | -------------------------------------------------- 21 | Payload ID: {{ payload['payload_id'] }} 22 | Size: {{ payload['size'] }} 23 | Extracted From: {{ payload['extracted_from'] }} 24 | Extracted By: {{ payload['extracted_by'] }} 25 | Metadata: 26 | - Archive Payload: {{ payload['payload_meta']['archive_payloads'] }} 27 | - Dispatch To: {{ payload['payload_meta']['dispatch_to']['archive_payloads'] }} 28 | {% for k, v in payload['payload_meta']['extra_data'].items() %} 29 | - {{ k }}: {{ v|safe }} 30 | {% endfor %} 31 | Archivers: 32 | {% for archiver in payload['archivers'] %} 33 | - {{ archiver }} 34 | {% endfor %} 35 | Worker Results: 36 | {% for worker in payload['workers'] %} 37 | {% for k, v in worker.items() %} 38 | {{ k }}: 39 | - {{ v|safe }} 40 | {% endfor %} 41 | {% endfor %} 42 | {% endfor %} -------------------------------------------------------------------------------- /jinja/requirements.txt: -------------------------------------------------------------------------------- 1 | Jinja2~=2.10 -------------------------------------------------------------------------------- /jinja/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="jinja", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Decorate results using a template", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /kafka-queue/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft kafka-queue 2 | -------------------------------------------------------------------------------- /kafka-queue/README.md: -------------------------------------------------------------------------------- 1 | # Kafka Queue 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that publishes and consumes messages from a Kafka Server 4 | 5 | ## Plugin Classes 6 | 7 | - [Archiver](https://stoq-framework.readthedocs.io/en/latest/dev/archivers.html) 8 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 9 | - [Provider](https://stoq-framework.readthedocs.io/en/latest/dev/providers.html) 10 | 11 | ## Configuration 12 | 13 | All options below may be set by: 14 | 15 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 16 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 17 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 18 | 19 | ### Options 20 | 21 | - `servers` [str]: Comma separated list of Kafka servers 22 | 23 | - `group` [str]: Group to consume/publish messages from/to 24 | 25 | - `topic` [str]: Kafka topic to bind to 26 | 27 | - `retries` [int]: Retry attempts if publishing a message fails 28 | 29 | - `heartbeat_interval_ms` [int]: The expected time in milliseconds between heartbeats to the consumer coordinator 30 | 31 | - `session_timeout_ms` [int]: The timeout used to detect failures 32 | 33 | - `publish_archive` [`True`/`False`]: When used as a Connector plugin, should the ArchiveResponses be saved, or StoqResponse? Useful for sending archived payload metadata to topic. 34 | 35 | ## Usage 36 | 37 | ### Kafka Queuing Example 38 | 39 | Start `stoq` using `kafka-queue` as the provider plugin, `filedir` as the source archiver, then scan the payload with the `hash`, and send results to `stdout` connector: 40 | 41 | $ stoq run -P kafka-queue -S filedir -a hash -C stdout 42 | 43 | In another terminal, load files from `/tmp/test-files` using the `filedir` provider plugin, then archive the payloads with `filedir` archive plugin, and send a message to the `kafka-queue` queue for processing: 44 | 45 | $ stoq run -P filedir -A filedir -C kafka-queue --plugin-opts filedir:source_dir=/tmp/test-files 46 | -------------------------------------------------------------------------------- /kafka-queue/kafka-queue/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /kafka-queue/kafka-queue/kafka-queue.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = kafka-queue 17 | Module = kafka-queue 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.1 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Publish and Consume messages from a Kafka Server 24 | 25 | [options] 26 | # Comma separated list of Kafka servers 27 | # servers = 127.0.0.1:9092 28 | 29 | # Group to consume/publish messages from/to 30 | # group = stoq 31 | 32 | # Kafka topic name 33 | # topic = stoq 34 | 35 | # Retry attempts if publishing a message fails 36 | # retries = 5 37 | 38 | # The expected time in milliseconds between heartbeats to the consumer coordinator 39 | # See https://kafka-python.readthedocs.io/en/master/apidoc/KafkaConsumer.html 40 | # heartbeat_interval_ms = 5000 41 | 42 | # The timeout used to detect failures 43 | # See https://kafka-python.readthedocs.io/en/master/apidoc/KafkaConsumer.html 44 | # session_timeout_ms = 15000 45 | 46 | # When used as a Connector plugin, should the ArchiveResponses be saved, or StoqResponse? 47 | # Useful for sending archived payload metadata to topic. 48 | # Default: True 49 | # publish_archive = True 50 | -------------------------------------------------------------------------------- /kafka-queue/requirements.txt: -------------------------------------------------------------------------------- 1 | aiokafka~=0.5.2 2 | -------------------------------------------------------------------------------- /kafka-queue/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="kafka-queue", 5 | version="3.0.1", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Publish and Consume messages from a Kafka Server", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /lief/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft lief 2 | -------------------------------------------------------------------------------- /lief/README.md: -------------------------------------------------------------------------------- 1 | # lief 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that parses and abstracts PE, ELF and MachO executable files using [LIEF](https://lief.quarkslab.com/doc/latest/index.html) and produces metadata about the payload. 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration 10 | 11 | All options below may be set by: 12 | 13 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 14 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 15 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 16 | 17 | ### Options 18 | 19 | - `abstract` [`True`/`False`]: Defines if the plugin outputs the abstracted version 20 | -------------------------------------------------------------------------------- /lief/lief/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /lief/lief/lief.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ 16 | Overview 17 | ======== 18 | 19 | Parse and abstract PE, ELF and MachO files using LIEF 20 | 21 | """ 22 | 23 | import json 24 | import lief 25 | from typing import Dict, Optional 26 | 27 | from stoq.helpers import StoqConfigParser 28 | from stoq.plugins import WorkerPlugin 29 | from stoq.exceptions import StoqPluginException 30 | from stoq import Payload, Request, WorkerResponse 31 | 32 | 33 | class LiefPlugin(WorkerPlugin): 34 | def __init__(self, config: StoqConfigParser) -> None: 35 | super().__init__(config) 36 | 37 | self.abstract = config.getboolean('options', 'abstract', fallback=True) 38 | 39 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 40 | """ 41 | Scan a payload using LIEF 42 | 43 | """ 44 | filename = payload.results.payload_meta.extra_data.get( 45 | 'filename', payload.results.payload_id 46 | ) 47 | 48 | try: 49 | binary = lief.parse(raw=payload.content, name=filename) 50 | except lief.exception as err: 51 | raise StoqPluginException(f'Unable to parse payload: {err}') 52 | 53 | if binary is None: 54 | raise StoqPluginException('The file type isn\'t supported by LIEF') 55 | 56 | if self.abstract == True: 57 | results = lief.to_json_from_abstract(binary.abstract) 58 | else: 59 | results = lief.to_json(binary) 60 | 61 | return WorkerResponse(json.loads(results)) 62 | -------------------------------------------------------------------------------- /lief/lief/lief.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = lief 17 | Module = lief 18 | 19 | [Documentation] 20 | Author = Duarte Silva 21 | Version = 3.0.1 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Parse and abstract PE, ELF and MachO files using LIEF 24 | 25 | [options] 26 | # abstract = True 27 | -------------------------------------------------------------------------------- /lief/requirements.txt: -------------------------------------------------------------------------------- 1 | lief~=0.10.0 2 | -------------------------------------------------------------------------------- /lief/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="lief", 5 | version="3.0.1", 6 | author="Duarte Silva (@serializingme)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Parse and abstract PE, ELF and MachO files using LIEF", 10 | packages=find_packages(), 11 | package_data={'lief': ['lief.stoq']}, 12 | ) 13 | -------------------------------------------------------------------------------- /mimetype/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft mimetype 2 | -------------------------------------------------------------------------------- /mimetype/README.md: -------------------------------------------------------------------------------- 1 | # Mimetype 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that determines the mimetype of a payload. 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | -------------------------------------------------------------------------------- /mimetype/mimetype/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /mimetype/mimetype/mimetype.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ 18 | Overview 19 | ======== 20 | 21 | Determine mimetype of a payload 22 | 23 | """ 24 | 25 | import magic 26 | 27 | from stoq.plugins import WorkerPlugin 28 | from stoq import Payload, Request, WorkerResponse 29 | 30 | # This is silly. python-magic is the preferred library as it is maintained. 31 | # But, sometimes filemagic is used by other libraries. Let's determine which 32 | # one is installed so we can call it properly. 33 | if hasattr(magic.Magic, 'from_buffer'): 34 | USE_PYTHON_MAGIC = True 35 | else: 36 | USE_PYTHON_MAGIC = False 37 | 38 | 39 | class MimeType(WorkerPlugin): 40 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 41 | if USE_PYTHON_MAGIC: 42 | magic_scan = magic.Magic(mime=True) 43 | magic_result = magic_scan.from_buffer(payload.content[0:1000]) 44 | else: 45 | with magic.Magic(flags=magic.MAGIC_MIME_TYPE) as m: 46 | magic_result = m.id_buffer(payload.content[0:1000]) 47 | if hasattr(magic_result, 'decode'): 48 | magic_result = magic_result.decode('utf-8') 49 | return WorkerResponse(results={'mimetype': magic_result}) 50 | -------------------------------------------------------------------------------- /mimetype/mimetype/mimetype.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = mimetype 17 | Module = mimetype 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Determine mimetype of a payload 24 | -------------------------------------------------------------------------------- /mimetype/requirements.txt: -------------------------------------------------------------------------------- 1 | python-magic~=0.4.15 -------------------------------------------------------------------------------- /mimetype/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="mimetype", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Determine mimetype of a payload", 10 | packages=find_packages(exclude=['tests']), 11 | include_package_data=True, 12 | test_suite="tests", 13 | tests_require=['asynctest>=0.13.0'], 14 | ) 15 | -------------------------------------------------------------------------------- /mimetype/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /mimetype/tests/test_mimetype.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import os 18 | import logging 19 | import asynctest 20 | 21 | from pathlib import Path 22 | 23 | from stoq import Request, Stoq, Payload 24 | from stoq.data_classes import WorkerResponse 25 | 26 | 27 | class TestCore(asynctest.TestCase): 28 | def setUp(self) -> None: 29 | self.plugin_name = 'mimetype' 30 | self.base_dir = Path(os.path.realpath(__file__)).parent 31 | self.data_dir = os.path.join(self.base_dir, 'data') 32 | self.plugin_dir = os.path.join(self.base_dir.parent, self.plugin_name) 33 | self.generic_data = b'This is a magical string' 34 | 35 | def tearDown(self) -> None: 36 | pass 37 | 38 | async def test_scan(self) -> None: 39 | s = Stoq(plugin_dir_list=[self.plugin_dir]) 40 | plugin = s.load_plugin(self.plugin_name) 41 | payload = Payload(self.generic_data) 42 | response = await plugin.scan(payload, Request()) 43 | self.assertIsInstance(response, WorkerResponse) 44 | self.assertEqual('text/plain', response.results['mimetype']) 45 | -------------------------------------------------------------------------------- /mongodb/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft mongodb 2 | -------------------------------------------------------------------------------- /mongodb/README.md: -------------------------------------------------------------------------------- 1 | # Mongodb 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that saves results and archives payloads to/from MongoDB. 4 | 5 | ## Plugin Classes 6 | 7 | - [Archiver](https://stoq-framework.readthedocs.io/en/latest/dev/archivers.html) 8 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 9 | 10 | ## Configuration 11 | 12 | All options below may be set by: 13 | 14 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 15 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 16 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 17 | 18 | ### Options 19 | 20 | - `mongodb_uri` [str]: MongoDB URI 21 | 22 | > Must be formatted as described in the [MongoDB documentation](https://docs.mongodb.com/manual/reference/connection-string/) 23 | 24 | - `mongodb_database` [str]: Name of the database to use. 25 | 26 | > Defaults to `stoq`. 27 | 28 | - `mongodb_collection` [str]: MongoDB Collection name when saving results. 29 | 30 | > Defaults to `stoq`. 31 | -------------------------------------------------------------------------------- /mongodb/mongodb/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /mongodb/mongodb/mongodb.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = mongodb 17 | Module = mongodb 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.1 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Save results and archive payloads using MongoDB 24 | 25 | [options] 26 | # What is the hostname/ip and port of the mongodb server? 27 | # Note: Should be inline with mongodb documentation at 28 | # https://docs.mongodb.com/manual/reference/connection-string/ 29 | # 30 | # Example: 31 | # Connect to localhost on port 27017 using MongoDB URI Format 32 | # mongodb_uri = mongodb://localhost:27017/ 33 | 34 | # MongoDB database name 35 | # mongodb_database = stoq 36 | # 37 | # MongoDB Collection name when saving results 38 | # mongodb_collection = stoq 39 | -------------------------------------------------------------------------------- /mongodb/requirements.txt: -------------------------------------------------------------------------------- 1 | pymongo~=3.10 2 | -------------------------------------------------------------------------------- /mongodb/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="mongodb", 5 | version="3.0.1", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Save results and archive payloads using MongoDB", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /mraptor/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft mraptor 2 | -------------------------------------------------------------------------------- /mraptor/README.md: -------------------------------------------------------------------------------- 1 | # MacroRaptor 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that mimics the functionality of [mraptor3 from oletools](https://github.com/decalage2/oletools/blob/master/oletools/mraptor3.py) 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | -------------------------------------------------------------------------------- /mraptor/mraptor/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /mraptor/mraptor/mraptor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ 18 | Overview 19 | ======== 20 | 21 | Port of mraptor3 from oletools 22 | 23 | """ 24 | 25 | from typing import Dict, List 26 | from oletools import olevba3 as olevba 27 | from oletools.mraptor3 import MacroRaptor 28 | 29 | from stoq.plugins import WorkerPlugin 30 | from stoq import Payload, Request, WorkerResponse 31 | 32 | 33 | class MacroRaptorPlugin(WorkerPlugin): 34 | FLAGS: Dict[str, str] = {'A': 'AutoExec', 'W': 'Write', 'X': 'Execute'} 35 | 36 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 37 | results: Dict = {} 38 | filename = payload.results.payload_meta.extra_data.get( 39 | 'filename', payload.results.payload_id 40 | ) 41 | vba_parser = olevba.VBA_Parser(filename=filename, data=payload.content) 42 | 43 | if vba_parser.detect_vba_macros(): 44 | vba_modules: List[str] = [ 45 | vba_code[3] for vba_code in vba_parser.extract_all_macros() 46 | ] 47 | mraptor = MacroRaptor('\n'.join(vba_modules)) 48 | mraptor.scan() 49 | flags = [ 50 | self.FLAGS[flag] for flag in mraptor.get_flags() if flag in self.FLAGS 51 | ] 52 | results = { 53 | 'suspicous': mraptor.suspicious, 54 | 'flags': flags, 55 | 'filetype': vba_parser.type, 56 | 'matches': mraptor.matches, 57 | } 58 | 59 | return WorkerResponse(results) 60 | -------------------------------------------------------------------------------- /mraptor/mraptor/mraptor.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = mraptor 17 | Module = mraptor 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Port of mraptor3 from oletools 24 | -------------------------------------------------------------------------------- /mraptor/requirements.txt: -------------------------------------------------------------------------------- 1 | oletools>=0.54 2 | -------------------------------------------------------------------------------- /mraptor/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="mraptor", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Port of mraptor3 from oletools", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /ole/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft ole 2 | -------------------------------------------------------------------------------- /ole/README.md: -------------------------------------------------------------------------------- 1 | # ole 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that carves OLE streams from Microsoft Office Documents using [oletools](https://github.com/decalage2/oletools). 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | -------------------------------------------------------------------------------- /ole/ole/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /ole/ole/ole.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = ole 17 | Module = ole 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Carve OLE streams within Microsoft Office Documents 24 | -------------------------------------------------------------------------------- /ole/requirements.txt: -------------------------------------------------------------------------------- 1 | olefile>=0.46 2 | oletools>=0.53.1 3 | -------------------------------------------------------------------------------- /ole/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="ole", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Extract objects from OLE payloads", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /opswat/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft opswat 2 | -------------------------------------------------------------------------------- /opswat/README.md: -------------------------------------------------------------------------------- 1 | # OPSWAT Metascan 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that scans payloads using [OPSWAT Metadefender](https://www.opswat.com/products/metadefender) 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration 10 | 11 | All options below may be set by: 12 | 13 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 14 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 15 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 16 | 17 | ### Options 18 | 19 | - `opswat_url` [str]: URL for Metadefender 20 | 21 | - `apikey` [str]: Metadefender API key 22 | 23 | - `delay` [int]: Time in seconds to wait between checking for completed results 24 | 25 | - `max_attempts` [int]: Maximum amount of attempts to retrieve results 26 | -------------------------------------------------------------------------------- /opswat/opswat/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /opswat/opswat/opswat.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = opswat 17 | Module = opswat 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.1 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Scan payloads using OPSWAT MetaDefender 24 | 25 | [options] 26 | # opswat_url = 27 | # apikey = 28 | 29 | # Time in seconds to wait between checking for completed results 30 | # Default: 30 31 | # delay = 30 32 | 33 | # Maximum amount of attempts to retrieve results 34 | # Default: 10 35 | # max_attempts = 10 36 | -------------------------------------------------------------------------------- /opswat/requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp~=3.7.4 2 | -------------------------------------------------------------------------------- /opswat/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="opswat", 5 | version="3.0.1", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Scan payloads using OPSWAT MetaDefender", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /pecarve/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft pecarve 2 | -------------------------------------------------------------------------------- /pecarve/README.md: -------------------------------------------------------------------------------- 1 | # pecarve 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that carves PE executables from payloads. 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration 10 | 11 | All options below may be set by: 12 | 13 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 14 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 15 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 16 | 17 | ### Options 18 | 19 | - `pe_headers` [str]: Regex pattern to match for PE headers (i.e., MZ or ZM) 20 | -------------------------------------------------------------------------------- /pecarve/pecarve/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /pecarve/pecarve/pecarve.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = pecarve 17 | Module = pecarve 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 2.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Carve portable executable files from a data stream 24 | 25 | [options] 26 | # pe_headers = \x4d\x5a|\x5a\x4d 27 | -------------------------------------------------------------------------------- /pecarve/requirements.txt: -------------------------------------------------------------------------------- 1 | pefile~=2018.8.8 -------------------------------------------------------------------------------- /pecarve/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="pecarve", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Carve portable executable files from a data stream", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /peinfo/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft peinfo 2 | -------------------------------------------------------------------------------- /peinfo/README.md: -------------------------------------------------------------------------------- 1 | # peinfo 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that parses PE executable files and produces metadata about the payload. 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration 10 | 11 | All options below may be set by: 12 | 13 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 14 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 15 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 16 | 17 | ## Configuration and Options 18 | 19 | No configuration options are required. 20 | 21 | ## Special Thanks 22 | 23 | Thanks to those at Facebook that provided most of the contributions for this plugin. 24 | -------------------------------------------------------------------------------- /peinfo/peinfo/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /peinfo/peinfo/peinfo.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = peinfo 17 | Module = peinfo 18 | 19 | [Documentation] 20 | Author = Facebook, Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Gather relevant information about an executable using pefile 24 | -------------------------------------------------------------------------------- /peinfo/requirements.txt: -------------------------------------------------------------------------------- 1 | pefile~=2018.8.8 -------------------------------------------------------------------------------- /peinfo/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="peinfo", 5 | version="3.0.0", 6 | author="Facebook, Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Gather relevant information about an executable using pefile", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /pubsub/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft pubsub 2 | -------------------------------------------------------------------------------- /pubsub/README.md: -------------------------------------------------------------------------------- 1 | # Redis Queue 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that interacts with Google Cloud Pub/Sub for queuing 4 | 5 | ## Plugin Classes 6 | 7 | - [Archiver](https://stoq-framework.readthedocs.io/en/latest/dev/archivers.html) 8 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 9 | - [Provider](https://stoq-framework.readthedocs.io/en/latest/dev/providers.html) 10 | 11 | ## Configuration 12 | 13 | All options below may be set by: 14 | 15 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 16 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 17 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 18 | 19 | ### Options 20 | 21 | - `project_id` [str]: Google Cloud project ID 22 | 23 | - `topic` [str]: Pub/Sub Topic to bind to 24 | 25 | - `subscription` [str]: Pub/Sub Subscription to monitor for messages 26 | 27 | - `max_messages` [int]: Maximum number of messages to pull at once 28 | 29 | ## Usage 30 | 31 | ### Pub/Sub Queuing Example 32 | 33 | Start `stoq` using `pubsub` as the provider plugin, `filedir` as the source archiver, then scan the payload with the `hash`, and send results to `stdout` connector: 34 | 35 | $ stoq run -P pubsub -S filedir -a hash -C stdout 36 | 37 | In another terminal, load files from `/tmp/test-files` using the `filedir` provider plugin, then archive the payloads with `filedir` archive plugin, and send a message to the `pubsub` queue for processing: 38 | 39 | $ stoq run -P filedir -A filedir -C pubsub --plugin-opts filedir:source_dir=/tmp/test-files 40 | -------------------------------------------------------------------------------- /pubsub/pubsub/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /pubsub/pubsub/pubsub.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = pubsub 17 | Module = pubsub 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Interact with Google Cloud Pub/Sub 24 | 25 | [options] 26 | # Google Cloud Project id 27 | # project_id = 28 | 29 | # Pub/Sub Topic for to bind to 30 | # topic = stoq 31 | 32 | # Pub/Sub Subscription to monitor for messages 33 | # subscription = stoq 34 | 35 | # When used as a Connector plugin, should the ArchiveResponses be saved, or StoqResponse? 36 | # Useful for sending archived payload metadata to topic. 37 | # Default: True 38 | # publish_archive = True 39 | 40 | # Number of messages to retrieve per request 41 | # Default: 10 42 | # max_messages = 10 43 | -------------------------------------------------------------------------------- /pubsub/requirements.txt: -------------------------------------------------------------------------------- 1 | google-cloud-pubsub~=0.39.0 -------------------------------------------------------------------------------- /pubsub/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="pubsub", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Interact with Google Cloud Pub/Sub", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /redis-queue/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft redis-queue 2 | -------------------------------------------------------------------------------- /redis-queue/README.md: -------------------------------------------------------------------------------- 1 | # Redis Queue 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that leverages Redis for queuing and saving results 4 | 5 | ## Plugin Classes 6 | 7 | - [Archiver](https://stoq-framework.readthedocs.io/en/latest/dev/archivers.html) 8 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 9 | - [Provider](https://stoq-framework.readthedocs.io/en/latest/dev/providers.html) 10 | 11 | ## Configuration 12 | 13 | All options below may be set by: 14 | 15 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 16 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 17 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 18 | 19 | ### Options 20 | 21 | - `redis_host` [str]: Redis hostname or ip 22 | 23 | - `redis_port` [int]: Redis port 24 | 25 | - `redis_queue` [str]: Queue name for sending and receiving messages 26 | 27 | - `publish_archive` [`True`/`False`]: When used as a Connector plugin, should the ArchiveResponses be saved, or StoqResponse? Useful for sending archived payload metadata to topic. 28 | 29 | - `max_connections` [int]: Max connections permitted in redis connection pool 30 | 31 | ## Usage 32 | 33 | ### Redis Queuing Example 34 | 35 | Start `stoq` using `redis-queue` as the provider plugin, `filedir` as the source archiver, then scan the payload with the `hash`, and send results to `stdout` connector: 36 | 37 | $ stoq run -P redis-queue -S filedir -a hash -C stdout 38 | 39 | In another terminal, load files from `/tmp/test-files` using the `filedir` provider plugin, then archive the payloads with `filedir` archive plugin, and send a message to the `redis-queue` queue for processing: 40 | 41 | $ stoq run -P filedir -A filedir -C redis-queue --plugin-opts filedir:source_dir=/tmp/test-files 42 | -------------------------------------------------------------------------------- /redis-queue/redis-queue/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /redis-queue/redis-queue/redis-queue.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = redis-queue 17 | Module = redis-queue 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Interact with Redis server for queuing 24 | 25 | [options] 26 | # redis_host = 127.0.0.1 27 | # redis_port = 6379 28 | # redis_queue = stoq 29 | 30 | # When used as a Connector plugin, should the ArchiveResponses be saved, or StoqResponse? 31 | # Useful for sending archived payload metadata to topic. 32 | # Default: True 33 | # publish_archive = True 34 | 35 | # Max connections permitted in redis connection pool 36 | # max_connections = 15 37 | -------------------------------------------------------------------------------- /redis-queue/requirements.txt: -------------------------------------------------------------------------------- 1 | redis~=3.0.1 -------------------------------------------------------------------------------- /redis-queue/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="redis-queue", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Interact with Redis server for queuing", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /rtf/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft rtf 2 | -------------------------------------------------------------------------------- /rtf/README.md: -------------------------------------------------------------------------------- 1 | # rtf 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that extracts objects from RTF payloads using [oletools](https://github.com/decalage2/oletools). 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | -------------------------------------------------------------------------------- /rtf/requirements.txt: -------------------------------------------------------------------------------- 1 | oletools~=0.53.1 -------------------------------------------------------------------------------- /rtf/rtf/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /rtf/rtf/rtf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ 18 | Overview 19 | ======== 20 | 21 | Extract objects from RTF payloads 22 | 23 | """ 24 | 25 | from typing import List 26 | from oletools import rtfobj 27 | 28 | from stoq.plugins import WorkerPlugin 29 | from stoq import Payload, PayloadMeta, ExtractedPayload, Request, WorkerResponse 30 | 31 | 32 | class RtfPlugin(WorkerPlugin): 33 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 34 | extracted: List[ExtractedPayload] = [] 35 | rtf = rtfobj.RtfObjParser(payload.content) 36 | rtf.parse() 37 | 38 | for obj_idx, obj in enumerate(rtf.objects): 39 | if obj.is_ole: 40 | data = obj.oledata 41 | meta = PayloadMeta(extra_data={'index': obj_idx}) 42 | elif obj.is_package: 43 | data = obj.olepkgdata 44 | meta = PayloadMeta( 45 | extra_data={'index': obj_idx, 'filename': obj.filename} 46 | ) 47 | else: 48 | data = obj.rawdata 49 | meta = PayloadMeta(extra_data={'index': obj_idx}) 50 | extracted.append(ExtractedPayload(data, meta)) 51 | return WorkerResponse(extracted=extracted) 52 | -------------------------------------------------------------------------------- /rtf/rtf/rtf.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = rtf 17 | Module = rtf 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Extract objects from RTF payloads 24 | -------------------------------------------------------------------------------- /rtf/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="rtf", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Extract objects from RTF payloads", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /s3/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft s3 2 | -------------------------------------------------------------------------------- /s3/README.md: -------------------------------------------------------------------------------- 1 | # S3 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that reads and writes data to Amazon S3 buckets. 4 | 5 | ## Plugin Classes 6 | 7 | - [Archiver](https://stoq-framework.readthedocs.io/en/latest/dev/archivers.html) 8 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 9 | 10 | ## Configuration 11 | 12 | All options below may be set by: 13 | 14 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 15 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 16 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 17 | 18 | ### Options 19 | 20 | - `access_key` [str]: AWS Access Key 21 | - `secret_key` [str]: AWS Secret Key 22 | 23 | #### Archiver 24 | 25 | - `archive_bucket` [str]: S3 Bucket to read/save archived files from 26 | 27 | - `use_sha` [`True`/`False`]: When archiving files, should archived files be saved in a directory structure based on the first five characters of the sha1 hash. 28 | > For example, if the sha1 hash of the payload is `da39a3ee5e6b4b0d3255bfef95601890afd80709`, the payload will be archived to `gs://$archive_bucket/d/a/3/9/a/da39a3ee5e6b4b0d3255bfef95601890afd80709`. 29 | 30 | #### Connector 31 | 32 | - `connector_bucket` [str]: S3 Bucket where results will be saved to 33 | -------------------------------------------------------------------------------- /s3/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3~=1.9.62 -------------------------------------------------------------------------------- /s3/s3/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /s3/s3/s3.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = s3 17 | Module = s3 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Read and write data to Amazon S3 24 | 25 | [options] 26 | # access_key = 27 | # secret_key = 28 | # archive_bucket = 29 | # connector_bucket = 30 | # use_sha = True 31 | -------------------------------------------------------------------------------- /s3/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="s3", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Read and write data to Amazon S3", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /sentinel/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft sentinel 2 | -------------------------------------------------------------------------------- /sentinel/README.md: -------------------------------------------------------------------------------- 1 | # Azure Sentinel 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that sends results to [Azure Sentinel](https://azure.microsoft.com/en-us/services/azure-sentinel/). 4 | 5 | ## Plugin Classes 6 | 7 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 8 | 9 | ## Prerequisites 10 | 11 | - Obtain Azure Log Analytics Workspace ID and Key. Directions for obtaining the keys can be found [here](https://docs.microsoft.com/en-us/azure/azure-monitor/platform/agent-linux#obtain-workspace-id-and-key) 12 | 13 | ## Configuration 14 | 15 | All options below may be set by: 16 | 17 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 18 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 19 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 20 | 21 | ### Required 22 | 23 | - `workspaceid` [str]: ClientID/ID for the Log Analytics Workspace string 24 | 25 | - `workspacekey` [str]: Key/Secret for the Log Analytics Workspace string. The primary or secondary shared key may be used. 26 | 27 | - `logtype` [str]: This field denote the Log Analytics table that the log will send to. Log analytics will automatically append `_CL` to this value. 28 | > Defaults to `stoQ`. 29 | -------------------------------------------------------------------------------- /sentinel/requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp~=3.7.4 2 | -------------------------------------------------------------------------------- /sentinel/sentinel/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/sentinel/sentinel/__init__.py -------------------------------------------------------------------------------- /sentinel/sentinel/sentinel.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = sentinel 17 | Module = sentinel 18 | 19 | [Documentation] 20 | Author = Joe Stahl (@happy-jo) 21 | Version = 3.0.2 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Send reults to Azure Sentinel (Log Analytics Workspace) using the Azure Log Analytics API 24 | 25 | [options] 26 | # Azure Log Analytics Workspace ID Connection string 27 | # workspaceid = 28 | 29 | # Azure Log Analytics Workspace Key Connection string 30 | # workspacekey = 31 | 32 | # Azure Sentinel Log Table Name string 33 | # logType = stoQ 34 | -------------------------------------------------------------------------------- /sentinel/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="sentinel", 5 | version="3.0.2", 6 | author="Joe Stahl (@happy-jo)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Send reults to Azure Sentinel (Log Analytics Workspace) using the Azure Log Analytics API", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /smtp/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft smtp 2 | -------------------------------------------------------------------------------- /smtp/requirements.txt: -------------------------------------------------------------------------------- 1 | python-dateutil~=2.8.0 2 | -------------------------------------------------------------------------------- /smtp/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="smtp", 5 | version="3.0.8", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public/v2", 8 | license="Apache License 2.0", 9 | description="SMTP Parser Worker", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /smtp/smtp/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /smtp/smtp/smtp.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = smtp 17 | Module = smtp 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.8 22 | Website = https://github.com/PUNCH-Cyber/stoq 23 | Description = SMTP Parser Worker 24 | 25 | [options] 26 | # Save body of e-mail (text or html) to the results. 27 | # omit_body = False 28 | 29 | # Always send extracted attachments to these plugins 30 | # always_dispatch = hash 31 | 32 | # Should attachments be archived? 33 | # archive_attachments = True 34 | 35 | # Automatically extract IOC's from SMTP sessions 36 | # extract_iocs = True 37 | 38 | # SMTP sessions keys to attempt to extract IOC's from 39 | # ioc_keys = received, x-orig-ip, x-originating-ip, x-remote-ip, x-sender-ip, body, body_html 40 | -------------------------------------------------------------------------------- /stdout/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft stdout 2 | -------------------------------------------------------------------------------- /stdout/README.md: -------------------------------------------------------------------------------- 1 | # STDOUT 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that prints results to stdout. 4 | 5 | ## Plugin Classes 6 | 7 | - [Connector](https://stoq-framework.readthedocs.io/en/latest/dev/connectors.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | -------------------------------------------------------------------------------- /stdout/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="stdout", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Sends content to STDOUT", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /stdout/stdout/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /stdout/stdout/stdout.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ 16 | Overview 17 | ======== 18 | 19 | Sends content to STDOUT 20 | 21 | """ 22 | 23 | from stoq.data_classes import StoqResponse 24 | from stoq.plugins import ConnectorPlugin 25 | 26 | 27 | class StdoutConnector(ConnectorPlugin): 28 | async def save(self, response: StoqResponse) -> None: 29 | """ 30 | Print results to STDOUT 31 | 32 | """ 33 | print(response) 34 | -------------------------------------------------------------------------------- /stdout/stdout/stdout.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = stdout 17 | Module = stdout 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Sends content to STDOUT 24 | 25 | -------------------------------------------------------------------------------- /swfcarve/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft swfcarve 2 | -------------------------------------------------------------------------------- /swfcarve/README.md: -------------------------------------------------------------------------------- 1 | # SWFCarve 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that carves and decompresses SWF files from payloads 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration 10 | 11 | All options below may be set by: 12 | 13 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 14 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 15 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 16 | 17 | ### Options 18 | 19 | - `swf_headers` [str]: Regex pattern to match for SWF headers (i.e., CWS or FWS) 20 | -------------------------------------------------------------------------------- /swfcarve/requirements.txt: -------------------------------------------------------------------------------- 1 | pylzma>=0.5.0 -------------------------------------------------------------------------------- /swfcarve/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="swfcarve", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Carve and decompress SWF files from payloads", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /swfcarve/swfcarve/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /swfcarve/swfcarve/swfcarve.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = swfcarve 17 | Module = swfcarve 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Carve and decompress SWF files from payloads 24 | 25 | [options] 26 | # swf_headers = CWS|ZWS|FWS 27 | -------------------------------------------------------------------------------- /symhash/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft symhash 2 | -------------------------------------------------------------------------------- /symhash/README.md: -------------------------------------------------------------------------------- 1 | # SYMHash 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin calculate symbol table hashes of a Mach-O executable file using [symhash](https://github.com/threatstream/symhash). 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | -------------------------------------------------------------------------------- /symhash/requirements.txt: -------------------------------------------------------------------------------- 1 | git+https://github.com/threatstream/symhash 2 | -------------------------------------------------------------------------------- /symhash/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="symhash", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public/v2", 8 | license="Apache License 2.0", 9 | description="Calculate symbol table hashes of a Mach-O executable file", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /symhash/symhash/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /symhash/symhash/symhash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ 18 | Overview 19 | ======== 20 | 21 | Calculate symbol table hashes of a Mach-O executable file 22 | 23 | """ 24 | 25 | from symhash import create_sym_hash 26 | 27 | from stoq.plugins import WorkerPlugin 28 | from stoq import Payload, Request, WorkerResponse 29 | 30 | 31 | class SymHash(WorkerPlugin): 32 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 33 | return WorkerResponse( 34 | results={'symhash': create_sym_hash(data=payload.content)} 35 | ) 36 | -------------------------------------------------------------------------------- /symhash/symhash/symhash.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2018 PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = symhash 17 | Module = symhash 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Calculate symbol table hashes of a Mach-O executable file 24 | -------------------------------------------------------------------------------- /tika/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft tika 2 | -------------------------------------------------------------------------------- /tika/README.md: -------------------------------------------------------------------------------- 1 | # Tika 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that uploads content to a [Tika](https://tika.apache.org/) server for automated text extraction. 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration 10 | 11 | All options below may be set by: 12 | 13 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 14 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 15 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 16 | 17 | ### Options 18 | 19 | - `tika_url` [str]: URL of Tika Server 20 | -------------------------------------------------------------------------------- /tika/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="tika", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Upload content to a Tika server for automated text extraction", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /tika/tika/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tika/tika/tika.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """ 18 | Overview 19 | ======== 20 | 21 | Upload content to a Tika server for automated text extraction 22 | 23 | """ 24 | 25 | import requests 26 | 27 | from stoq.plugins import WorkerPlugin 28 | from stoq.helpers import StoqConfigParser 29 | from stoq import Payload, Request, WorkerResponse, ExtractedPayload 30 | 31 | 32 | class TikaPlugin(WorkerPlugin): 33 | def __init__(self, config: StoqConfigParser) -> None: 34 | super().__init__(config) 35 | 36 | self.tika_url = config.get( 37 | 'options', 'tika_url', fallback='http://localhost:9998/tika' 38 | ) 39 | 40 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 41 | """ 42 | Upload content to a Tika server for automated text extraction 43 | 44 | """ 45 | response = requests.put(self.tika_url, data=payload.content) 46 | response.raise_for_status() 47 | extracted = [ExtractedPayload(response.content)] 48 | return WorkerResponse(extracted=extracted) 49 | -------------------------------------------------------------------------------- /tika/tika/tika.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = tika 17 | Module = tika 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Upload content to a Tika server for automated text extraction 24 | 25 | [options] 26 | # tika_url = http://localhost:9998/tika 27 | -------------------------------------------------------------------------------- /tnef/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft tnef 2 | -------------------------------------------------------------------------------- /tnef/README.md: -------------------------------------------------------------------------------- 1 | # TNEFParse 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that extracts objects from TNEF payloads 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration and Options 10 | 11 | No configuration options are required. 12 | 13 | #### Module performance 14 | 15 | The speed of the `UnicodeDammit` decoder from `BeautifulSoup` module is much faster when the `cchardet` module is installed, 16 | but will fall back to the `chardet` module if it is not installed. 17 | -------------------------------------------------------------------------------- /tnef/requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4~=4.6.3 2 | git+https://github.com/koodaamo/tnefparse -------------------------------------------------------------------------------- /tnef/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="tnef", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="TNEF File Extractor", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /tnef/tnef/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tnef/tnef/tnef.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | """ 17 | Overview 18 | ======== 19 | 20 | Extract object from TNEF payloads 21 | 22 | """ 23 | 24 | from typing import List 25 | from tnefparse import TNEF 26 | from bs4 import UnicodeDammit 27 | 28 | from stoq.plugins import WorkerPlugin 29 | from stoq import Payload, Request, WorkerResponse, ExtractedPayload, PayloadMeta 30 | 31 | 32 | class TNEFExtractorPlugin(WorkerPlugin): 33 | async def scan(self, payload: Payload, request: Request) -> WorkerResponse: 34 | extracted: List[ExtractedPayload] = [] 35 | tnef_results = TNEF(payload.content) 36 | if tnef_results.attachments: 37 | for tnef_attachment in tnef_results.attachments: 38 | try: 39 | filename = UnicodeDammit(tnef_attachment.name).unicode_markup 40 | except: 41 | filename = "None" 42 | tnef_meta = PayloadMeta(extra_data={'filename': filename}) 43 | extracted.append(ExtractedPayload(tnef_attachment.data, tnef_meta)) 44 | return WorkerResponse(extracted=extracted) 45 | -------------------------------------------------------------------------------- /tnef/tnef/tnef.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = tnef 17 | Module = tnef 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq 23 | Description = TNEF File Extractor 24 | 25 | -------------------------------------------------------------------------------- /trid/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft trid 2 | -------------------------------------------------------------------------------- /trid/README.md: -------------------------------------------------------------------------------- 1 | # TRiD 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that scans a payload using [TRiD](http://mark0.net/soft-trid-e.html) 4 | 5 | > Note: TRiD binary and definitions need to be installed for this plugin to operate properly. 6 | 7 | ## Plugin Classes 8 | 9 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 10 | 11 | ## Configuration 12 | 13 | All options below may be set by: 14 | 15 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 16 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 17 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 18 | 19 | ### Options 20 | 21 | - `bin` [str]: Path to TRiD binary 22 | 23 | - `trids_defs` [str]: Path to TRiD definitions 24 | 25 | - `skip_warnings` [List]: List of TRiD warnings to skip. 26 | 27 | > Paths may be relative to the module, or a full path. 28 | -------------------------------------------------------------------------------- /trid/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="trid", 5 | version="3.0.2", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Identify file types from their TrID signature", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /trid/trid/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /trid/trid/trid.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = trid 17 | Module = trid 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.2 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Identify file types from their TrID signature 24 | 25 | [options] 26 | # bin = trid 27 | # trid_defs = triddefs.trd 28 | # skip_warnings = "file seems to be plain text/ASCII" 29 | -------------------------------------------------------------------------------- /vtmis-filefeed/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft vtmis-filefeed 2 | -------------------------------------------------------------------------------- /vtmis-filefeed/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="vtmis-filefeed", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Process VTMIS File Feed", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /vtmis-filefeed/vtmis-filefeed/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /vtmis-filefeed/vtmis-filefeed/vtmis-filefeed.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = vtmis-filefeed 17 | Module = vtmis-filefeed 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Process VTMIS File Feed 24 | 25 | [options] 26 | # apikey = 27 | # time_since = 1m 28 | # download = False 29 | -------------------------------------------------------------------------------- /vtmis-search/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft vtmis-search 2 | -------------------------------------------------------------------------------- /vtmis-search/README.md: -------------------------------------------------------------------------------- 1 | # VTMIS Search 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that searches [VTMIS](https://www.virustotal.com) for sha1 hash of a payload or from results of `iocextract` plugin. 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | - [Dispatcher](https://stoq-framework.readthedocs.io/en/latest/dev/dispatchers.html) 9 | - [DeepDispatcher](https://stoq-framework.readthedocs.io/en/latest/dev/deepdispatchers.html) 10 | 11 | ## Configuration 12 | 13 | All options below may be set by: 14 | 15 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 16 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 17 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 18 | 19 | ### Options 20 | 21 | - `apikey` [str]: VTMIS API key 22 | -------------------------------------------------------------------------------- /vtmis-search/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="vtmis-search", 5 | version="3.0.1", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Search VTMIS for sha1 hash of a payload or from results of `iocextract` plugin", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /vtmis-search/vtmis-search/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /vtmis-search/vtmis-search/vtmis-search.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = vtmis-search 17 | Module = vtmis-search 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.1 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Search VTMIS for sha1 hash of a payload or from results of `iocextract` plugin 24 | 25 | [options] 26 | # apikey = 27 | -------------------------------------------------------------------------------- /xdpcarve/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft xdpcarve 2 | -------------------------------------------------------------------------------- /xdpcarve/README.md: -------------------------------------------------------------------------------- 1 | # XDPCarve 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin carves and decodes elements from XDP objects from payloads 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Configuration 10 | 11 | All options below may be set by: 12 | 13 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 14 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 15 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 16 | 17 | ### Options 18 | 19 | - `elements` [str]: Elements to look for objects in (i.e., `chunk`) 20 | -------------------------------------------------------------------------------- /xdpcarve/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="xdpcarve", 5 | version="3.0.0", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Carve and decode elements from XDP objects", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /xdpcarve/xdpcarve/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /xdpcarve/xdpcarve/xdpcarve.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = xdpcarve 17 | Module = xdpcarve 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Carve and decode elements from XDP objects 24 | 25 | [options] 26 | # elements = chunk 27 | -------------------------------------------------------------------------------- /xordecode/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft xordecode 2 | -------------------------------------------------------------------------------- /xordecode/README.md: -------------------------------------------------------------------------------- 1 | # XORDecode 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that decodes XOR encoded payloads. 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | ## Use 10 | 11 | This plugin is designed to be used with Dispatching plugins that support XOR Key extraction, such as the 12 | [yara](https://github.com/PUNCH-Cyber/stoq-plugins-public/tree/v3/yara) plugin. Dispatchers must provide a `xorkey` key in `DispatcherResponse.meta`. This plugin will search through the `DispatcherResponse.meta` object for keys with the value of `xorkey`. Once found it will use the values in the `xorkey` in an attempt to XOR decode the payload. The `xorkey` values must be an integer, string, or a list of strings or integers. If a list is provided, this plugin will using rolling xor to decode the payload. 13 | 14 | ## Configuration and Options 15 | 16 | No configuration options are required. 17 | -------------------------------------------------------------------------------- /xordecode/requirements.txt: -------------------------------------------------------------------------------- 1 | dpath>=2.0.1 2 | -------------------------------------------------------------------------------- /xordecode/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="xordecode", 5 | version="3.0.0", 6 | author="Marcus LaFerrera <@mlaferrera>", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Decode XOR encoded content", 10 | packages=find_packages(exclude=['tests']), 11 | include_package_data=True, 12 | test_suite='tests', 13 | tests_require=['asynctest>=0.13.0'], 14 | ) 15 | -------------------------------------------------------------------------------- /xordecode/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/xordecode/tests/__init__.py -------------------------------------------------------------------------------- /xordecode/xordecode/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2015 PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /xordecode/xordecode/xordecode.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = xordecode 17 | Module = xordecode 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Decode XOR encoded payloads 24 | -------------------------------------------------------------------------------- /xorsearch/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft xorsearch 2 | -------------------------------------------------------------------------------- /xorsearch/README.md: -------------------------------------------------------------------------------- 1 | # XORSearch 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that scans a payload using [XORSearch](https://blog.didierstevens.com/programs/xorsearch/) 4 | 5 | > Note: XORSearch binary needs to be installed for this plugin to operate properly. 6 | 7 | ## Plugin Classes 8 | 9 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 10 | 11 | ## Configuration 12 | 13 | All options below may be set by: 14 | 15 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 16 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 17 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 18 | 19 | ### Options 20 | 21 | - `bin_path` [str]: Path to xorsearch binary 22 | 23 | - `terms` [str]: Path to text file containing terms to search 24 | 25 | > Paths may be relative to the module, or a full path. 26 | -------------------------------------------------------------------------------- /xorsearch/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="xorsearch", 5 | version="3.1.1", 6 | author="Marcus LaFerrera (@mlaferrera)", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Scan a payload using xorsearch", 10 | packages=find_packages(exclude=['tests']), 11 | include_package_data=True, 12 | test_suite='tests', 13 | tests_require=['asynctest>=0.13.0'], 14 | ) 15 | -------------------------------------------------------------------------------- /xorsearch/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/xorsearch/tests/__init__.py -------------------------------------------------------------------------------- /xorsearch/tests/test_xorsearch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2014-present PUNCH Cyber Analytics Group 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import os 18 | import asynctest 19 | 20 | from pathlib import Path 21 | 22 | from stoq import Request, Stoq, Payload, WorkerResponse 23 | 24 | 25 | class TestCore(asynctest.TestCase): 26 | def setUp(self) -> None: 27 | self.plugin_name = 'xorsearch' 28 | self.base_dir = Path(os.path.realpath(__file__)).parent 29 | self.data_dir = os.path.join(self.base_dir, 'data') 30 | self.plugin_dir = os.path.join(self.base_dir.parent, self.plugin_name) 31 | self.generic_data = b'MZAdjustTokenPrivileges CurrentVersion' 32 | 33 | def tearDown(self) -> None: 34 | pass 35 | 36 | async def test_scan(self) -> None: 37 | s = Stoq(plugin_dir_list=[self.plugin_dir]) 38 | plugin = s.load_plugin(self.plugin_name) 39 | xord = bytes(x ^ 92 for x in self.generic_data) 40 | payload = Payload(xord) 41 | response = await plugin.scan(payload, Request()) 42 | self.assertIsInstance(response, WorkerResponse) 43 | self.assertIn('0x5C', response.results) 44 | self.assertEqual( 45 | 'AdjustTokenPrivileges CurrentVersion', response.results['0x5C'][0]['match'] 46 | ) 47 | self.assertEqual('CurrentVersion', response.results['0x5C'][1]['match']) 48 | -------------------------------------------------------------------------------- /xorsearch/xorsearch/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /xorsearch/xorsearch/terms.txt: -------------------------------------------------------------------------------- 1 | AdjustTokenPrivileges 2 | CreateFile 3 | CreateProcess 4 | CurrentVersion 5 | GetCommandLine 6 | GetFile 7 | GetTempPath 8 | GetTickCount 9 | GetVersion 10 | LoadResource 11 | RegSetValue 12 | ShellExecute 13 | program cannot -------------------------------------------------------------------------------- /xorsearch/xorsearch/xorsearch.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = xorsearch 17 | Module = xorsearch 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.1.1 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Scan a payload using xorsearch 24 | 25 | [options] 26 | # bin = xorsearch 27 | # terms = terms.txt 28 | -------------------------------------------------------------------------------- /xyz/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft xyz 2 | -------------------------------------------------------------------------------- /xyz/README.md: -------------------------------------------------------------------------------- 1 | # Xyz 2 | 3 | [stoQ](https://stoq-framework.readthedocs.io/en/latest/index.html) plugin that extracts rich metadata from Zip files 4 | 5 | ## Plugin Classes 6 | 7 | - [Worker](https://stoq-framework.readthedocs.io/en/latest/dev/workers.html) 8 | 9 | 10 | ## Configuration 11 | 12 | All options below may be set by: 13 | 14 | - [plugin configuration file](https://stoq-framework.readthedocs.io/en/latest/dev/plugin_overview.html#configuration) 15 | - [`stoq` command](https://stoq-framework.readthedocs.io/en/latest/gettingstarted.html#plugin-options) 16 | - [`Stoq` class](https://stoq-framework.readthedocs.io/en/latest/dev/core.html?highlight=plugin_opts#using-providers) 17 | 18 | ### Options 19 | 20 | - `decompress_files` [`True`/`False`]: Decompress files within zip and store metadata 21 | 22 | - `derive_deflate_level` [`True`/`False`]: Calculate the deflate level 23 | 24 | 25 | ## Thanks 26 | 27 | Thanks to Sandia National Labs and Charles Smutz for authoring and open sourcing the [original code](https://github.com/sandialabs/xyz). 28 | 29 | The original MIT license can be found in [xyz.py](xyz/xyz.py) 30 | 31 | 32 | ## Note 33 | 34 | This version has been modified from the original to work with the stoQ framework as well as python 3.6+ 35 | -------------------------------------------------------------------------------- /xyz/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="xyz", 5 | version="3.0.0", 6 | author="Marcus LaFerrera <@mlaferrera>", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0, MIT", 9 | description="Extract Zip file metadata", 10 | packages=find_packages(), 11 | include_package_data=True, 12 | ) 13 | -------------------------------------------------------------------------------- /xyz/xyz/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /xyz/xyz/xyz.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = xyz 17 | Module = xyz 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.0 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Extract Zip file metadata 24 | 25 | [options] 26 | # Decompress files within zip and store metadata 27 | # Default: True 28 | # decompress_files = True 29 | 30 | # Calculate the deflate level 31 | # Default: True 32 | # derive_deflate_level = True 33 | -------------------------------------------------------------------------------- /yara/MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft yarascan 2 | -------------------------------------------------------------------------------- /yara/requirements.txt: -------------------------------------------------------------------------------- 1 | yara-python>=3.11 2 | -------------------------------------------------------------------------------- /yara/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="yara", 5 | version="3.0.3", 6 | author="Marcus LaFerrera (@mlaferrera), David Maydewd", 7 | url="https://github.com/PUNCH-Cyber/stoq-plugins-public", 8 | license="Apache License 2.0", 9 | description="Process a payload using yara", 10 | packages=find_packages(exclude=['tests']), 11 | include_package_data=True, 12 | test_suite='tests', 13 | tests_require=['asynctest>=0.13.0'], 14 | ) 15 | -------------------------------------------------------------------------------- /yara/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PUNCH-Cyber/stoq-plugins-public/8c2c94e43ce54221121e8e3f542b54d255862078/yara/tests/__init__.py -------------------------------------------------------------------------------- /yara/tests/data/dispatch_rules.yar: -------------------------------------------------------------------------------- 1 | rule test_dispatch_rule: tag1 tag2 2 | { 3 | meta: 4 | plugin = "test_dispatch_plugin" 5 | save = "True" 6 | strings: 7 | $a = "testtesttest" 8 | condition: 9 | any of them 10 | } 11 | 12 | rule test_save_false 13 | { 14 | meta: 15 | plugin = "save_false" 16 | save = "False" 17 | strings: 18 | $a = "save_false" 19 | condition: 20 | any of them 21 | } 22 | 23 | rule test_xorkey_creation 24 | { 25 | meta: 26 | plugin = "xordecode" 27 | save = "True" 28 | xor_plaintext_for_string_this_prog = "This program" 29 | // xorkey = "Only extract first XOR key as str by yarascan.py, if xor_first_match is True" 30 | // xor_info = "Extract XOR keys as a list of tuples by yarascan.py, if xor_first_match is False" 31 | strings: 32 | $this_prog = "This program" xor(0x01-0xFF) 33 | condition: 34 | any of them 35 | } 36 | 37 | rule test_xor_info_creation 38 | { 39 | meta: 40 | plugin = "xordecode" 41 | save = "True" 42 | xor_plaintext_for_string_this_prog = "This program" 43 | xor_plaintext_for_string_this_prog_2b = "This program" 44 | // xorkey = "Only extract first XOR key as str by yarascan.py, if xor_first_match is True" 45 | // xor_info = "Extract XOR keys as a list of tuples by yarascan.py, if xor_first_match is False" 46 | strings: 47 | $this_prog = "This program" xor(0x01-0xFF) 48 | $this_prog_2b = "Tiir qrngsal" xor(0x01-0xFF) 49 | condition: 50 | any of them 51 | } 52 | -------------------------------------------------------------------------------- /yara/tests/data/invalid_rules.yar: -------------------------------------------------------------------------------- 1 | rule valid_syntax_rule 2 | { 3 | meta: 4 | plugin = "test_plugin" 5 | save = "True" 6 | strings: 7 | $a = "this too shall pass" 8 | condition: 9 | any of them 10 | } 11 | 12 | rule invalid_syntax 13 | { 14 | meta: 15 | plugin = "text_plugin" 16 | save = "False" 17 | strings: 18 | $a = "this shall fail miserably" 19 | condition: 20 | any of them -------------------------------------------------------------------------------- /yara/tests/data/scan_rules.yar: -------------------------------------------------------------------------------- 1 | rule test_scan_rule 2 | { 3 | meta: 4 | plugin = "test_scan_plugin" 5 | save = "True" 6 | strings: 7 | $a = "testtesttest" 8 | condition: 9 | any of them 10 | } 11 | 12 | rule test_scan_metadata 13 | { 14 | meta: 15 | plugin = "save_false" 16 | author = "Peter Rabbit" 17 | strings: 18 | $a = "scan_meta" 19 | condition: 20 | any of them 21 | } 22 | 23 | rule test_scan_metadata_bytes 24 | { 25 | meta: 26 | plugin = "save_false" 27 | author = "Peter Rabbit" 28 | bytes = "\x41Neato" 29 | strings: 30 | $a = "meta_bytes" 31 | condition: 32 | any of them 33 | } -------------------------------------------------------------------------------- /yara/yarascan/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /yara/yarascan/rules/fireeye.yar: -------------------------------------------------------------------------------- 1 | rule Trojan_Hastati 2 | { 3 | meta: 4 | author = "FireEye Researchers" 5 | alert = true 6 | log = true 7 | alert_severity = "HIGH" 8 | type = "Malware" 9 | description = "Yara signature to detect Korean DarkSeoul MBR wipr virus 20MAR2013." 10 | cve = "n/a" 11 | reference = "http://www.fireeye.com/blog/botnet-activities-outbreaks/2013/03/more-insights-on-the-recent-korean-cyber-attacks-trojan-hastati.html" 12 | source = "FireEye" 13 | weight = 100 14 | version = 1 15 | strings: 16 | $a = "taskkill /F /IM clisvc.exe" 17 | $b = "taskkill /F /IM pasvc.exe" 18 | $c = "shutdown -r -t 0" 19 | condition: 20 | all of them 21 | } 22 | -------------------------------------------------------------------------------- /yara/yarascan/rules/stoq.yar: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2015 PUNCH Cyber Analytics Group 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | include "./alienvault.yar" 18 | include "./fireeye.yar" 19 | -------------------------------------------------------------------------------- /yara/yarascan/yarascan.stoq: -------------------------------------------------------------------------------- 1 | # Copyright 2014-present PUNCH Cyber Analytics Group 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [Core] 16 | Name = yara 17 | Module = yarascan 18 | 19 | [Documentation] 20 | Author = Marcus LaFerrera 21 | Version = 3.0.3 22 | Website = https://github.com/PUNCH-Cyber/stoq-plugins-public 23 | Description = Process a payload using yara 24 | 25 | [options] 26 | # Worker rules file 27 | # worker_rules = rules/stoq.yar 28 | 29 | # Dispatcher rules file 30 | # dispatch_rules = rules/dispatcher.yar 31 | 32 | # Limit the strings results in yara matches 33 | # Default: None 34 | # strings_limit = 10 35 | 36 | # Time in seconds to wait for a yara scan to complete. 37 | # Default: 60 38 | # timeout = 60 39 | 40 | # Dispatcher returns first extracted XOR key as str (xorkey), not all keys as list of tuples (xor_info) 41 | # Default: True 42 | # xor_first_match = True 43 | --------------------------------------------------------------------------------