├── tests ├── requirements.txt ├── samples │ └── dadc624d4454e10293dbd1b701b9ee9f99ef83b4cd07b695111d37eb95abcff8 ├── test_signatures.py ├── test_cuckoo_task.py └── test_cuckoo_result.py ├── requirements.txt ├── .dockerignore ├── inetsim └── random_dns_patch │ ├── inetsim_patch.conf │ └── DNS.pm ├── Dockerfile ├── analyzer └── windows │ └── modules │ ├── auxiliary │ └── file_pickup.py │ └── packages │ └── dll_multi.py ├── .vscode └── settings.json ├── .gitignore ├── LICENCE.md ├── CONTRIBUTING.md ├── pipelines ├── azure-tests.yaml └── azure-build.yaml ├── al_config └── system_safelist.yaml ├── README.md ├── service_manifest.yml └── cuckoo ├── safe_process_tree_leaf_hashes.py └── signatures.py /tests/requirements.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | requests-mock 3 | pytest-mock 4 | -------------------------------------------------------------------------------- /tests/samples/dadc624d4454e10293dbd1b701b9ee9f99ef83b4cd07b695111d37eb95abcff8: -------------------------------------------------------------------------------- 1 | this is a text file -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | assemblyline-service-utilities 2 | pefile 3 | retrying 4 | SetSimilaritySearch 5 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | .idea 3 | .git 4 | 5 | pipelines 6 | venv 7 | env 8 | test 9 | tests 10 | exemples 11 | docs 12 | 13 | pip-log.txt 14 | pip-delete-this-directory.txt 15 | .tox 16 | .coverage 17 | .coverage.* 18 | .cache 19 | nosetests.xml 20 | coverage.xml 21 | *,cover 22 | *.log 23 | -------------------------------------------------------------------------------- /inetsim/random_dns_patch/inetsim_patch.conf: -------------------------------------------------------------------------------- 1 | ######################################### 2 | # dns_random_ip 3 | # 4 | # Random IPs for DNS 5 | # 6 | # Syntax: dns_random_ip [yes|no] 7 | # 8 | # Default: no 9 | # 10 | # dns_random_ip yes 11 | 12 | ######################################### 13 | # dns_random_range 14 | # 15 | # Range for random IPs for DNS 16 | # 17 | # Syntax: dns_random_range - 18 | # 19 | # Default: none 20 | # 21 | # dns_random_range 192.0.2.0-192.0.2.255 -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG branch=latest 2 | FROM cccs/assemblyline-v4-service-base:$branch 3 | 4 | ENV SERVICE_PATH cuckoo.cuckoo_main.Cuckoo 5 | 6 | USER root 7 | 8 | # Get required apt packages 9 | RUN apt-get update && apt-get install -y qemu-utils && rm -rf /var/lib/apt/lists/* 10 | 11 | # Switch to assemblyline user 12 | USER assemblyline 13 | 14 | # Install python dependencies 15 | COPY requirements.txt requirements.txt 16 | RUN pip install --no-cache-dir --user --requirement requirements.txt && rm -rf ~/.cache/pip 17 | 18 | # Copy Cuckoo service code 19 | WORKDIR /opt/al_service 20 | COPY . . 21 | 22 | # Patch version in manifest 23 | ARG version=4.0.0.dev1 24 | USER root 25 | RUN sed -i -e "s/\$SERVICE_TAG/$version/g" service_manifest.yml 26 | 27 | # Switch to assemblyline user 28 | USER assemblyline 29 | -------------------------------------------------------------------------------- /tests/test_signatures.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | class TestSignatures: 5 | @staticmethod 6 | @pytest.mark.parametrize( 7 | "sig, correct_int", 8 | [ 9 | ("blah", 9999), 10 | ("network_cnc_http", 22) 11 | ] 12 | ) 13 | def test_get_category_id(sig, correct_int): 14 | from cuckoo.signatures import get_category_id 15 | assert get_category_id(sig) == correct_int 16 | 17 | @staticmethod 18 | @pytest.mark.parametrize( 19 | "sig, correct_string", 20 | [ 21 | ("blah", "unknown"), 22 | ("network_cnc_http", "C2") 23 | ] 24 | ) 25 | def test_get_signature_category(sig, correct_string): 26 | from cuckoo.signatures import get_signature_category 27 | assert get_signature_category(sig) == correct_string 28 | -------------------------------------------------------------------------------- /analyzer/windows/modules/auxiliary/file_pickup.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | 4 | from lib.common.abstracts import Auxiliary 5 | from lib.common.exceptions import CuckooDisableModule, CuckooPackageError 6 | from lib.common.results import upload_to_host 7 | 8 | log = logging.getLogger(__name__) 9 | 10 | class FilePickup(Auxiliary): 11 | """In cases where you want to run something with 'free=yes' but know that a file will be generated, 12 | you can use this aux module to tell cuckoo to pick up the file""" 13 | 14 | def start(self): 15 | if not self.options.get("filepickup"): 16 | raise CuckooDisableModule 17 | 18 | self.file_to_get = self.options.get("filepickup") 19 | 20 | def stop(self): 21 | if hasattr(self, "file_to_get"): 22 | if self.file_to_get: 23 | log.info("uploading %s" % self.file_to_get) 24 | # We're using the 'supplementary' directory since that already has some special meaning within the 25 | # AssemblyLine Cuckoo service, and shouldn't matter if you're outside of AssemblyLine 26 | upload_to_host(self.file_to_get, os.path.join("supplementary", os.path.basename(self.file_to_get))) -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.organizeImports": true, 4 | }, 5 | "editor.formatOnSave": true, 6 | "editor.rulers": [ 7 | 120 8 | ], 9 | "editor.tabSize": 4, 10 | "editor.wordWrap": "wordWrapColumn", 11 | "editor.wordWrapColumn": 120, 12 | "files.insertFinalNewline": true, 13 | "files.trimFinalNewlines": true, 14 | "files.trimTrailingWhitespace": true, 15 | "isort.args": [ 16 | "-l", 17 | "120", 18 | "--profile=black", 19 | // "--src=${workspaceFolder}" 20 | ], 21 | "python.formatting.autopep8Args": [ 22 | "--max-line-length", 23 | "120", 24 | "--experimental" 25 | ], 26 | "python.formatting.provider": "autopep8", 27 | "python.formatting.blackArgs": [ 28 | "--line-length=120" 29 | ], 30 | "python.linting.enabled": true, 31 | "python.linting.flake8Enabled": true, 32 | "python.linting.flake8Args": [ 33 | "--max-line-length=120", 34 | //Added the ignore of E203 for now : https://github.com/PyCQA/pycodestyle/issues/373 35 | "--ignore=E203,W503" 36 | ], 37 | "python.linting.pylintEnabled": false, 38 | } 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # IDE files 10 | .pydevproject 11 | .python-version 12 | .idea 13 | 14 | # Distribution / packaging 15 | .Python 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | downloads/ 20 | eggs/ 21 | .eggs/ 22 | lib/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | wheels/ 28 | share/python-wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .nox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | *.py,cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | cover/ 58 | 59 | # Translations 60 | *.mo 61 | *.pot 62 | 63 | # PyBuilder 64 | .pybuilder/ 65 | target/ 66 | 67 | # Jupyter Notebook 68 | .ipynb_checkpoints 69 | 70 | # IPython 71 | profile_default/ 72 | ipython_config.py 73 | 74 | # Environments 75 | .env 76 | .venv 77 | env/ 78 | venv/ 79 | ENV/ 80 | env.bak/ 81 | venv.bak/ 82 | 83 | # Cython debug symbols 84 | cython_debug/ -------------------------------------------------------------------------------- /LICENCE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Crown Copyright, Government of Canada (Canadian Centre for Cyber Security / Communications Security Establishment) 4 | 5 | Copyright title to all 3rd party software distributed with Assemblyline (AL) is held by the respective copyright holders as noted in those files. Users are asked to read the 3rd Party Licenses referenced with those assets. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Assemblyline contributing guide 2 | 3 | This guide covers the basics of how to contribute to the Assemblyline project. 4 | 5 | Python code should follow the PEP8 guidelines defined here: [PEP8 Guidelines](https://www.python.org/dev/peps/pep-0008/). 6 | 7 | ## Tell us want you want to build/fix 8 | Before you start coding anything you should connect with the Assemblyline community via the [Assemblyline Discord server](https://discord.gg/GUAy9wErNu) and/or the [central Assemblyline GitHub project](https://github.com/CybercentreCanada/assemblyline/issues) to make sure no one else is working on the same thing and that whatever you are going to build still fits with the vision of the system. 9 | 10 | ## Git workflow 11 | 12 | - Clone the repo to your own account 13 | - Checkout and pull the latest commits from the master branch 14 | - Make a branch 15 | - Work in any way you like and make sure your changes actually work 16 | - When you're satisfied with your changes, create a pull requests to the main assemblyline repo 17 | 18 | #### Transfer your service repo 19 | If you've worked on a new service that you want to be included in the default service selection you'll have to transfer the repo into our control. 20 | 21 | #### You are not allowed to merge: 22 | 23 | Even if you try to merge in your pull request, you will be denied. Only a few people in our team are allowed to merge code into our repositories. 24 | 25 | We check for new pull requests every day and will merge them in once they have been approved by someone in our team. 26 | -------------------------------------------------------------------------------- /analyzer/windows/modules/packages/dll_multi.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2013 Claudio Guarnieri. 2 | # Copyright (C) 2014-2016 Cuckoo Foundation. 3 | # This file was originally part of Cuckoo Sandbox - http://www.cuckoosandbox.org (https://github.com/cuckoosandbox/cuckoo) 4 | # Copied and modified for use within AssemblyLine 5 | 6 | import os 7 | import shlex 8 | import shutil 9 | 10 | from lib.common.abstracts import Package 11 | 12 | class DllMulti(Package): 13 | """DLL analysis package, for attempting to execute multiple exports""" 14 | PATHS = [ 15 | ("System32", "rundll32.exe"), 16 | ] 17 | 18 | def start(self, path): 19 | rundll32 = self.get_path("rundll32.exe") 20 | functions = self.options.get("function", "DllMain").split("|") 21 | arguments = self.options.get("arguments", "") 22 | loader_name = self.options.get("loader") 23 | 24 | # Check file extension. 25 | ext = os.path.splitext(path)[-1].lower() 26 | 27 | # If the file doesn't have the proper .dll extension force it 28 | # and rename it. This is needed for rundll32 to execute correctly. 29 | # See ticket #354 for details. 30 | if ext != ".dll": 31 | new_path = path + ".dll" 32 | os.rename(path, new_path) 33 | path = new_path 34 | 35 | if loader_name: 36 | loader = os.path.join(os.path.dirname(rundll32), loader_name) 37 | shutil.copy(rundll32, loader) 38 | rundll32 = loader 39 | 40 | ret_list = [] 41 | for function_name in functions: 42 | args = ["%s,%s" % (path, function_name)] 43 | if arguments: 44 | args += shlex.split(arguments) 45 | 46 | ret_list.append(self.execute(rundll32, args=args)) 47 | 48 | return ret_list 49 | -------------------------------------------------------------------------------- /tests/test_cuckoo_task.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from cuckoo.cuckoo_main import ( 3 | CUCKOO_API_DELETE_TASK, 4 | CUCKOO_API_QUERY_MACHINES, 5 | CUCKOO_API_QUERY_PCAP, 6 | CUCKOO_API_QUERY_REPORT, 7 | CUCKOO_API_QUERY_TASK, 8 | CUCKOO_API_SUBMIT, 9 | ) 10 | from test_cuckoo_main import cuckoo_task_class, samples 11 | 12 | 13 | class TestCuckooTask: 14 | @staticmethod 15 | @pytest.mark.parametrize("sample", samples) 16 | def test_init(sample, cuckoo_task_class): 17 | kwargs = {"blah": "blah"} 18 | host_details = {"ip": "blah", "port": "blah", "auth_header": "blah"} 19 | cuckoo_task_class_instance = cuckoo_task_class(sample["filename"], host_details, **kwargs) 20 | assert cuckoo_task_class_instance.file == sample["filename"] 21 | assert cuckoo_task_class_instance.id is None 22 | assert cuckoo_task_class_instance.report is None 23 | assert cuckoo_task_class_instance.errors == [] 24 | assert cuckoo_task_class_instance == {"blah": "blah"} 25 | assert cuckoo_task_class_instance.base_url == f"http://{host_details['ip']}:{host_details['port']}" 26 | assert cuckoo_task_class_instance.submit_url == f"{cuckoo_task_class_instance.base_url}/{CUCKOO_API_SUBMIT}" 27 | assert cuckoo_task_class_instance.query_task_url == f"{cuckoo_task_class_instance.base_url}/{CUCKOO_API_QUERY_TASK}" 28 | assert cuckoo_task_class_instance.delete_task_url == f"{cuckoo_task_class_instance.base_url}/{CUCKOO_API_DELETE_TASK}" 29 | assert cuckoo_task_class_instance.query_report_url == f"{cuckoo_task_class_instance.base_url}/{CUCKOO_API_QUERY_REPORT}" 30 | assert cuckoo_task_class_instance.query_pcap_url == f"{cuckoo_task_class_instance.base_url}/{CUCKOO_API_QUERY_PCAP}" 31 | assert cuckoo_task_class_instance.query_machines_url == f"{cuckoo_task_class_instance.base_url}/{CUCKOO_API_QUERY_MACHINES}" 32 | -------------------------------------------------------------------------------- /pipelines/azure-tests.yaml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | variables: 4 | - group: unittest-samples 5 | - name: self_location 6 | value: "self_location" 7 | - name: full_self_location 8 | value: "$(Agent.BuildDirectory)/$(self_location)" 9 | - name: samples_location 10 | value: "samples_location" 11 | - name: full_samples_location 12 | value: "$(Agent.BuildDirectory)/$(samples_location)" 13 | 14 | resources: 15 | repositories: 16 | - repository: unittest-samples 17 | type: github 18 | name: $(unittest_samples_repository) 19 | ref: main 20 | endpoint: github-repo-sa 21 | trigger: none 22 | 23 | trigger: ["*"] 24 | pr: ["*"] 25 | 26 | pool: 27 | vmImage: "ubuntu-20.04" 28 | 29 | jobs: 30 | - job: run_test 31 | strategy: 32 | matrix: 33 | Python3_9: 34 | python.version: "3.9" 35 | #Python3_10: 36 | # python.version: "3.10" 37 | #Python3_11: 38 | # python.version: "3.11" 39 | 40 | timeoutInMinutes: 10 41 | 42 | steps: 43 | - task: UsePythonVersion@0 44 | displayName: Set python version 45 | inputs: 46 | versionSpec: "$(python.version)" 47 | - checkout: self 48 | fetchDepth: 1 49 | path: $(self_location) 50 | - checkout: unittest-samples 51 | fetchDepth: 1 52 | path: $(samples_location) 53 | - script: | 54 | [ ! -d "$(pwd)/tests" ] && echo "No tests found" && exit 55 | sudo apt-get update 56 | sudo apt-get install -y libfuzzy-dev libfuzzy2 57 | if [[ -f "$(pwd)/pkglist.txt" ]]; then 58 | grep -vE '^#' "$(pwd)/pkglist.txt" | xargs sudo apt install -y 59 | fi 60 | sudo rm -rf /var/lib/apt/lists/* 61 | sudo env "PATH=$PATH" python -m pip install -U --no-cache-dir assemblyline assemblyline_v4_service 62 | [ -f $(pwd)/requirements.txt ] && sudo env "PATH=$PATH" python -m pip install -U --no-cache-dir -r $(pwd)/requirements.txt 63 | [ -f $(pwd)/tests/requirements.txt ] && sudo env "PATH=$PATH" python -m pip install -U --no-cache-dir -r $(pwd)/tests/requirements.txt 64 | sudo rm -rf /tmp/* /var/lib/apt/lists/* ~/.cache/pip 65 | workingDirectory: $(full_self_location) 66 | displayName: Setup environment 67 | - script: | 68 | [ ! -d "$(pwd)/tests" ] && echo "No tests found" && exit 69 | export REPO_NAME=${BUILD_REPOSITORY_NAME##*/} 70 | python -m pytest -p no:cacheprovider --durations=10 -rsx -xsvvv --disable-warnings 71 | workingDirectory: $(full_self_location) 72 | displayName: Test 73 | -------------------------------------------------------------------------------- /pipelines/azure-build.yaml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | variables: 4 | - group: unittest-samples 5 | - name: self_location 6 | value: "self_location" 7 | - name: full_self_location 8 | value: "$(Agent.BuildDirectory)/$(self_location)" 9 | - name: samples_location 10 | value: "samples_location" 11 | - name: full_samples_location 12 | value: "$(Agent.BuildDirectory)/$(samples_location)" 13 | 14 | resources: 15 | repositories: 16 | - repository: unittest-samples 17 | type: github 18 | name: $(unittest_samples_repository) 19 | ref: main 20 | endpoint: github-repo-sa 21 | trigger: none 22 | 23 | trigger: 24 | tags: 25 | include: ["v*"] 26 | pr: none 27 | 28 | pool: 29 | vmImage: "ubuntu-20.04" 30 | 31 | stages: 32 | - stage: deploy 33 | jobs: 34 | - job: deploy 35 | displayName: Deploy containers to dockerhub 36 | variables: 37 | - group: deployment-information 38 | steps: 39 | - task: Docker@2 40 | displayName: Login to docker hub 41 | inputs: 42 | command: login 43 | containerRegistry: dockerhub 44 | - task: Docker@2 45 | displayName: Login to chimera 46 | inputs: 47 | command: login 48 | containerRegistry: CHIMERA-U-ACR 49 | - checkout: self 50 | fetchDepth: 1 51 | path: $(self_location) 52 | - checkout: unittest-samples 53 | fetchDepth: 1 54 | path: $(samples_location) 55 | - script: | 56 | export TAG=${BUILD_SOURCEBRANCH#"refs/tags/v"} 57 | if [[ "$TAG" == *stable* ]]; then export BUILD_TYPE=stable; else export BUILD_TYPE=latest; fi 58 | docker build --build-arg version=$TAG --build-arg branch=$BUILD_TYPE -t cccs/${BUILD_REPOSITORY_NAME##*/}:$TAG -t cccs/${BUILD_REPOSITORY_NAME##*/}:$BUILD_TYPE -f ./Dockerfile . 59 | workingDirectory: $(full_self_location) 60 | displayName: Build containers 61 | - script: | 62 | [ ! -d "$(pwd)/tests" ] && echo "No tests found" && exit 63 | export TAG=${BUILD_SOURCEBRANCH#"refs/tags/v"} 64 | if [[ "$TAG" == *stable* ]]; then export BUILD_TYPE=stable; else export BUILD_TYPE=latest; fi 65 | [ -f "$(pwd)/tests/requirements.txt" ] && docker run -e FULL_SELF_LOCATION=/opt/al_service -e FULL_SAMPLES_LOCATION=/opt/samples -v /usr/share/ca-certificates/mozilla:/usr/share/ca-certificates/mozilla -v $(pwd)/tests/:/opt/al_service/tests/ -v ${FULL_SAMPLES_LOCATION}:/opt/samples cccs/${BUILD_REPOSITORY_NAME##*/}:$BUILD_TYPE bash -c 'pip install -U -r tests/requirements.txt; pytest -p no:cacheprovider -xsvvv' && exit 66 | docker run -e FULL_SELF_LOCATION=/opt/al_service -e FULL_SAMPLES_LOCATION=/opt/samples -v /usr/share/ca-certificates/mozilla:/usr/share/ca-certificates/mozilla -v $(pwd)/tests/:/opt/al_service/tests/ -v ${FULL_SAMPLES_LOCATION}:/opt/samples cccs/${BUILD_REPOSITORY_NAME##*/}:$BUILD_TYPE bash -c 'pytest -p no:cacheprovider -xsvvv' 67 | workingDirectory: $(full_self_location) 68 | displayName: Test containers 69 | - script: | 70 | export TAG=${BUILD_SOURCEBRANCH#"refs/tags/v"} 71 | if [[ "$TAG" == *stable* ]]; then export BUILD_TYPE=stable; else export BUILD_TYPE=latest; fi 72 | export SERIES="`expr $TAG : '\([0-9]\+\.[0-9]\+\.\)'`${BUILD_TYPE}" 73 | 74 | for IMAGE in "cccs/" "uchimera.azurecr.io/cccs/" 75 | do 76 | docker tag cccs/${BUILD_REPOSITORY_NAME##*/}:$BUILD_TYPE ${IMAGE}${BUILD_REPOSITORY_NAME##*/}:$TAG 77 | docker tag cccs/${BUILD_REPOSITORY_NAME##*/}:$BUILD_TYPE ${IMAGE}${BUILD_REPOSITORY_NAME##*/}:$BUILD_TYPE 78 | docker tag cccs/${BUILD_REPOSITORY_NAME##*/}:$BUILD_TYPE ${IMAGE}${BUILD_REPOSITORY_NAME##*/}:$SERIES 79 | docker push ${IMAGE}${BUILD_REPOSITORY_NAME##*/} --all-tags 80 | done 81 | displayName: Deploy to container repositories 82 | -------------------------------------------------------------------------------- /al_config/system_safelist.yaml: -------------------------------------------------------------------------------- 1 | match: 2 | file.path: 3 | - SharedDataEvents 4 | - SharedDataEvents-journal 5 | - AcroFnt09.lst 6 | - AdobeSysFnt09.lst 7 | - AdobeCMapFnt09.lst 8 | - ACECache10.lst 9 | - UserCache.bin 10 | - desktop.ini 11 | - sRGB Color Space Profile.icm 12 | - is330.icm 13 | - kodak_dc.icm 14 | - R000000000007.clb 15 | - JSByteCodeWin.bin 16 | # adobe plugins 17 | - Accessibility.api 18 | - AcroForm.api 19 | - Annots.api 20 | - Checker.api 21 | - DigSig.api 22 | - DVA.api 23 | - eBook.api 24 | - EScript.api 25 | - HLS.api 26 | - IA32.api 27 | - MakeAccessible.api 28 | - Multimedia.api 29 | - PDDom.api 30 | - PPKLite.api 31 | - ReadOutLoad.api 32 | - reflow.api 33 | - SaveAsRTF.api 34 | - Search5.api 35 | - Search.api 36 | - SendMail.api 37 | - Spelling.api 38 | - Updater.api 39 | - weblink.api 40 | - ADMPlugin.apl 41 | # adobe annotations 42 | - Words.pdf 43 | - Dynamic.pdf 44 | - SignHere.pdf 45 | - StandardBusiness.pdf 46 | # adobe templates 47 | - AdobeID.pdf 48 | - DefaultID.pdf 49 | # adobe fonts 50 | - AdobePiStd.otf 51 | - CourierStd.otf 52 | - CourierStd-Bold.otf 53 | - CourierStd-BoldOblique.otf 54 | - CourierStd-Oblique.otf 55 | - MinionPro-Bold.otf 56 | - MinionPro-BoldIt.otf 57 | - MinionPro-It.otf 58 | - MinionPro-Regular.otf 59 | - MyriadPro-Bold.otf 60 | - MyriadPro-BoldIt.otf 61 | - MyriadPro-It.otf 62 | - MyriadPro-Regular.otf 63 | - SY______.PFB 64 | - ZX______.PFB 65 | - ZY______.PFB 66 | - SY______.PFM 67 | - zx______.pfm 68 | - zy______.pfm 69 | # adobe cmap 70 | - Identity-H 71 | - Identity-V 72 | # Winword 73 | - msointl.dll 74 | - Normal.dot 75 | - ~$Normal.dotm 76 | - wwintl.dll 77 | - Word11.pip 78 | - Word12.pip 79 | - shell32.dll 80 | - oleacc.dll 81 | # IE 82 | - index.dat 83 | regex: 84 | dynamic.process.file_name: 85 | # Cuckoo 86 | - C:\\tmp.+\\bin\\.+ 87 | - C:\\Windows\\System32\\lsass\.exe 88 | - lsass\.exe 89 | # Office 90 | - C:\\Program Files\\Common Files\\Microsoft Shared\\OfficeSoftwareProtectionPlatform\\OSPPSVC\.exe 91 | # Sysmon 92 | - C:\\Windows\\System32\\csrss\.exe 93 | - C:\\Windows\\System32\\SearchIndexer\.exe 94 | - C:\\Windows\\SMaster(32|64).exe 95 | # Azure 96 | - C:\\Program Files\\Microsoft Monitoring Agent\\Agent\\(MonitoringHost\.exe|Health Service State\\ICT 2\\(CMF-64|CMF)\\DesiredStateConfiguration\\DscRun\.exe) 97 | - C:\\WindowsAzure\\GuestAgent.*\\(GuestAgent\\WindowsAzureGuestAgent\.exe|WaAppAgent\.exe|CollectGuestLogs\.exe) 98 | # Flash 99 | - C:\\windows\\SysWOW64\\Macromed\\Flash\\FlashPlayerUpdateService\.exe 100 | dynamic.process.command_line: 101 | # Cuckoo 102 | - C:\\Python27\\pythonw\.exe C:/tmp.+/analyzer\.py 103 | # Azure 104 | - \"C:\\Program Files\\Microsoft Monitoring Agent\\Agent\\MonitoringHost\.exe\" -Embedding 105 | - \"C:\\Program Files\\Microsoft Monitoring Agent\\Agent\\MOMPerfSnapshotHelper\.exe\\\" -Embedding 106 | - \"C:\\windows\\system32\\cscript\.exe\" /nologo ("MonitorKnowledgeDiscovery\.vbs"|"ChangeEventModuleBatchSize\.vbs) 107 | # Windows 108 | - C:\\windows\\system32\\(SppExtComObj|mobsync)\.exe -Embedding 109 | - C:\\windows\\system32\\wbem\\wmiprvse\.exe -secured -Embedding 110 | - (C:\\Windows\\)?explorer\.exe 111 | - \"C:\\Windows\\explorer\.exe\" /LOADSAVEDWINDOWS 112 | - wmiadap\.exe (/F /T /R|/D /T) 113 | - C:\\windows\\system32\\(sppsvc|wuauclt|appidpolicyconverter|appidcertstorecheck)\.exe 114 | - \"C:\\Windows\\SystemApps\\(ShellExperienceHost|Microsoft\.Windows\.Cortana)_.*\\(ShellExperienceHost|SearchUI)\.exe\" -ServerName:(App|CortanaUI)\.App.*\.mca 115 | - C:\\Windows\\system32\\dllhost\.exe /Processid:.* 116 | - C:\\Windows\\system32\\wbem\\WmiApSrv\.exe 117 | - C:\\Windows\\system32\\sc\.exe start wuauserv 118 | - \"C:\\windows\\system32\\SearchProtocolHost\.exe\" Global\\UsGthrFltPipeMssGthrPipe_S-1-5-21-451555073-2684619755-382164121-5006_ Global\\UsGthrCtrlFltPipeMssGthrPipe_S-1-5-21-451555073-2684619755-382164121-5006 1 -2147483646 "Software\\Microsoft\\Windows Search" "Mozilla/4\.0 (compatible; MSIE 6\.0; Windows NT; MS Search 4\.0 Robot)" "C:\\ProgramData\\Microsoft\\Search\\Data\\Temp\\usgthrsvc" "DownLevelDaemon" "1" 119 | - taskhost\.exe \$\(Arg0\) 120 | # If an error is raised, WerFault will pop up and WerMgr will try to upload it 121 | - C:\\Windows\\system32\\WerFault\.exe (-u -p [0-9]{3,5} -s [0-9]{3,5}|-pss -s [0-9]{3,5} -p [0-9]{3,5} -ip [0-9]{3,5}) 122 | - C:\\Windows\\system32\\wermgr\.exe -upload 123 | # NET 124 | - C:\\Windows\\Microsoft\.NET\\Framework64\\v.*\\mscorsvw\.exe -StartupEvent [0-9]{3} -InterruptEvent [0-9] -NGENProcess [0-9]{2}[a-z} -Pipe [0-9]{3} -Comment "NGen Worker Process" 125 | # Sysmon 126 | - \\\?\?\\C:\\Windows\\system32\\conhost\.exe 127 | - \\\?\?\\C:\\Windows\\system32\\conhost\.exe ".*" 128 | - \\\?\?\\C:\\Windows\\system32\\conhost\.exe 0xffffffff -ForceV1 129 | - C:\\windows\\system32\\svchost\.exe -k (DcomLaunch|NetworkService|UnistackSvcGroup|WerSvcGroup|netsvcs -p -s (Schedule|Winmgmt|UsoSvc)) 130 | - C:\\windows\\system32\\SearchIndexer\.exe \/Embedding 131 | - C:\\Windows\\System32\\wevtutil\.exe query-events microsoft-windows-powershell/operational /rd:true /e:root /format:xml /uni:true 132 | - C:\\Windows\\System32\\wevtutil\.exe query-events microsoft-windows-sysmon/operational /format:xml /e:Events 133 | - C:\\Windows\\system32\\AUDIODG\.EXE 0x6e8 134 | network.dynamic.domain: 135 | # Adobe 136 | - .+\.adobe\.com$ 137 | - files\.acrobat\.com$ 138 | # Google 139 | - play\.google\.com$ 140 | # Android 141 | - .*\.android\.pool\.ntp\.org$ 142 | - android\.googlesource\.com$ 143 | - schemas\.android\.com$ 144 | # XML 145 | - xmlpull\.org$ 146 | - schemas\.openxmlformats\.org$ 147 | # Akamai 148 | - img-s-msn-com\.akamaized\.net$ 149 | - fbstatic-a\.akamaihd\.net$ 150 | # ASPNet 151 | - ajax\.aspnetcdn\.com$ 152 | # WWW 153 | - (www\.)?w3\.org$ 154 | # Omniroot 155 | - ocsp\.omniroot\.com$ 156 | # WPAD 157 | - ^wpad\..*$ 158 | # Microsoft 159 | - schemas\.microsoft\.com$ 160 | - .*\.?teredo\.ipv6\.microsoft\.com$ 161 | - watson\.microsoft\.com$ 162 | - dns\.msftncsi\.com$ 163 | - www\.msftncsi\.com$ 164 | - ipv6\.msftncsi\.com$ 165 | - crl\.microsoft\.com$ 166 | - (www|go)\.microsoft\.com$ 167 | - isatap\..*\.microsoft\.com$ 168 | - tile-service\.weather\.microsoft\.com$ 169 | - .*\.prod\.do\.dsp\.mp\.microsoft\.com$ 170 | - (login|g)\.live\.com$ 171 | - nexus\.officeapps\.live\.com$ 172 | - .*\.events\.data\.microsoft\.com$ 173 | - wdcp\.microsoft\.com$ 174 | - fe3(cr)?\.delivery\.mp\.microsoft\.com$ 175 | - client\.wns\.windows\.com$ 176 | - (www\.)?go\.microsoft\.com$ 177 | - js\.microsoft\.com$ 178 | - ajax\.microsoft\.com$ 179 | - ieonline\.microsoft\.com$ 180 | - dns\.msftncsi\.com$ 181 | - ocsp\.msocsp\.com$ 182 | - fs\.microsoft\.com$ 183 | - www\.msftconnecttest\.com$ 184 | - www\.msftncsi\.com$ 185 | - iecvlist\.microsoft\.com$ 186 | - r20swj13mr\.microsoft\.com$ 187 | - (([a-z]-ring(-fallback)?)|(fp)|(segments-[a-z]))\.msedge\.net$ 188 | - displaycatalog(\.md)?\.mp\.microsoft\.com$ 189 | - officeclient\.microsoft\.com$ 190 | - ow1\.res\.office365\.com$ 191 | - fp-(as-nocache|vp)\.azureedge\.net$ 192 | - outlookmobile-office365-tas\.msedge\.net$ 193 | - config\.messenger\.msn\.com$ 194 | - microsoftwindows\.client\.cbs$ 195 | # Windows 196 | - settings(-win)?\.data\.microsoft\.com$ 197 | - .*vortex-win\.data\.microsoft\.com$ 198 | - .*\.windowsupdate\.com$ 199 | - time\.(microsoft|windows)\.com$ 200 | - .*\.windows\.com$ 201 | - .*\.update\.microsoft\.com$ 202 | - .*download\.microsoft\.com$ 203 | - kms\.core\.windows\.net$ 204 | - .*windows\.microsoft\.com$ 205 | - win10\.ipv6\.microsoft\.com$ 206 | - activation-v2\.sls\.microsoft\.com$ 207 | - msedge\.api\.cdp\.microsoft\.com$ 208 | # MSN 209 | - cdn\.content\.prod\.cms\.msn\.com$ 210 | - ((www|arc)\.)?msn\.com$ 211 | - (www\.)?static-hp-eas\.s-msn\.com$ 212 | - img\.s-msn\.com$ 213 | # Bing 214 | - ((api|www|platform)\.)?bing\.com$ 215 | # Azure 216 | - md-ssd-.*\.blob\.core\.windows\.net$ 217 | - .*\.table\.core\.windows\.net 218 | - .*\.blob\.core\.windows\.net 219 | - .*\.opinsights\.azure\.com 220 | - .*reddog\.microsoft\.com$ 221 | - agentserviceapi\.azure-automation\.net$ 222 | - agentserviceapi\.guestconfiguration\.azure\.com$ 223 | - .*\.blob\.storage\.azure\.net$ 224 | # Office 225 | - config\.edge\.skype\.com 226 | - cdn\.onenote\.net$ 227 | # Verisign 228 | - (www\.)?verisign\.com$ 229 | - csc3-2010-crl\.verisign\.com$ 230 | - csc3-2010-aia\.verisign\.com$ 231 | - ocsp\.verisign\.com$ 232 | - logo\.verisign\.com$ 233 | - crl\.verisign\.com$ 234 | # Ubuntu 235 | - (changelogs|daisy|ntp|ddebs|security)\.ubuntu\.com$ 236 | - (azure|ca)\.archive\.ubuntu\.com$ 237 | # Local 238 | - .*\.local$ 239 | - local$ 240 | - localhost$ 241 | # Comodo 242 | - .*\.comodoca\.com$ 243 | # .arpa 244 | - ^[0-9a-f\.]+\.ip6\.arpa$ 245 | - ^[0-9\.]+\.in-addr\.arpa$ 246 | # Oracle 247 | - (www\.)?java\.com$ 248 | - sldc-esd\.oracle\.com$ 249 | - javadl\.sun\.com$ 250 | # Digicert 251 | - ocsp\.digicert\.com$ 252 | - crl[0-9]\.digicert\.com$ 253 | # Symantec 254 | - s[a-z0-9]?\.symc[bd]\.com$ 255 | - (evcs|ts)-(ocsp|crl)\.ws\.symantec\.com$ 256 | # Thawte 257 | - ocsp\.thawte\.com$ 258 | # GlobalSign 259 | - ocsp[0-9]?\.globalsign\.com$ 260 | - crl\.globalsign\.(com|net)$ 261 | # Google 262 | - google\.com$ 263 | # INetSim 264 | - (www\.)?inetsim\.org$ 265 | network.dynamic.ip: 266 | # Public DNS 267 | - (^1\.1\.1\.1$)|(^8\.8\.8\.8$) 268 | # Local 269 | - (?:127\.|10\.|192\.168|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[01]\.).* 270 | - 255\.255\.255\.255 271 | # Honeynet 272 | - 169\.169\.169\.169 273 | # Windows 274 | - 239\.255\.255\.250 275 | - 224\..* 276 | # Azure 277 | - 169\.254\.169\.254 278 | - 168\.63\.129\.16 279 | network.dynamic.uri: 280 | # Local 281 | - (?:ftp|http)s?://localhost(?:$|/.*) 282 | - (?:ftp|http)s?://(?:(?:(?:10|127)(?:\.(?:[2](?:[0-5][0-5]|[01234][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9])){3})|(?:172\.(?:1[6-9]|2[0-9]|3[0-1])(?:\.(?:2[0-4][0-9]|25[0-5]|[1][0-9][0-9]|[1-9][0-9]|[0-9])){2}|(?:192\.168(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){2})))(?:$|/.*) 283 | # Android 284 | - https?://schemas\.android\.com/apk/res(-auto|/android) 285 | - https?://android\.googlesource\.com/toolchain/llvm-project 286 | # Azure 287 | - https?://wpad\..*/wpad\.dat 288 | # Google 289 | - https?://www\.google\.com 290 | network.dynamic.uri_path: 291 | # Adobe 292 | - \/11\/rdr\/enu\/win\/nooem\/none\/message\.zip 293 | file.path: 294 | # Office 295 | - (?:[a-f0-9]{2}|\~\$)[a-f0-9]{62}\.(doc|xls|ppt)x?$ 296 | - \\~[A-Z]{3}{[A-F0-9]{8}\-([A-F0-9]{4}\-){3}[A-F0-9]{12}\}\.tmp$ 297 | - \\Microsoft\\OFFICE\\DATA\\[a-z0-9]+\.dat$ 298 | - AppData\\Local\\Microsoft\\Windows\\Temporary Internet Files\\Content.Word\\~WRS 299 | - .*\\Temp\\~\$[a-z0-9]+\.doc 300 | - \\Microsoft\\Document Building Blocks\\[0-9]{4}\\ 301 | - AppData\\Roaming\\MicrosoftOffice\\.*\.acl$ 302 | - AppData\\Roaming\\Microsoft\\UProof\\CUSTOM.DIC$ 303 | - .*AppData\\Roaming\\Microsoft\\Proof\\\~\$CUSTOM.DIC$ 304 | - AppData\\Local\\Temp\\Word...\\MSForms.exd$' 305 | # Meta Font 306 | - \[A-F0-9\]{7,8}\.(w|e)mf$ 307 | # IE 308 | - RecoveryStore\.([A-F0-9]{8}\-([A-F0-9]{4}\-){3}[A-F0-9]{12})\.dat$ 309 | - ([A-F0-9]{8}\-([A-F0-9]{4}\-){3}[A-F0-9]{12})\.dat$ 310 | - AppData\\Local\\Microsoft\\Windows\\Temporary Internet Files\\Content.MSO\\ 311 | # CryptnetCache 312 | - AppData\\[^\\]+\\MicrosoftCryptnetUrlCache\\ 313 | # Cab File 314 | - \\Temp\\Cab....\.tmp 315 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cuckoo Service 2 | 3 | ***THIS SERVICE IS DEPRECATED SINCE THE CUCKOO PROJECT IS DEAD*** 4 | 5 | ***USE THE [CAPE SERVICE](https://github.com/CybercentreCanada/assemblyline-service-cape) INSTEAD*** 6 | 7 | This Assemblyline service interfaces with the open-source project [Cuckoo Sandbox](https://cuckoosandbox.org), which provides the ability to perform live dynamic analysis on submitted files. 8 | 9 | **NOTE**: This service **requires extensive additional installation outside of Assemblyline** before being functional. It is **not** preinstalled during a default installation. 10 | 11 | ## Cuckoo Sandbox Overview 12 | 13 | Cuckoo Sandbox is an open-source software for automating analysis of suspicious files. To do so it makes use of custom components 14 | that monitor the behaviour of the malicious processes while running in an isolated environment. 15 | 16 | It can retrieve the following type of results: 17 | 18 | * Traces of calls performed by all processes spawned by the malware. 19 | * Files being created, deleted and downloaded by the malware during its execution. 20 | * Memory dumps of the malware processes. 21 | * Network traffic trace in PCAP format. 22 | * Screenshots taken during the execution of the malware. 23 | * Full memory dumps of the machines. 24 | 25 | Cuckoo Sandbox supports instrumenting Windows, Linux, Macintosh, and 26 | Android virtual machines. 27 | 28 | ## Assemblyline's Cuckoo Service Overview 29 | The Cuckoo service uses the Cuckoo REST API to send files to the Cuckoo nest which then hands out these tasks to a pool of victim machines (one file per victim). 30 | **You are responsible for setting up the Cuckoo nest and victims**. The analysis results for the detonation of a submitted file in a victim is then retrieved, 31 | and a summarized version of the report is displayed to the user through the Assemblyline UI. The full report is also included in the Assemblyline UI as a supplementary file for your reading pleasure. 32 | Files that are unpacked and saved to disk are fed back into Assemblyline. 33 | 34 | ### Service Options 35 | #### Host Configurations 36 | * **remote_host_details**: A list of JSON objects, where each JSON object represents a Cuckoo Host. Details regarding the Cuckoo API can be found [here](https://cuckoo.readthedocs.io/en/latest/usage/api/). Each JSON object must have the following keys and values: 37 | * **ip** - [default: 127.0.0.1] The IP address of the machine where the Cuckoo API is being served 38 | * **port** - [default: 8090] The port where the Cuckoo API is being served 39 | * **api_key** - [default: sample_api_token] The authentication token to be passed with each API call 40 | * **connection_timeout_in_seconds** - [default: 30] The timeout used to make the initial query to a host. (GET /machines/list) 41 | * **rest_timeout_in_seconds** - [default: 120] The timeout used to make subsequent queries to a host. (GET /cuckoo/status, POST /tasks/create/file, GET /tasks/view/123, GET /tasks/report/123, DELETE /tasks/delete/123, etc.) 42 | * **connection_attempts** - [default: 3] The number of attempts to connect (perform a GET /machines/list) to a host. 43 | 44 | #### Victim configurations 45 | * **allowed_images**: A list of strings representing the images that can be selected for detonation. 46 | * **auto_architecture**: A JSON object consisting of the following structure: 47 | ``` 48 | win: 49 | x64: [] 50 | x86: [] 51 | ub: 52 | x64: [] 53 | x86: [] 54 | ``` 55 | This is only relevant if you are using the `auto` value for the `specific_image` submission parameter. 56 | 57 | If you have multiple images that a sample can be sent to for detonation based on type (for example Win7x64, Win10x64, Win7x86, Win10x86, WinXP, and Win7x64WithOffice), but you only want a sample to be sent to a set of those images (for example, Win7x64 and Win10x64), then you can specify those images here. 58 | 59 | The method for interpretting this structure is that files are divided between Linux (ub) and Windows (win), as well as what processor they must be ran on (x86 or x64). If a file matches these conditions, it will be sent to all of the images specified in corresponding list. If a file does not match any of these conditions, the default list is the win + x64. 60 | 61 | #### Analysis Configurations 62 | * **max_file_size** - [default: 80000000] The maximum size of an extracted file, in bytes. 63 | * **default_analysis_timeout_in_seconds** - [default: 150] The maximum timeout for an analysis. 64 | * **max_dll_exports_exec** - [default: 5] Limiting the amount of DLLs executed that we report about. 65 | **NB** : this functionality relies on placing the package found in this repo at `analyzer/windows/modules/packages/dll_multi.py` in the Cuckoo nest at `$CWD/analyzer/windows/modules/packages/dll_multi.py` 66 | * **machinery_supports_memory_dumps** - [default: False] A boolean flag indicating if the Cuckoo machinery supports dumping memory. 67 | * **reboot_supported** - [default: False] A boolean flag indicating if the Cuckoo machinery supports reboot submissions. 68 | * **uses_https_proxy_in_sandbox** - [default: False] A boolean flag indicating if the sandbox architecture uses an HTTPS proxy to decrypt and forward traffic. 69 | 70 | #### Reporting Configurations 71 | * **recursion_limit** - [default: 10000] The recursion limit of the Python environment where the service is being run. This is used to traverse large JSONs generated from analysis. 72 | * **max_report_size** - [default: 275000000] Limiting the size that the service will accept from Cuckoo when asking for a report file, in bytes. 73 | 74 | #### INetSim specifications 75 | * **random_ip_range** - [default: 192.0.2.0/24] This is the IP range that INetSim (if configured) will pick from in order to return a random IP for any DNS request that the victims make (note that this requires a patch to INetSim). This option is mainly for safelisting. 76 | **NB** : this functionality relies on the "INetSim - Random DNS Resolution" section below. 77 | 78 | #### Assemblyline service specifications 79 | * **dedup_similar_percent** - [default: 40] SSDeep attempts to match hashes, and this is the threshold percentage for matching. 80 | 81 | ### Cuckoo Submission Options 82 | 83 | The following options are available for submissions to the Cuckoo service ([official documentation](https://cuckoo.readthedocs.io/en/latest/usage/api/#tasks-create-file)): 84 | 85 | * **analysis_timeout_in_seconds** - [default: 0] Maximum amount of time to wait for analysis to complete. NB: The analysis job may complete faster 86 | than this if the process being monitored exits. If the value is 0, then the analysis will default to use the value of the service parameter `default_analysis_timeout_in_seconds`. 87 | * **specific_image** - [default: [auto, auto_all, all]] List of available images and options to send the file to (selected option is attached as tag to the task). 88 | * In terms of selecting a victim for detonation, this option has the third highest priority, but is the most popular with analysts. 89 | * This list should contain all available images, as well as the three options `auto`, `auto_all` and `all`: 90 | * `auto` will automatically select the image(s) that a file will be detonated on, determined by its file type. If you have a lot of images that a file can be detonated on, use the `auto_architecture` service parameter to be more specific. 91 | * `auto_all` will ignore the `auto_architecture` service parameter, and will send the file to all images that can detonate the file type. 92 | * `all` will send the file to all images in `allowed_images`. 93 | * **dll_function** - [default: ""] Specify the DLL function to run on the DLL. 94 | * **dump_memory** - [default: false] A boolean value indicating whether we want the memory dumped from the analysis and run volatility plugins on it. *NB*: This is very slow! 95 | * **force_sleepskip** - [default: true] Forces a sample that attempts to sleep to wake up and skip the attempted sleep. 96 | * **no_monitor** - [default: false] Run analysis without injecting the Cuckoo monitoring agent. Equivalent to passing `--options free=yes` (see [here](https://cuckoo.sh/docs/usage/packages.html) for more information). Note that running the Cuckoo monitor on Windows 10 images has the tendency to crash analysis. 97 | * **simulate_user** - [default: true] Enables user simulation 98 | * **sysmon_enabled** - [default: true] Enables the Sysmon auxiliary module: [PR](https://github.com/cuckoosandbox/cuckoo/pull/2518) 99 | * **take_screenshots** - [default: false] Enables screenshots to be taken every second. 100 | * **reboot** - [default: false] a boolean indicating if we want an analysis to be repeated but in a simulated "rebooted" environment. *NB*: This is a development option, as users can select it without understanding what it is for and then double processing time. 101 | * **arguments** - [default: ""] command line arguments to pass to the sample being analyzed 102 | * **custom_options** - [default: ""] Custom options to pass to the cuckoo submission. Same as the `--options` command line option [here](https://cuckoo.sh/docs/usage/submit.html) 103 | * **clock** - [default: ""] Set virtual machine clock (format %m-%d-%Y %H:%M:%S). 104 | * **package** - [default: ""] The name of the analysis package to run the sample with, with out-of-the-box options found [here](https://cuckoo.readthedocs.io/en/latest/usage/packages/). 105 | * **specific_machine** - [default: ""] The name of the machine that you want to run the sample on. 106 | *NB* Used for development, when you want to send a file to a specific machine on a specific host. String format is ":" if more than one host exists. If only one host exists, then format can be either ":" or "". 107 | * This has the highest precendence for victim selection when submitting a file. 108 | * **max_total_size_of_uploaded_files** - [default: 134217728] Limit of bytes of total files uploaded per analysis, based on [PR](https://github.com/cuckoosandbox/cuckoo/pull/3169) 109 | * **platform** - [default: "none"] If you don't care about the version of the operating system that you get, as long as it matches the platform, use this. 110 | * This has the second-highest precedence for victim selection when submitting a file. 111 | * **routing** - [default: "none"] Specify the type of routing to be used on a per-analysis basis. 112 | 113 | ### Deployment of Cuckoo Nest 114 | 115 | See the official documentation: https://cuckoo.readthedocs.io/en/latest/installation/ 116 | 117 | ### Deployment of Cuckoo Victim 118 | 119 | See the official documentation: https://cuckoo.readthedocs.io/en/latest/installation/guest/ 120 | 121 | ### Using Community Signatures 122 | As per the official documentation, `cuckoo community` can be run on the nest machine in order to install signatures. 123 | 124 | ### Cuckoo Service Heuristics 125 | The heuristics for the service determine the scoring of the result, and can cover a variety of behaviours. Heuristics are 126 | raised for network calls, signature hits etc. Specifically for signature hits, we have grouped all 500+ signatures into 127 | categories where each category is a heuristic and is representative of the signatures that fall under that category. 128 | 129 | #### Scoring 130 | The scores for these categories are based on the average of the signature severities (which can be found in the Cuckoo Community 131 | repo on Github) for all the signatures in that category. This average was then rounded (up >= .5, down < .5) and applied to 132 | the following range map: 133 | 134 | > <= 1: 100 (informative) 135 | > 136 | > > 1 and <= 2: 500 (suspicious) 137 | > 138 | > > 2 and <= 4: 1000 (highly suspicious) 139 | > 140 | > > 4: 2000 (malicious) 141 | 142 | #### ATT&CK IDs 143 | For these categories, we have attempted to give default Mitre ATT&CK IDs to them by looking through all signatures in a category, 144 | and then taking the set of all ATT&CK IDs for these signatures (called `ttp` in the signature code), and if the set was a single ID 145 | that ID would be the default for the category. Progress is being made on finding generic IDs that can apply loosely to all signatures 146 | in a category when the above tactic doesn't work, such that there are defaults for all heuristics. 147 | 148 | ### Azure Deployment 149 | A document has been prepared on our side to assist with the deployment of Cuckoo using Azure resources. The release date of this document is TBD. 150 | In the meantime, the PR associated with this deployment is [here](https://github.com/cuckoosandbox/cuckoo/pull/3120) 151 | 152 | ### Additional Features 153 | #### Execute multiple DLL exports 154 | `dll_multi.py` 155 | 156 | This is located at `analyzer/windows/modules/packages`. It's a slightly modified 157 | version of the upstream `dll.py` package that is able to launch multiple DLL 158 | exports in a single run by passing the export names to execute using the 159 | function option, separated by pipe character. ie. `function=export1|export2` 160 | 161 | #### INetSim 162 | 163 | ##### Random DNS Resolution 164 | `DNS.pm, Config.pm, inetsim_patch.conf` 165 | 166 | These files are located at `inetsim/random_dns_patch/`. They allow an INetSim installation's DNS service to return a random IP from a given range for DNS lookups. 167 | In order to implement this patch, replace the `DNS.pm` and `Config.pm` found wherever you're running INetSim with the files found in this directory. If on a Linux box, then they 168 | could be at `/usr/share/perl5/INetSim/`. Then append the contents from `inetsim_patch.conf` to `/etc/inetsim/inetsim.conf`. Restart INetSim with `sudo systemctl restart inetsim.service`. 169 | 170 | ##### Geo-IP Service Patch 171 | `HTTP.pm` 172 | 173 | This file is located at `inetsim/geo_ip_service_patch/`. It allows an INetSim installation's HTTP service to return a fake response for a geo-IP service lookup. 174 | In order to implement this patch, replace the `HTTP.pm` found wherever you're running INetSim with the file found in this directory. If on a Linux box, then they 175 | could be at `/usr/share/perl5/INetSim/`. Restart INetSim with `sudo systemctl restart inetsim.service`. 176 | 177 | ### Assemblyline System Safelist 178 | #### Cuckoo-specific safelisted items 179 | The file at `al_config/system_safelist.yaml` contains suggested safelisted values that can be added to the Assemblyline system safelist 180 | either by copy-and-pasting directly to the text editor on the page `https:///admin/tag_safelist` or through the [Assemblyline Client](https://github.com/CybercentreCanada/assemblyline_client). 181 | -------------------------------------------------------------------------------- /service_manifest.yml: -------------------------------------------------------------------------------- 1 | name: Cuckoo 2 | version: $SERVICE_TAG 3 | description: Provides dynamic malware analysis through sandboxing. 4 | 5 | accepts: (executable/(windows|linux)|java|audiovisual|meta)/.*|document/(installer/windows|office/(excel|ole|powerpoint|rtf|unknown|word|mhtml)|pdf$)|code/(javascript|jscript|python|vbs|wsf|html|ps1|batch|hta|shell)|shortcut/windows 6 | rejects: empty|metadata/.* 7 | 8 | stage: CORE 9 | category: Dynamic Analysis 10 | 11 | file_required: true 12 | timeout: 800 13 | disable_cache: false 14 | 15 | enabled: false 16 | is_external: false 17 | licence_count: 0 18 | 19 | config: 20 | # See README for in-depth descriptions of configuration values 21 | # Cuckoo host configurations 22 | 23 | remote_host_details: 24 | hosts: 25 | - ip: "127.0.0.1" 26 | port: 8090 27 | api_key: "sample_api_token" 28 | 29 | connection_timeout_in_seconds: 30 30 | rest_timeout_in_seconds: 120 31 | connection_attempts: 3 32 | 33 | # Cuckoo victim configurations 34 | allowed_images: [] 35 | # This is used if the "auto" specific image will select multiple images and you want to override it with less images 36 | auto_architecture: 37 | win: 38 | x64: [] 39 | x86: [] 40 | ub: 41 | x64: [] 42 | x86: [] 43 | 44 | # Cuckoo analysis configurations 45 | max_file_size: 80000000 46 | default_analysis_timeout_in_seconds: 150 47 | max_dll_exports_exec: 5 48 | machinery_supports_memory_dumps: false 49 | reboot_supported: false 50 | uses_https_proxy_in_sandbox: false 51 | 52 | # Cuckoo reporting configurations 53 | recursion_limit: 10000 54 | max_report_size: 275000000 55 | 56 | # INetSim specifications 57 | random_ip_range: 192.0.2.0/24 58 | 59 | # Assemblyline service specifications 60 | dedup_similar_percent: 40 61 | 62 | # Since Windows 10x64 is not supported by the Cuckoo monitor, but a lot of malware samples only run on Windows 10x64, 63 | # we want a service-level variable that will submit files to Windows 10x64 without the Cuckoo monitor, in 64 | # order to still catch network IOCs 65 | no_monitor_for_win10x64: false 66 | 67 | submission_params: 68 | - default: 0 69 | name: analysis_timeout_in_seconds 70 | type: int 71 | value: 0 72 | 73 | # value = auto + auto_all + all + allowed_images 74 | # This has the third-highest precedence when submitting a file 75 | - default: "auto" 76 | name: specific_image 77 | type: list 78 | value: "auto" 79 | list: ["auto", "auto_all", "all"] 80 | 81 | - default: "" 82 | name: dll_function 83 | type: str 84 | value: "" 85 | 86 | - default: false 87 | name: dump_memory 88 | type: bool 89 | value: false 90 | 91 | - default: true 92 | name: force_sleepskip 93 | type: bool 94 | value: true 95 | 96 | - default: false 97 | name: no_monitor 98 | type: bool 99 | value: false 100 | 101 | - default: true 102 | name: simulate_user 103 | type: bool 104 | value: true 105 | 106 | - default: true 107 | name: sysmon_enabled 108 | type: bool 109 | value: true 110 | 111 | - default: false 112 | name: take_screenshots 113 | type: bool 114 | value: false 115 | 116 | - default: false 117 | name: reboot 118 | type: bool 119 | value: false 120 | 121 | - default: "" 122 | name: arguments 123 | type: str 124 | value: "" 125 | 126 | - default: "" 127 | name: custom_options 128 | type: str 129 | value: "" 130 | 131 | - default: "" 132 | name: clock 133 | type: str 134 | value: "" 135 | 136 | - default: "" 137 | name: package 138 | type: str 139 | value: "" 140 | 141 | - default: "" 142 | name: specific_machine 143 | type: str 144 | value: "" 145 | 146 | - default: 134217728 147 | name: max_total_size_of_uploaded_files 148 | type: int 149 | value: 134217728 150 | 151 | - default: "none" 152 | name: platform 153 | type: list 154 | value: "none" 155 | list: ["none", "windows", "linux"] 156 | 157 | # https://cuckoo.readthedocs.io/en/latest/installation/host/routing/#per-analysis-network-routing-options 158 | - default: "none" 159 | name: routing 160 | type: list 161 | value: none 162 | list: ["none", "inetsim", "drop", "internet", "tor", "vpn"] 163 | 164 | heuristics: 165 | - heur_id: 1 166 | attack_id: [T1190, T1212, T1082, T1211, T1068] 167 | name: Exploit 168 | score: 250 169 | signature_score_map: 170 | queries_programs: 10 171 | filetype: '*' 172 | description: Exploits an known software vulnerability or security flaw. 173 | 174 | - heur_id: 2 175 | attack_id: T1059.001 176 | name: PowerShell 177 | score: 500 178 | signature_score_map: 179 | suspicious_powershell: 250 180 | filetype: '*' 181 | description: Leverages Powershell to attack Windows operating systems. 182 | 183 | - heur_id: 3 184 | attack_id: T1059 185 | name: Hacking tool 186 | score: 750 187 | filetype: '*' 188 | description: Programs designed to crack or break computer and network security measures. 189 | 190 | - heur_id: 4 191 | attack_id: T1112 192 | name: Locker 193 | score: 100 194 | filetype: '*' 195 | description: Prevents access to system data and files. 196 | 197 | - heur_id: 5 198 | attack_id: T1518.001 199 | name: Anti-analysis 200 | score: 250 201 | filetype: '*' 202 | description: Constructed to conceal or obfuscate itself to prevent analysis. 203 | 204 | - heur_id: 6 205 | attack_id: T1106 206 | name: Suspicious PDF API 207 | score: 100 208 | filetype: '*' 209 | description: Makes PDF API calls not consistent with expected/standard behaviour. 210 | 211 | - heur_id: 7 212 | attack_id: T1106 213 | name: Suspicious Android API 214 | score: 250 215 | filetype: '*' 216 | description: Makes Android API calls not consistent with expected/standard behaviour. 217 | 218 | - heur_id: 8 219 | attack_id: [T1518.001, T1562.001] 220 | name: Anti-antivirus 221 | score: 250 222 | signature_score_map: 223 | antiav_servicestop: 25 224 | filetype: '*' 225 | description: Attempts to conceal itself from detection by anti-virus. 226 | 227 | - heur_id: 9 228 | attack_id: [T1497, T1007] 229 | name: Anti-vm 230 | score: 250 231 | signature_score_map: 232 | antivm_generic_cpu: 10 233 | antivm_generic_disk: 100 234 | antivm_vbox_keys: 100 235 | filetype: '*' 236 | description: Attempts to detect if it is being run in virtualized environment. 237 | 238 | - heur_id: 10 239 | attack_id: [T1057, T1518.001] 240 | name: Anti-debug 241 | score: 100 242 | filetype: '*' 243 | description: Attempts to detect if it is being debugged. 244 | 245 | - heur_id: 11 246 | name: Worm 247 | score: 250 248 | filetype: '*' 249 | description: Attempts to replicate itself in order to spread to other systems. 250 | 251 | - heur_id: 12 252 | attack_id: T1526 253 | name: Cloud 254 | score: 100 255 | filetype: '*' 256 | description: Makes connection to cloud service. 257 | 258 | - heur_id: 13 259 | name: Virus 260 | score: 250 261 | filetype: '*' 262 | description: Malicious software program 263 | 264 | - heur_id: 14 265 | name: Suspicious Office 266 | score: 100 267 | signature_score_map: 268 | creates_doc: 10 269 | filetype: '*' 270 | description: Makes API calls not consistent with expected/standard behaviour 271 | 272 | - heur_id: 15 273 | attack_id: T1486 274 | name: Ransomware 275 | score: 250 276 | filetype: '*' 277 | description: Designed to block access to a system until a sum of money is paid. 278 | 279 | - heur_id: 16 280 | attack_id: [T1547.001, T1546.010, T1098] 281 | name: Persistence 282 | score: 250 283 | signature_score_map: 284 | creates_shortcut: 10 285 | creates_exe: 10 286 | persistence_ads: 10 287 | deletes_executed_files: 100 288 | privilege_luid_check: 10 289 | filetype: '*' 290 | description: Technique used to maintain presence in system(s) across interruptions that could cut off access. 291 | 292 | - heur_id: 17 293 | attack_id: T1055 294 | name: Injection 295 | score: 250 296 | signature_score_map: 297 | allocates_rwx: 10 298 | hollowshunter_exe: 1000 299 | hollowshunter_dll: 100 300 | injection_resumethread: 100 301 | filetype: '*' 302 | description: Hide executable code in another process or within the malicious process after unpacking iteself. 303 | 304 | - heur_id: 18 305 | name: Dropper 306 | score: 100 307 | filetype: '*' 308 | description: Trojan that drops additional malware on an affected system. 309 | 310 | - heur_id: 19 311 | attack_id: T1059 312 | name: Suspicious Execution Chain 313 | score: 250 314 | signature_score_map: 315 | uses_windows_utilities: 10 316 | filetype: '*' 317 | description: Command shell or script process was created by unexpected parent process. 318 | 319 | - heur_id: 20 320 | name: Trojan 321 | score: 250 322 | filetype: '*' 323 | description: Presents itself as legitimate in attempt to infiltrate a system. 324 | 325 | - heur_id: 21 326 | attack_id: T1219 327 | name: RAT 328 | score: 250 329 | filetype: '*' 330 | description: Designed to provide the capability of covert surveillance and/or unauthorized access to a target. 331 | 332 | - heur_id: 22 333 | attack_id: T1071 334 | name: C2 335 | score: 250 336 | signature_score_map: 337 | dead_host: 10 # This signature ranges from 2-8 -> 100-1000 338 | network_icmp: 10 339 | network_http_post: 10 340 | network_http: 10 341 | network_cnc_http: 200 342 | multiple_useragents: 100 343 | filetype: '*' 344 | description: Communicates with a server controlled by a malicious actor. 345 | 346 | - heur_id: 23 347 | attack_id: [T1090, T1090.003] 348 | name: Tor 349 | score: 250 350 | signature_score_map: 351 | network_torgateway: 500 352 | filetype: '*' 353 | description: Installs/Leverages Tor to enable anonymous communication. 354 | 355 | - heur_id: 24 356 | name: Web Mail 357 | score: 100 358 | filetype: '*' 359 | description: Connects to smtp.[domain] for possible spamming or data exfiltration. 360 | 361 | - heur_id: 25 362 | attack_id: T1497 363 | name: Anti-sandbox 364 | score: 250 365 | signature_score_map: 366 | antisandbox_idletime: 10 367 | antisandbox_foregroundwindows: 10 368 | filetype: '*' 369 | description: Attempts to detect if it is in a sandbox. 370 | 371 | - heur_id: 26 372 | attack_id: [T1036, T1564.001, T1070] 373 | name: Stealth 374 | score: 250 375 | signature_score_map: 376 | reads_user_agent: 10 377 | filetype: '*' 378 | description: Leverages/modifies internal processes and settings to conceal itself. 379 | 380 | - heur_id: 27 381 | attack_id: T1027.002 382 | name: Packer 383 | score: 100 384 | signature_score_map: 385 | suspicious_process: 500 # This signature is a 2 -> 100 386 | filetype: '*' 387 | description: Compresses, encrypts, and/or modifies a malicious file's format. 388 | 389 | - heur_id: 28 390 | name: Banker 391 | score: 250 392 | filetype: '*' 393 | description: Designed to gain access to confidential information stored or processed through online banking. 394 | 395 | - heur_id: 29 396 | name: Point-of-sale 397 | score: 250 398 | filetype: '*' 399 | description: Steals information related to financial transactions, including credit card information. 400 | 401 | - heur_id: 30 402 | attack_id: T1562.001 403 | name: Bypass 404 | score: 250 405 | filetype: '*' 406 | description: Attempts to bypass operating systems security controls (firewall, amsi, applocker, etc.) 407 | 408 | - heur_id: 31 409 | name: Crash 410 | score: 10 411 | filetype: '*' 412 | description: Attempts to crash the system. 413 | 414 | - heur_id: 32 415 | name: IM 416 | score: 100 417 | filetype: '*' 418 | description: Leverages instant-messaging. 419 | 420 | - heur_id: 33 421 | attack_id: T1014 422 | name: Rootkit 423 | score: 250 424 | filetype: '*' 425 | description: Designed to provide continued privileged access to a system while actively hiding its presence. 426 | 427 | - heur_id: 34 428 | name: Adware 429 | score: 100 430 | filetype: '*' 431 | description: Displays unwanted, unsolicited advertisements. 432 | 433 | - heur_id: 35 434 | attack_id: [T1003, T1005] 435 | name: Infostealer 436 | score: 250 437 | filetype: '*' 438 | description: Collects and disseminates information such as login details, usernames, passwords, etc. 439 | 440 | - heur_id: 36 441 | attack_id: T1047 442 | name: WMI 443 | score: 250 444 | signature_score_map: 445 | office_uses_wmi: 250 # This signature is a 5 -> 750 446 | filetype: '*' 447 | description: Leverages Windows Management Instrumentation (WMI) to gather information and/or execute a process. 448 | 449 | - heur_id: 37 450 | attack_id: [T1071, T1129] 451 | name: Downloader 452 | score: 250 453 | filetype: '*' 454 | description: Trojan that downloads / installs files. 455 | 456 | - heur_id: 38 457 | name: DynDNS 458 | score: 100 459 | filetype: '*' 460 | description: Utilizes dynamic DNS. 461 | 462 | - heur_id: 39 463 | name: BOT 464 | score: 250 465 | filetype: '*' 466 | description: Appears to be a bot or exhibits bot-like behaviour. 467 | 468 | - heur_id: 40 469 | name: Rop 470 | score: 500 471 | filetype: '*' 472 | description: Exploits trusted programs to execute malicious code from memory to evade data execution prevention. 473 | 474 | - heur_id: 41 475 | name: Fraud 476 | score: 250 477 | filetype: '*' 478 | description: Presents itself as a legitimate program and/or facilitates fraudulent activity. 479 | 480 | - heur_id: 42 481 | name: URLshort 482 | score: 100 483 | filetype: '*' 484 | description: Leverages URL shortening to obfuscate malicious destination. 485 | 486 | - heur_id: 43 487 | attack_id: T1497 488 | name: Anti-emulation 489 | score: 250 490 | filetype: '*' 491 | description: Detects the presence of an emulator. 492 | 493 | - heur_id: 44 494 | name: Cryptocurrency 495 | score: 100 496 | filetype: '*' 497 | description: Facilitates mining of cryptocurrency. 498 | 499 | - heur_id: 45 500 | name: Bind 501 | score: 100 502 | filetype: '*' 503 | description: Allows a resource to be sent or received across a network. 504 | 505 | - heur_id: 46 506 | name: Suspicious DLL 507 | score: 250 508 | filetype: '*' 509 | description: Attempts to load DLL that is inconsistent with expected/standard behaviour. 510 | 511 | - heur_id: 1000 512 | name: Domain detected 513 | score: 10 514 | filetype: '*' 515 | description: Cuckoo detected Domains 516 | 517 | - heur_id: 1002 518 | name: HTTP/HTTPS detected 519 | score: 10 520 | filetype: '*' 521 | description: Cuckoo detected HTTP/HTTPS requests 522 | 523 | - heur_id: 1003 524 | name: Access Remote File 525 | score: 10 526 | filetype: '*' 527 | description: Cuckoo detected an attempt to access a remote file 528 | 529 | - heur_id: 1004 530 | name: TCP/UDP Detected 531 | score: 10 532 | filetype: '*' 533 | description: Cuckoo detected traffic made over TCP/UDP 534 | 535 | - heur_id: 1005 536 | name: Non-HTTP Traffic over HTTP ports 537 | score: 10 538 | filetype: '*' 539 | description: Cuckoo detected non-HTTP traffic being made over HTTP ports (80, 443) 540 | 541 | - heur_id: 1006 542 | name: IOC found in Buffer 543 | score: 500 544 | filetype: '*' 545 | description: Cuckoo detected an IOC found in a buffer, either encrypted or decrypted 546 | 547 | - heur_id: 1007 548 | name: Suspicious User Agent 549 | score: 1 550 | filetype: '*' 551 | description: Cuckoo detected a suspicious user agent used for HTTP calls 552 | 553 | - heur_id: 1008 554 | name: AntiVirus Hit 555 | score: 1000 556 | filetype: '*' 557 | description: AntiVirus hit. File is infected. 558 | 559 | - heur_id: 9999 560 | name: Unknown 561 | score: 0 562 | filetype: '*' 563 | description: Unknown signature detected by Cuckoo 564 | 565 | docker_config: 566 | allow_internet_access: true 567 | image: ${REGISTRY}cccs/assemblyline-service-cuckoo:$SERVICE_TAG 568 | cpu_cores: 0.5 569 | ram_mb: 2000 570 | -------------------------------------------------------------------------------- /inetsim/random_dns_patch/DNS.pm: -------------------------------------------------------------------------------- 1 | # -*- perl -*- 2 | # 3 | # INetSim::DNS - A fake DNS server 4 | # 5 | # RFC 1035 (and many others) - Domain Name System 6 | # 7 | # (c)2007-2019 Matthias Eckert, Thomas Hungenberg 8 | # 9 | ############################################################# 10 | 11 | package INetSim::DNS; 12 | 13 | use strict; 14 | use warnings; 15 | use Net::DNS; 16 | use Net::DNS::Nameserver; 17 | 18 | # Path to use for DNS 'cache' 19 | our $dns_mapping_file = "/tmp/inetsim_dns_ip_mappings.csv"; 20 | 21 | sub dns{ 22 | # check for broken version 0.65 of Net::DNS 23 | if ($Net::DNS::VERSION eq "0.65") { 24 | INetSim::Log::MainLog("failed! (The installed version 0.65 of Perl library Net::DNS is broken. Please upgrade to version 0.66 or later.)", INetSim::Config::getConfigParameter("DNS_ServiceName")); 25 | exit 1; 26 | } 27 | 28 | my $CPID = $$; 29 | my $localaddr = (defined INetSim::Config::getConfigParameter("DNS_BindAddress") ? INetSim::Config::getConfigParameter("DNS_BindAddress") : INetSim::Config::getConfigParameter("Default_BindAddress")); 30 | $localaddr =~ /\A(.*)\z/; # fool taint check 31 | $localaddr = $1; 32 | my $bindport = INetSim::Config::getConfigParameter("DNS_BindPort"); 33 | $bindport =~ /\A(.*)\z/; # fool taint check 34 | $bindport = $1; 35 | 36 | local $SIG{'INT'} = 'IGNORE'; 37 | local $SIG{'TERM'} = sub {INetSim::Log::MainLog("stopped (PID $CPID)", INetSim::Config::getConfigParameter("DNS_ServiceName")); exit 0;}; 38 | 39 | my $server = Net::DNS::Nameserver->new(LocalAddr => $localaddr, 40 | LocalPort => $bindport, 41 | ReplyHandler => \&dns_reply_handler, 42 | Verbose => '0'); 43 | if(! $server) { 44 | INetSim::Log::MainLog("failed!", INetSim::Config::getConfigParameter("DNS_ServiceName")); 45 | exit 1; 46 | } 47 | 48 | # drop root privileges 49 | my $runasuser = INetSim::Config::getConfigParameter("Default_RunAsUser"); 50 | my $runasgroup = INetSim::Config::getConfigParameter("Default_RunAsGroup"); 51 | 52 | my $uid = getpwnam($runasuser); 53 | my $gid = getgrnam($runasgroup); 54 | POSIX::setgid($gid); 55 | my $newgid = POSIX::getgid(); 56 | if ($newgid != $gid) { 57 | INetSim::Log::MainLog("failed! (Cannot switch group)", INetSim::Config::getConfigParameter("DNS_ServiceName")); 58 | exit 0; 59 | } 60 | 61 | POSIX::setuid($uid); 62 | if ($< != $uid || $> != $uid) { 63 | $< = $> = $uid; # try again - reportedly needed by some Perl 5.8.0 Linux systems 64 | if ($< != $uid) { 65 | INetSim::Log::MainLog("failed! (Cannot switch user)", INetSim::Config::getConfigParameter("DNS_ServiceName")); 66 | exit 0; 67 | } 68 | } 69 | 70 | # Clear and create a DNS log file to track IP->hostname mappings 71 | my $dns_random_ip = &INetSim::Config::getConfigParameter("DNS_RandomIp"); 72 | if ($dns_random_ip) { 73 | unlink($dns_mapping_file); 74 | open(my $mapping_fh, '>', $dns_mapping_file); 75 | close($mapping_fh); 76 | } 77 | 78 | $0 = 'inetsim_' . INetSim::Config::getConfigParameter("DNS_ServiceName"); 79 | INetSim::Log::MainLog("started (PID $CPID)", INetSim::Config::getConfigParameter("DNS_ServiceName")); 80 | $server->main_loop; 81 | INetSim::Log::MainLog("stopped (PID $CPID)", INetSim::Config::getConfigParameter("DNS_ServiceName")); 82 | exit 0; 83 | } 84 | 85 | 86 | sub dns_reply_handler { 87 | # STILL NEEDS WORK !!! 88 | my ($queryname, $queryclass, $querytype, $rhost, $query) = @_; 89 | my (@ans, @auth, @add) = (); 90 | my @logans = (); 91 | my $resultcode = "REFUSED"; 92 | my $ttl = 3600; 93 | my $SOA_serial = 20150801; 94 | my $SOA_refresh = 1000; 95 | my $SOA_retry = 800; 96 | my $SOA_expire = 7200; 97 | my $SOA_minimum = 3600; 98 | my $stat_success = 0; 99 | my $serviceName = INetSim::Config::getConfigParameter("DNS_ServiceName"); 100 | my $localaddress = INetSim::Config::getConfigParameter("Default_BindAddress"); 101 | 102 | INetSim::Log::SubLog("[$rhost] connect", $serviceName, $$); 103 | 104 | if (! defined ($queryname) || ! defined ($queryclass) || ! defined ($querytype) || ! defined ($rhost)) { 105 | $resultcode = "SERVFAIL"; 106 | } 107 | 108 | elsif (($queryclass ne "IN") && ($queryclass ne "CH")) { 109 | $resultcode = "REFUSED"; 110 | } 111 | 112 | elsif (length($queryname) > 255) { 113 | $resultcode = "FORMERR"; 114 | } 115 | 116 | elsif ($querytype eq "A") { 117 | my $rdata; 118 | if ($queryname =~ /\Awpad\z/i || $queryname =~ /\Awpad\..*/i) { 119 | $rdata = $localaddress; 120 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass A $rdata"); 121 | push (@logans, "$queryname $ttl $queryclass A $rdata"); 122 | $resultcode = "NOERROR"; 123 | } 124 | else { 125 | if ($queryname =~ /\A[0-9a-zA-Z-.]{1,255}\z/) { 126 | $rdata = &getIP($queryname); 127 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass A $rdata"); 128 | push (@logans, "$queryname $ttl $queryclass A $rdata"); 129 | $resultcode = "NOERROR"; 130 | } 131 | else { 132 | # invalid queryname 133 | $resultcode = "NXDOMAIN"; 134 | } 135 | } 136 | } 137 | 138 | elsif ($querytype eq "SOA") { 139 | if ($queryname =~ /\A[0-9a-zA-Z-.]{1,255}\z/) { 140 | # Answer section 141 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass SOA ns1.$queryname hostmaster.$queryname $SOA_serial $SOA_refresh $SOA_retry $SOA_expire $SOA_minimum"); 142 | push @logans, "$queryname $ttl $queryclass SOA ns1.$queryname hostmaster.$queryname $SOA_serial $SOA_refresh $SOA_retry $SOA_expire $SOA_minimum"; 143 | # NS in Authority section 144 | push @auth, Net::DNS::RR->new("$queryname $ttl $queryclass NS ns1.$queryname"); 145 | push @auth, Net::DNS::RR->new("$queryname $ttl $queryclass NS ns2.$queryname"); 146 | push @logans, "$queryname $ttl $queryclass NS ns1.$queryname"; 147 | push @logans, "$queryname $ttl $queryclass NS ns2.$queryname"; 148 | # IPs for NS NS in Additional section 149 | my $ns1ip = getIP("ns1.$queryname"); 150 | my $ns2ip = getIP("ns2.$queryname"); 151 | push @add, Net::DNS::RR->new("ns1.$queryname $ttl $queryclass A $ns1ip"); 152 | push @add, Net::DNS::RR->new("ns2.$queryname $ttl $queryclass A $ns2ip"); 153 | push @logans, "ns1.$queryname $ttl $queryclass A $ns1ip"; 154 | push @logans, "ns2.$queryname $ttl $queryclass A $ns2ip"; 155 | $resultcode = "NOERROR"; 156 | } 157 | else { 158 | # invalid queryname 159 | $resultcode = "NXDOMAIN"; 160 | } 161 | } 162 | 163 | elsif ($querytype eq "PTR") { 164 | if ($queryname =~ /\A[0-9a-zA-Z-.]{1,255}\z/) { 165 | my $rdata = &getHost($queryname); 166 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass PTR $rdata"); 167 | push @logans, "$queryname $ttl $queryclass $querytype $rdata"; 168 | $resultcode = "NOERROR"; 169 | } 170 | else { 171 | # invalid queryname 172 | $resultcode = "NXDOMAIN"; 173 | } 174 | } 175 | 176 | elsif ($querytype eq "TXT") { 177 | my $rdata; 178 | # http://www.ietf.org/rfc/rfc4892.txt 179 | # http://www.ietf.org/proceedings/54/I-D/draft-ietf-dnsop-serverid-00.txt 180 | if ($queryclass eq "CH" && ($queryname =~ /\A(version|hostname)\.bind/i || $queryname =~ /\A(id|version)\.server/i)) { 181 | $rdata = INetSim::Config::getConfigParameter("DNS_Version"); 182 | } 183 | elsif ($queryname =~ /\A[0-9a-zA-Z-.]{1,255}\z/) { 184 | $rdata = "this is a txt record"; 185 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass TXT \"$rdata\""); 186 | push @logans, "$queryname $ttl $queryclass $querytype \"$rdata\""; 187 | $resultcode = "NOERROR"; 188 | } 189 | else { 190 | # invalid queryname 191 | $resultcode = "NXDOMAIN"; 192 | } 193 | } 194 | 195 | elsif ($querytype eq "MX") { 196 | if ($queryname =~ /\A[0-9a-zA-Z-.]{1,255}\z/) { 197 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass MX 10 mx1.$queryname"); 198 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass MX 20 mx2.$queryname"); 199 | push (@logans, "$queryname $ttl $queryclass MX 10 mx1.$queryname"); 200 | push (@logans, "$queryname $ttl $queryclass MX 20 mx2.$queryname"); 201 | # IP-Adressen f?r MX in Additional Section 202 | my $mx1ip = getIP("mx1.$queryname"); 203 | my $mx2ip = getIP("mx2.$queryname"); 204 | push @add, Net::DNS::RR->new("mx1.$queryname $ttl $queryclass A $mx1ip"); 205 | push @add, Net::DNS::RR->new("mx2.$queryname $ttl $queryclass A $mx2ip"); 206 | push (@logans, "mx1.$queryname $ttl $queryclass A $mx1ip"); 207 | push (@logans, "mx2.$queryname $ttl $queryclass A $mx2ip"); 208 | $resultcode = "NOERROR"; 209 | } 210 | else { 211 | # invalid queryname 212 | $resultcode = "NXDOMAIN"; 213 | } 214 | } 215 | 216 | elsif ($querytype eq "NS") { 217 | if ($queryname =~ /\A[0-9a-zA-Z-.]{1,255}\z/) { 218 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass NS ns1.$queryname"); 219 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass NS ns2.$queryname"); 220 | push (@logans, "$queryname $ttl $queryclass NS ns1.$queryname"); 221 | push (@logans, "$queryname $ttl $queryclass NS ns2.$queryname"); 222 | # IPs for NS in Additional Section 223 | my $ns1ip = getIP("ns1.$queryname"); 224 | my $ns2ip = getIP("ns2.$queryname"); 225 | push @add, Net::DNS::RR->new("ns1.$queryname $ttl $queryclass A $ns1ip"); 226 | push @add, Net::DNS::RR->new("ns2.$queryname $ttl $queryclass A $ns2ip"); 227 | push @logans, "ns1.$queryname $ttl $queryclass A $ns1ip"; 228 | push @logans, "ns2.$queryname $ttl $queryclass A $ns2ip"; 229 | $resultcode = "NOERROR"; 230 | } 231 | else { 232 | # invalid queryname 233 | $resultcode = "NXDOMAIN"; 234 | } 235 | } 236 | 237 | elsif ($querytype eq "ANY") { 238 | if ($queryname =~ /\A[0-9a-zA-Z-.]{1,255}\z/) { 239 | # SOA 240 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass SOA ns1.$queryname hostmaster.$queryname $SOA_serial $SOA_refresh $SOA_retry $SOA_expire $SOA_minimum"); 241 | push @logans, "$queryname $ttl $queryclass SOA ns1.$queryname hostmaster.$queryname $SOA_serial $SOA_refresh $SOA_retry $SOA_expire $SOA_minimum"; 242 | # NS 243 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass NS ns1.$queryname"); 244 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass NS ns2.$queryname"); 245 | push (@logans, "$queryname $ttl $queryclass NS ns1.$queryname"); 246 | push (@logans, "$queryname $ttl $queryclass NS ns2.$queryname"); 247 | # MX 248 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass MX 10 mx1.$queryname"); 249 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass MX 20 mx2.$queryname"); 250 | push (@logans, "$queryname $ttl $queryclass $querytype 10 mx1.$queryname"); 251 | push (@logans, "$queryname $ttl $queryclass $querytype 20 mx2.$queryname"); 252 | # A 253 | my $rdata = &getIP($queryname); 254 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass A $rdata"); 255 | push (@logans, "$queryname $ttl $queryclass A $rdata"); 256 | # IPs for NS and MX 257 | my $ns1ip = getIP("ns1.$queryname"); 258 | my $ns2ip = getIP("ns2.$queryname"); 259 | push @add, Net::DNS::RR->new("ns1.$queryname $ttl $queryclass A $ns1ip"); 260 | push @add, Net::DNS::RR->new("ns2.$queryname $ttl $queryclass A $ns2ip"); 261 | push @logans, "ns1.$queryname $ttl $queryclass A $ns1ip"; 262 | push @logans, "ns2.$queryname $ttl $queryclass A $ns2ip"; 263 | my $mx1ip = getIP("mx1.$queryname"); 264 | my $mx2ip = getIP("mx2.$queryname"); 265 | push @add, Net::DNS::RR->new("mx1.$queryname $ttl $queryclass A $mx1ip"); 266 | push @add, Net::DNS::RR->new("mx2.$queryname $ttl $queryclass A $mx2ip"); 267 | push (@logans, "mx1.$queryname $ttl $queryclass A $mx1ip"); 268 | push (@logans, "mx2.$queryname $ttl $queryclass A $mx2ip"); 269 | $resultcode = "NOERROR"; 270 | } 271 | else { 272 | # invalid queryname 273 | $resultcode = "NXDOMAIN"; 274 | } 275 | } 276 | 277 | elsif ($querytype eq "CNAME") { 278 | if ($queryname =~ /\A[0-9a-zA-Z-.]{1,255}\z/) { 279 | # some host 280 | push @ans, Net::DNS::RR->new("$queryname $ttl $queryclass CNAME host.$queryname"); 281 | push (@logans, "$queryname $ttl $queryclass CNAME host.$queryname"); 282 | $resultcode = "NOERROR"; 283 | } 284 | else { 285 | # invalid queryname 286 | $resultcode = "NXDOMAIN"; 287 | } 288 | } 289 | 290 | elsif ($querytype eq "AXFR") { 291 | $resultcode = "REFUSED"; 292 | } 293 | 294 | elsif ($querytype eq "AAAA") { 295 | $resultcode = "NOERROR"; 296 | } 297 | 298 | else { 299 | # $resultcode = "NXDOMAIN"; 300 | $resultcode = "NOTIMP"; 301 | } 302 | 303 | INetSim::Log::SubLog("[$rhost] recv: Query Type ".$querytype.", Class ".$queryclass.", Name ".$queryname, $serviceName, $$); 304 | if ($resultcode ne "NXDOMAIN" && $resultcode ne "REFUSED" && $resultcode ne "NOTIMP" && $resultcode ne "SERVFAIL") { 305 | foreach my $msg (@logans){ 306 | INetSim::Log::SubLog("[$rhost] send: ".$msg, $serviceName, $$); 307 | } 308 | $stat_success = 1; 309 | } 310 | else { 311 | INetSim::Log::SubLog("[$rhost] Error: $resultcode", $serviceName, $$); 312 | } 313 | INetSim::Log::SubLog("[$rhost] disconnect", $serviceName, $$); 314 | INetSim::Log::SubLog("[$rhost] stat: $stat_success qtype=$querytype qclass=$queryclass qname=$queryname", $serviceName, $$); 315 | return ($resultcode, \@ans, \@auth, \@add, {aa => 1}); 316 | } 317 | 318 | 319 | # Found this here: https://www.perlmonks.org/?node_id=389028 320 | sub n2dq{ join '.', unpack 'C4', pack 'N', $_[ 0 ] };; 321 | sub dq2n{ unpack 'N', pack 'C4', split '\.', $_[ 0 ] };; 322 | 323 | 324 | sub getIP { 325 | my $hostname = lc(shift); 326 | 327 | my %static_host_to_ip = INetSim::Config::getConfigHash("DNS_StaticHostToIP"); 328 | 329 | my $return_random_ip = &INetSim::Config::getConfigParameter("DNS_RandomIp"); 330 | 331 | if (defined $static_host_to_ip{$hostname}) { 332 | return $static_host_to_ip{$hostname}; 333 | } 334 | elsif ($return_random_ip) { 335 | # have we already created an IP for this hostname? 336 | open(my $dns_mapping_fh, $dns_mapping_file) or die "Can't open $dns_mapping_file"; 337 | 338 | my @dns_mappings = <$dns_mapping_fh>; 339 | my @matching_hostnames=grep /$hostname/,@dns_mappings; 340 | close($dns_mapping_fh); 341 | 342 | if (scalar(@matching_hostnames) > 0) { 343 | my @line_parts = split(",", $matching_hostnames[0]); 344 | return $line_parts[1]; 345 | } 346 | else { 347 | # Generate a random IP 348 | my @randrange = split("-", &INetSim::Config::getConfigParameter("DNS_RandomRange")); 349 | my $min_addr = dq2n($randrange[0]); 350 | my $max_addr = dq2n($randrange[1]); 351 | my $addr = $min_addr + rand($max_addr - $min_addr); 352 | my $dqip = n2dq($addr); 353 | 354 | # Save the IP mapping and return the ip 355 | open(my $fh, '>>', $dns_mapping_file); 356 | say $fh "$hostname,$dqip"; 357 | close($fh); 358 | return $dqip; 359 | } 360 | } 361 | else { 362 | return INetSim::Config::getConfigParameter("DNS_Default_IP"); 363 | } 364 | } 365 | 366 | 367 | sub getHost { 368 | my $ip = lc(shift); 369 | 370 | my %static_ip_to_host = INetSim::Config::getConfigHash("DNS_StaticIPToHost"); 371 | 372 | my $return_random_ip = &INetSim::Config::getConfigParameter("DNS_RandomIp"); 373 | 374 | if (defined $static_ip_to_host{$ip}) { 375 | return $static_ip_to_host{$ip}; 376 | } 377 | elsif ($return_random_ip) { 378 | my @forward_ip_split = split(/\./, $ip); 379 | my $forward_ip = $forward_ip_split[3] . "." . $forward_ip_split[2] . "." . $forward_ip_split[1] . "." . $forward_ip_split[0]; 380 | # do we have a hostname associated to this IP? 381 | open(my $dns_mapping_fh, $dns_mapping_file) or die "Can't open $dns_mapping_file"; 382 | 383 | my @dns_mappings = <$dns_mapping_fh>; 384 | my @matching_ips=grep /$forward_ip/,@dns_mappings; 385 | close($dns_mapping_fh); 386 | 387 | if (scalar(@matching_ips) > 0) { 388 | my @line_parts = split(",", $matching_ips[0]); 389 | return $line_parts[0]; 390 | } 391 | else { 392 | return &INetSim::Config::getConfigParameter("DNS_Default_Hostname") . "." . &INetSim::Config::getConfigParameter("DNS_Default_Domainname"); 393 | } 394 | } 395 | else { 396 | return INetSim::Config::getConfigParameter("DNS_Default_Hostname") . "." . INetSim::Config::getConfigParameter("DNS_Default_Domainname"); 397 | } 398 | } 399 | 400 | 401 | 1; 402 | # 403 | -------------------------------------------------------------------------------- /cuckoo/safe_process_tree_leaf_hashes.py: -------------------------------------------------------------------------------- 1 | SAFE_PROCESS_TREE_LEAF_HASHES = { 2 | "d3b14a95c2160abc76f356b5e9b79c71c91035e49f1c5962ce7a100e61decd78": { 3 | "image": "?sys32\\lsass.exe", 4 | "command_line": "C:\\WINDOWS\\system32\\lsass.exe", 5 | "children": [] 6 | }, 7 | "f405c23c52c0dd0cd7ac31f92df0e76f9c6702b155ca5be6afbc076bb81d82a6": { 8 | "image": "?pf86\\common files\\microsoft shared\\officesoftwareprotectionplatform\\osppsvc.exe", 9 | "command_line": "\"C:\\Program Files\\Common Files\\Microsoft Shared\\OfficeSoftwareProtectionPlatform\\OSPPSVC.EXE\"", 10 | "children": [] 11 | }, 12 | "a1d7889895b3a83edb3306c85df424da544369567d860215a75f5cbffe635375": { 13 | "image": '?sys32\\lsass.exe', 14 | "command_line": None, 15 | "children": [ 16 | { 17 | "image": '?sys32\\services.exe', 18 | "command_line": None, 19 | "children": [ 20 | { 21 | "image": "?pf86\\common files\\microsoft shared\\officesoftwareprotectionplatform\\osppsvc.exe", 22 | "command_line": "\"C:\\Program Files\\Common Files\\Microsoft Shared\\OfficeSoftwareProtectionPlatform\\OSPPSVC.EXE\"", 23 | "children": [] 24 | } 25 | ] 26 | } 27 | ] 28 | }, 29 | "7e2c38006c7720d214b726be34bf3bbfca1c8f02c3b36f7c8b7c7198f119c8a2": { 30 | "image": "?sys32\\sppsvc.exe", 31 | "command_line": "C:\\Windows\\system32\\sppsvc.exe", 32 | "children": [] 33 | }, 34 | "2f6044eb59e4d5104cfd7025ffd14fe2bea9405c566f7f4ecc9548f694fad00a": { 35 | "image": "?sys32\\svchost.exe", 36 | "command_line": "C:\\WINDOWS\\System32\\svchost.exe -k WerSvcGroup", 37 | "children": [ 38 | { 39 | "image": "?sys32\\werfault.exe", 40 | "command_line": "C:\\WINDOWS\\system32\\WerFault.exe -pss -s 476 -p 3168 -ip 3168", 41 | "children": [] 42 | } 43 | ] 44 | }, 45 | "b04893383338161ca8bec608cb9b877acf5c6708cbc4244ec5d0f49f5ab4b9f1": { 46 | "image": "?sys32\\slui.exe", 47 | "command_line": "C:\\WINDOWS\\System32\\slui.exe -Embedding", 48 | "children": [] 49 | }, 50 | "01bf5d0579b4db52ee0322f9f84b7db238c037a2d32b4969298830612ffbdcf8": { 51 | "image": "?sys32\\backgroundtaskhost.exe", 52 | "command_line": "\"C:\\WINDOWS\\system32\\backgroundTaskHost.exe\" -ServerName:App.AppXmtcan0h2tfbfy7k9kn8hbxb6dmzz1zh0.mca", 53 | "children": [] 54 | }, 55 | "a53afad8f3925d95edace69eb6e68184b3d52bdaae0bacdd2f7df5ede70446a8": { 56 | "image": "?pf86\\windowsapps\\microsoft.windowscommunicationsapps_16005.13426.20920.0_x64__8wekyb3d8bbwe\\hxtsr.exe", 57 | "command_line": "\"C:\\Program Files\\WindowsApps\\microsoft.windowscommunicationsapps_16005.13426.20920.0_x64__8wekyb3d8bbwe\\HxTsr.exe\" -ServerName:Hx.IPC.Server", 58 | "children": [] 59 | }, 60 | "1fc2ec278dbd4f03d4a6ea748d35f75b554e43b8211fc5bcebb2ff295e03182b": { 61 | "image": "?sys32\\runtimebroker.exe", 62 | "command_line": "C:\\Windows\\System32\\RuntimeBroker.exe -Embedding", 63 | "children": [] 64 | }, 65 | "51b9684487d1a103549ec6f5773e058932073037dc30fdb6580c9c388503cf74": { 66 | "image": "?sys32\\conhost.exe", 67 | "command_line": "\\??\\C:\\WINDOWS\\system32\\conhost.exe 0xffffffff -ForceV1", 68 | "children": [] 69 | }, 70 | "ddb872aa77c4c7ba1ec280f77e1a2f19cbd4d461fe21da009f89ade882fe26be": { 71 | "image": "?win\\explorer.exe", 72 | "command_line": "C:\\WINDOWS\\Explorer.EXE", 73 | "children": [] 74 | }, 75 | "f3d6ed01b460589fbebaf89c2fcad5503bf4d86993fb20d410eace46a595108f": { 76 | "image": "?sys32\\svchost.exe", 77 | "command_line": "C:\\WINDOWS\\System32\\svchost.exe -k WerSvcGroup", 78 | "children": [] 79 | }, 80 | "d1c20b94425d2d866bdd30adc1af7d7ce5b08c30c7418f618d8164ac06ae76ee": { 81 | "image": "?sys32\\dllhost.exe", 82 | "command_line": "C:\\Windows\\system32\\DllHost.exe /Processid:{F9717507-6651-4EDB-BFF7-AE615179BCCF}", 83 | "children": [] 84 | }, 85 | "9c58c41fb2916bea2d6059e912a55c5505ce0b3b7b78cdf6ee3321387ce0f0ae": { 86 | "image": "?sys32\\wbem\\wmiprvse.exe", 87 | "command_line": "C:\\Windows\\system32\\wbem\\wmiprvse.exe -secured -Embedding", 88 | "children": [] 89 | }, 90 | # FP since we only look at the image here 91 | # "3e3793b897525f211e7425c45df068b2594bb4ad8dcf731f5771fd30233d721b": { 92 | # "image": "?sys32\\rundll32.exe", 93 | # "command_line": "C:\\WINDOWS\\system32\\rundll32.exe C:\\WINDOWS\\system32\\PcaSvc.dll,PcaPatchSdbTask", 94 | # "children": [] 95 | # }, 96 | "ab2bf0e9666652ed8254b079209e27568e0e55a4418cfe94a48181f34625ff15": { 97 | "image": "?sys32\\sc.exe", 98 | "command_line": "C:\\WINDOWS\\system32\\sc.exe start wuauserv", 99 | "children": [ 100 | { 101 | "image": "?sys32\\conhost.exe", 102 | "command_line": "\\??\\C:\\WINDOWS\\system32\\conhost.exe 0xffffffff -ForceV1", 103 | "children": [] 104 | } 105 | ] 106 | }, 107 | "2dd065baf9009515b0d68a64a7cf324ff325893fb8ca630febed2950a3be7432": { 108 | "image": "?sys32\\wermgr.exe", 109 | "command_line": "\"C:\\WINDOWS\\system32\\wermgr.exe\" \"-outproc\" \"0\" \"2720\" \"1936\" \"1868\" \"1940\" \"0\" \"0\" \"0\" \"0\" \"0\" \"0\" \"0\" \"0\"", 110 | "children": [] 111 | }, 112 | "50c958b80515a739a7a9397890d310a91d1e3593ab1aae7757331d71768ccc4a": { 113 | "image": "?sys32\\sc.exe", 114 | "command_line": "C:\\Windows\\system32\\sc.exe start w32time task_started", 115 | "children": [] 116 | }, 117 | "faac8a70045bd7596a1f1e368e346130e357b6f5e8b043287653dfe1fabb12b9": { 118 | "image": "?sys32\\sdclt.exe", 119 | "command_line": "C:\\Windows\\System32\\sdclt.exe /CONFIGNOTIFICATION", 120 | "children": [] 121 | }, 122 | "d922fb8a674c43236b96805a7ba2d4090f0cb7e6ae12d0186339c9ad489c6386": { 123 | "image": "?sys32\\taskhost.exe", 124 | "command_line": "taskhost.exe $(Arg0)", 125 | "children": [] 126 | }, 127 | "e7a3087aba99f3aa0dd4aa5a44d0be58256b4ef41be49da617026838f5204f5c": { 128 | "image": "?win\\systemapps\\microsoftwindows.client.cbs_cw5n1h2txyewy\\inputapp\\textinputhost.exe", 129 | "command_line": "\"C:\\Windows\\SystemApps\\MicrosoftWindows.Client.CBS_cw5n1h2txyewy\\InputApp\\TextInputHost.exe\" -ServerName:InputApp.AppX9jnwykgrccxc8by3hsrsh07r423xzvav.mca", 130 | "children": [] 131 | }, 132 | "04184d24f08dadab15c91374f7aedba484d8214d0d3c2e8b240e3b7b6f25d959": { 133 | "image": '?sys32\\svchost.exe', 134 | "command_line": None, 135 | "children": [ 136 | { 137 | "image": "?win\\systemapps\\microsoftwindows.client.cbs_cw5n1h2txyewy\\inputapp\\textinputhost.exe", 138 | "command_line": "\"C:\\Windows\\SystemApps\\MicrosoftWindows.Client.CBS_cw5n1h2txyewy\\InputApp\\TextInputHost.exe\" -ServerName:InputApp.AppX9jnwykgrccxc8by3hsrsh07r423xzvav.mca", 139 | "children": [] 140 | } 141 | ] 142 | }, 143 | "24954e76154b030985354403bdb85d0a334c0007c842f5381ed8a0544f11466b": { 144 | "image": "?sys32\\wbem\\wmiadap.exe", 145 | "command_line": "wmiadap.exe /F /T /R", 146 | "children": [] 147 | }, 148 | "a7756c96db89aaf251d32633e40b57c104807060c3f7c650c0b94ea90cb0458b": { 149 | "image": "?win\\explorer.exe", 150 | "command_line": "C:\\WINDOWS\\Explorer.EXE", 151 | "children": [ 152 | { 153 | "image": "?sys32\\werfault.exe", 154 | "command_line": "C:\\WINDOWS\\system32\\WerFault.exe -u -p 6080 -s 6792", 155 | "children": [] 156 | } 157 | ] 158 | }, 159 | "aa5dd26518bf22e0d6ca76b67a2295934aa52858ec19b47affadf99cbd328a2e": { 160 | "image": "?win\\systemapps\\microsoft.windows.startmenuexperiencehost_cw5n1h2txyewy\\startmenuexperiencehost.exe", 161 | "command_line": "\"C:\\Windows\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\StartMenuExperienceHost.exe\" -ServerName:App.AppXywbrabmsek0gm3tkwpr5kwzbs55tkqay.mca", 162 | "children": [] 163 | }, 164 | "44dcdb8d08f7fdcfe0843d73a652ddbe1e1729fdfdcb66e8f009d3f82a3103ea": { 165 | "image": "?win\\systemapps\\microsoft.windows.search_cw5n1h2txyewy\\searchapp.exe", 166 | "command_line": "\"C:\\Windows\\SystemApps\\Microsoft.Windows.Search_cw5n1h2txyewy\\SearchApp.exe\" -ServerName:CortanaUI.AppX8z9r6jm96hw4bsbneegw0kyxx296wr9t.mca", 167 | "children": [] 168 | }, 169 | "6a27c89bdbe4f9855307c59f8c8a480e9a76681cf533d18690754baa250228db": { 170 | "image": "?sys32\\mobsync.exe", 171 | "command_line": "C:\\WINDOWS\\System32\\mobsync.exe -Embedding", 172 | "children": [] 173 | }, 174 | "b12bbea6f1a504c7288762f649b849457edbee81b4967863dad67f3158b250fb": { 175 | "image": "?sys32\\musnotifyicon.exe", 176 | "command_line": "%%systemroot%%\\system32\\MusNotifyIcon.exe NotifyTrayIcon 0", 177 | "children": [] 178 | }, 179 | "bcb1213942dd880cc729f5b6cad820e1cc0c0c92cdd4ab3e3919edd6e40fbb64": { 180 | "image": "?pf86\\windowsapps\\microsoft.xboxgamingoverlay_5.621.4222.0_x64__8wekyb3d8bbwe\\gamebar.exe", 181 | "command_line": "\"C:\\Program Files\\WindowsApps\\Microsoft.XboxGamingOverlay_5.621.4222.0_x64__8wekyb3d8bbwe\\GameBar.exe\" -ServerName:App.AppXbdkk0yrkwpcgeaem8zk81k8py1eaahny.mca", 182 | "children": [] 183 | }, 184 | "fd4fad363ee4c67ab9826cff5ab63d8a68bde96c63b60d70bc7654d26695e469": { 185 | "image": "?pf86\\windowsapps\\microsoft.xboxgamingoverlay_5.621.4222.0_x64__8wekyb3d8bbwe\\gamebarftserver.exe", 186 | "command_line": "\"C:\\Program Files\\WindowsApps\\Microsoft.XboxGamingOverlay_5.621.4222.0_x64__8wekyb3d8bbwe\\GameBarFTServer.exe\" -Embedding", 187 | "children": [] 188 | }, 189 | "f3de6d0a84196f1af3fe985f772c7a4dd23a7979286e78c9928d3f3fcb090a82": { 190 | "image": "?sys32\\backgroundtransferhost.exe", 191 | "command_line": "\"BackgroundTransferHost.exe\" -ServerName:BackgroundTransferHost.1", 192 | "children": [] 193 | }, 194 | "73eb56621fbdbdfaeb669105ba4eb327854790d55994a23a2f852fed8bf9b9af": { 195 | "image": "?sys32\\backgroundtaskhost.exe", 196 | "command_line": "\"C:\\WINDOWS\\system32\\backgroundTaskHost.exe\" -ServerName:App.AppXmtcan0h2tfbfy7k9kn8hbxb6dmzz1zh0.mca", 197 | "children": [ 198 | { 199 | "image": "?sys32\\conhost.exe", 200 | "command_line": "\\??\\C:\\WINDOWS\\system32\\conhost.exe 0xffffffff -ForceV1", 201 | "children": [] 202 | } 203 | ] 204 | }, 205 | "0e3b8b7c5bbffdf8923f5acd914194d7f5db897b73a0f0541dc13750e4af718a": { 206 | "image": "?sys32\\werfault.exe", 207 | "command_line": "C:\\WINDOWS\\system32\\WerFault.exe -pss -s 484 -p 6448 -ip 6448", 208 | "children": [] 209 | }, 210 | "25a026bdd54385f3aaefb8e1723f5be97b7c36e255b2c48f7f7f8a66d9df7eb8": { 211 | "image": "?sys32\\waasmedicagent.exe", 212 | "command_line": "C:\\WINDOWS\\System32\\WaaSMedicAgent.exe 843c17b493dbd4989beed27582c82422 sXMpv2EzyEqV2L6NYnvYjw.0.1.0.0.0", 213 | "children": [] 214 | }, 215 | "54e726d55dcb6c6c4914a0ae899d89c454442624fa64c824bee9110b4abc7721": { 216 | "image": "?sys32\\sc.exe", 217 | "command_line": "C:\\WINDOWS\\system32\\sc.exe start pushtoinstall registration", 218 | "children": [ 219 | { 220 | "image": "?sys32\\conhost.exe", 221 | "command_line": "\\??\\C:\\WINDOWS\\system32\\conhost.exe 0xffffffff -ForceV1", 222 | "children": [ 223 | { 224 | "image": "?sys32\\wermgr.exe", 225 | "command_line": "\"C:\\WINDOWS\\system32\\wermgr.exe\" \"-outproc\" \"0\" \"1072\" \"1928\" \"1876\" \"1932\" \"0\" \"0\" \"0\" \"0\" \"0\" \"0\" \"0\" \"0\"", 226 | "children": [] 227 | } 228 | ] 229 | } 230 | ] 231 | }, 232 | "bbc5e661e106c6dcd8dc6dd186454c2fcba3c710fb4d8e71a60c93eaf077f073": { 233 | "image": "system", 234 | "command_line": None, 235 | "children": [] 236 | }, 237 | "acbf70b95a96ba178eb89269e7f1db5f622fa4b6b009cd29284d7be14024625b": { 238 | "image": "?sys32\\searchindexer.exe", 239 | "command_line": None, 240 | "children": [] 241 | }, 242 | "49a2ab6c73a10ee6bd97a0ba200c6f6dc0dc2977059b8029579e780748f19c72": { 243 | "image": "?c\\python27\\pythonw.exe", 244 | "command_line": None, 245 | "children": [] 246 | }, 247 | "49d9994a34643bea4cc71a26501d1e58ccabd051a1cf9704184b6374e1ef3764": { 248 | "image": "?sys32\\searchprotocolhost.exe", 249 | "command_line": None, 250 | "children": [] 251 | }, 252 | "a54f2146bd3272b89f7b9c7047f2b436a9514f89feeed754bcc6d19d32dc2db3": { 253 | "image": "?sys32\\searchfilterhost.exe", 254 | "command_line": None, 255 | "children": [] 256 | }, 257 | "1d038671bb56576c62a176c7902e6867a978732d1ecafe792c8ac6ac3dde79ba": { 258 | "image": "?sys32\\svchost.exe", 259 | "command_line": None, 260 | "children": [ 261 | { 262 | "image": "?win\\explorer.exe", 263 | "command_line": None, 264 | "children": [] 265 | } 266 | ] 267 | }, 268 | "5f4653a82121522720fbb9bdab186d70bf7f21e1ca475cb87b12f448ea71e1ca": { 269 | "image": "?sys32\\svchost.exe", 270 | "command_line": None, 271 | "children": [ 272 | { 273 | "image": "?sys32\\conhost.exe", 274 | "command_line": "\\??\\C:\\Windows\\system32\\conhost.exe \"-28232134049486641315307486691639655269-80106784-108753052346563986-549529209\"", 275 | "children": [] 276 | } 277 | ] 278 | }, 279 | "78f84277f3383d654d64679ea93be5614d09b588006f0e9ca7395bb797a6f942": { 280 | "image": "?sys32\\svchost.exe", 281 | "command_line": None, 282 | "children": [ 283 | { 284 | "image": '?c\\python27\\pythonw.exe', 285 | "command_line": None, 286 | "children": [] 287 | } 288 | ] 289 | }, 290 | "da60beb532bc62cd2208910c086bcbabc4488d45e2dcc4e8414b3969e7902fc7": { 291 | "image": "?sys32\\svchost.exe", 292 | "command_line": None, 293 | "children": [ 294 | { 295 | "image": "?sys32\\svchost.exe", 296 | "command_line": None, 297 | "children": [] 298 | } 299 | ] 300 | }, 301 | "6dea6b390c3611c05f7ce0a8d56b136431168161237ae254f4f0a3eeedb52fa9": { 302 | "image": "?sys32\\userinit.exe", 303 | "command_line": None, 304 | "children": [] 305 | }, 306 | "fe1b33fe682a3ce734f5e66aface2e59bad7a91741a6166b793e1658a44cab7b": { 307 | "image": "?win\\microsoft.net\\framework64\\v4.0.30319\\mscorsvw.exe", 308 | "command_line": None, 309 | "children": [] 310 | }, 311 | "eea8165b1ac8e04a4257e249753f1b8085e712521e3fc44718a49bb94851ff1b": { 312 | "image": "?win\\microsoft.net\\framework\\v4.0.30319\\mscorsvw.exe", 313 | "command_line": None, 314 | "children": [] 315 | }, 316 | "5a5f1f8bf9b80413fff222a0a88c3c52c018f9539f0904590999d46c75df012b": { 317 | "image": "?sys32\\wevtutil.exe", 318 | "command_line": None, 319 | "children": [] 320 | }, 321 | '683045c417897765931f9c4de5799babaf16b2ab34a6a3a30eb442512c7df6cf': { 322 | "image": '?sys32\\svchost.exe', 323 | "command_line": None, 324 | "children": [ 325 | { 326 | "image": '?pf86\\microsoft\\edgeupdate\\microsoftedgeupdate.exe', 327 | "command_line": None, 328 | "children": [] 329 | } 330 | ] 331 | }, 332 | 'ca2681bddeb1b3c58f48ab9244d677808317cc73efb553bf6376621456696386': { 333 | "image": '?sys32\\svchost.exe', 334 | "command_line": None, 335 | "children": [ 336 | { 337 | "image": '?sys32\\wbem\\wmiprvse.exe', 338 | "command_line": None, 339 | "children": [] 340 | } 341 | ] 342 | }, 343 | '34f75b36eb062dd4e2fceecea864aeb679d15099f6b76d46d9e881cdc0c2565f': { 344 | "image": '?sys32\\svchost.exe', 345 | "command_line": None, 346 | "children": [ 347 | { 348 | "image": '?pf86\\windowsapps\\microsoft.yourphone_1.22022.180.0_x64__8wekyb3d8bbwe\\yourphone.exe', 349 | "command_line": None, 350 | "children": [] 351 | } 352 | ] 353 | }, 354 | 'd5eaaf0f58b9480f6d77d6f8cc07fc7de6f0100fd9cb20ffffcd4e3755ac2c91': { 355 | "image": '?sys32\\svchost.exe', 356 | "command_line": None, 357 | "children": [ 358 | { 359 | "image": '?win\\microsoft.net\\framework64\\v4.0.30319\\smsvchost.exe', 360 | "command_line": None, 361 | "children": [] 362 | } 363 | ] 364 | }, 365 | '9c1ab7458090e539853fc3467a646f6609bfd65562c493123a0a0bbbf8010756': { 366 | "image": '?sys32\\svchost.exe', 367 | "command_line": None, 368 | "children": [ 369 | { 370 | "image": '?sys32\\mqsvc.exe', 371 | "command_line": None, 372 | "children": [] 373 | } 374 | ] 375 | }, 376 | 'f2917a808064123e3affa565e9bcbe222ed377a586291c5db0c253647c094d44': { 377 | "image": '?sys32\\svchost.exe', 378 | "command_line": None, 379 | "children": [ 380 | { 381 | "image": '?sys32\\dwm.exe', 382 | "command_line": None, 383 | "children": [] 384 | } 385 | ] 386 | }, 387 | '31c722814723945f3a75457cc44353b4d3569c6a352af85dccafa182c58ad653': { 388 | "image": '?sys32\\svchost.exe', 389 | "command_line": None, 390 | "children": [ 391 | { 392 | "image": '?sys32\\fontdrvhost.exe', 393 | "command_line": None, 394 | "children": [] 395 | } 396 | ] 397 | }, 398 | 'eae18f81f6dd53ad84a780d67f1f91c6f8427e2aba53aeb3617e2c6a64ca6731': { 399 | "image": '?sys32\\svchost.exe', 400 | "command_line": None, 401 | "children": [ 402 | { 403 | "image": '?sys32\\sihost.exe', 404 | "command_line": None, 405 | "children": [] 406 | } 407 | ] 408 | }, 409 | 'aa43ef5d5f78c7017d4ba1ad33b988ca68e2a2635f5010d8c0bc8157816770c2': { 410 | "image": '?sys32\\ctfmon.exe', 411 | "command_line": None, 412 | "children": [] 413 | }, 414 | 'f26db097862af031c8a7ab84423f063be7f6e01f50699cdd3bfc23542af6a5b4': { 415 | "image": '?sys32\\services.exe', 416 | "command_line": None, 417 | "children": [ 418 | { 419 | "image": '?sys32\\svchost.exe', 420 | "command_line": 'C:\\WINDOWS\\System32\\svchost.exe -k netsvcs -p -s BITS', 421 | "children": [] 422 | } 423 | ] 424 | }, 425 | '44e862ebd67cd7ffe848064c41aa16111ec0d95c918bb792d1625df1d98b29aa': { 426 | "image": '?sys32\\smss.exe', 427 | "command_line": None, 428 | "children": [] 429 | }, 430 | '1851240177eab8d1db9cae2a230ba8f46f660b99de4324457bfad2b51346bef5': { 431 | "image": '?sys32\\svchost.exe', 432 | "command_line": None, 433 | "children": [ 434 | { 435 | "image": '?sys32\\searchfilterhost.exe', 436 | "command_line": None, 437 | "children": [] 438 | } 439 | ] 440 | }, 441 | '444f02be8905f4dc7be2ab190159644baebab2bd8ed351ceb6474ce317440f0c': { 442 | "image": '?sys32\\svchost.exe', 443 | "command_line": None, 444 | "children": [ 445 | { 446 | "image": '?sys32\\searchprotocolhost.exe', 447 | "command_line": None, 448 | "children": [] 449 | } 450 | ] 451 | }, 452 | '8c173d9b81725561674d18ec4e7c77d21f93b19384b342fbdf1592f5fc6300f3': { 453 | "image": '?sys32\\svchost.exe', 454 | "command_line": None, 455 | "children": [ 456 | { 457 | "image": '?sys32\\taskhost.exe', 458 | "command_line": None, 459 | "children": [] 460 | } 461 | ] 462 | }, 463 | '666cb65f44287de82e3b77628abd670990c78732e42ef209b4baaf6e5fe8bace': { 464 | "image": '?pf86\\microsoft\\edge\\application\\msedge.exe', 465 | "command_line": 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe', 466 | "children": [] 467 | }, 468 | '524241b8a3e1a062d8edf4058545fbd5c7300068c9c3cdffd4ea81c008553c99': { 469 | "image": '?pf86\\microsoft\\edge\\application\\106.0.1370.47\\identity_helper.exe', 470 | "command_line": 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\106.0.1370.47\\identity_helper.exe', 471 | "children": [] 472 | }, 473 | '4a18770b50a98be7d9960e4d556b882793139dbb850b3f78920fa97ea5d2e5f3': { 474 | "image": '?pf86\\microsoft\\edge\\application\\100.0.1185.29\\identity_helper.exe', 475 | "command_line": 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\100.0.1185.29\\identity_helper.exe', 476 | "children": [] 477 | }, 478 | '7a569f652c1711967a935feedac0a2bf196c3bd5a7e8f75f85f02c65fe48e188': { 479 | "image": '?pf86\\microsoft\\edge\\application\\106.0.1370.47\\bho\\ie_to_edge_stub.exe', 480 | "command_line": 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\106.0.1370.47\\BHO\\ie_to_edge_stub.exe', 481 | "children": [] 482 | }, 483 | '957447ee69253fe8bba3044bd46e7bd9623700c1f9d2e79376599dccd6498951': { 484 | "image": '?pf86\\microsoft\\edge\\application\\100.0.1185.29\\bho\\ie_to_edge_stub.exe', 485 | "command_line": 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\100.0.1185.29\\BHO\\ie_to_edge_stub.exe', 486 | "children": [] 487 | }, 488 | 'c7e4b5c4b3a1ae3fefaf965b87233e02beeb961c43e3844165979c69f199980d': { 489 | "image": '?pf86\\microsoft\\edge\\application\\msedge.exe|?pf86\\microsoft\\edge\\application\\msedge.exe', 490 | "command_line": '"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe" --type=crashpad-handler "--user-data-dir=C:\\Users\\buddy\\AppData\\Local\\Microsoft\\Edge\\User Data" /prefetch:7 --monitor-self-annotation=ptype=crashpad-handler "--database=C:\\Users\\buddy\\AppData\\Local\\Microsoft\\Edge\\User Data\\Crashpad" --annotation=IsOfficialBuild=1 --annotation=channel= --annotation=chromium-version=106.0.5249.119 "--annotation=exe=C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe" --annotation=plat=Win64 "--annotation=prod=Microsoft Edge" --annotation=ver=106.0.1370.47 --initial-client-data=0xe8,0xec,0xf0,0xb4,0xfc,0x7ffb13406e08,0x7ffb13406e18,0x7ffb13406e28', 491 | "children": [] 492 | }, 493 | '1b4a01c9672bc7575a1be176490f1e46b52bbfb88c5267a4b6c3d6b5c1ff3a95': { 494 | "image": '?pf86\\windowsapps\\microsoft.windows.photos_2022.30070.26007.0_x64__8wekyb3d8bbwe\\microsoft.photos.exe', 495 | "command_line": '"C:\\Program Files\\WindowsApps\\Microsoft.Windows.Photos_2022.30070.26007.0_x64__8wekyb3d8bbwe\\Microsoft.Photos.exe" -ServerName:App.AppXzst44mncqdg84v7sv6p7yznqwssy6f7f.mca', 496 | "children": [] 497 | }, 498 | '3d2d8f7a1bb607c13d1d86d9224439bef5c4e7f530e715bbc7fd2c1d25f83ed7': { 499 | "image": '?pf86\\windowsapps\\microsoft.yourphone_1.22022.180.0_x64__8wekyb3d8bbwe\\yourphone.exe', 500 | "command_line": '"C:\\Program Files\\WindowsApps\\Microsoft.YourPhone_1.22022.180.0_x64__8wekyb3d8bbwe\\YourPhone.exe" -ServerName:App.AppX9yct9q388jvt4h7y0gn06smzkxcsnt8m.mca', 501 | "children": [] 502 | }, 503 | } 504 | -------------------------------------------------------------------------------- /cuckoo/signatures.py: -------------------------------------------------------------------------------- 1 | # TODO: convert into list? 2 | CUCKOO_SIGNATURES = { 3 | "html_flash": "Exploit", 4 | "powershell_bitstransfer": "PowerShell", 5 | "powershell_empire": "Hacking tool", 6 | "locker_cmd": "Locker", 7 | "js_anti_analysis": "Anti-analysis", 8 | "pdf_javascript": "Suspicious PDF API", 9 | "application_sent_sms_messages": "Suspicious Android API", 10 | "android_antivirus_virustotal": "AntiVirus Hit", 11 | "antivm_vmware_keys": "Anti-vm", 12 | "antidbg_devices": "Anti-Debug", 13 | "worm_phorpiex": "Worm", 14 | "cloud_google": "Cloud", 15 | "jeefo_mutexes": "Virus", 16 | "rtf_unknown_version": "Suspicious Office", 17 | "ransomware_files": "Ransomware", 18 | "credential_dumping_lsass": "Persistence", 19 | "injection_explorer": "Injection", 20 | "dropper": "Dropper", 21 | "process_martian": "Suspicious Execution Chain", 22 | "trojan_redosru": "Trojan", 23 | "rat_delf": "RAT", 24 | "recon_beacon": "C2", 25 | "network_tor": "Tor", 26 | "smtp_gmail": "Web Mail", 27 | "antisandbox_cuckoo_files": "Anti-sandbox", 28 | "stealth_hide_notifications": "Stealth", 29 | "packer_entropy": "Packer", 30 | "banker_zeus_url": "Banker", 31 | "blackpos_url": "Point-of-sale", 32 | "exec_waitfor": "Bypass", 33 | "exec_crash": "Crash", 34 | "im_btb": "IM", 35 | "blackenergy_mutexes": "Rootkit", 36 | "browser_startpage": "Adware", 37 | "has_wmi": "WMI", 38 | "suspicious_write_exe": "Downloader", 39 | "dnsserver_dynamic": "DynDNS", 40 | "betabot_url": "BOT", 41 | "fraudtool_fakerean": "Fraud", 42 | "urlshortcn_checkip": "URLshort", 43 | "antiemu_wine": "Anti-emulation", 44 | "cryptomining_stratum_command": "Cryptocurrency", 45 | "network_bind": "Bind", 46 | "exploitkit_mutexes": "Exploit", 47 | "powershell_ddi_rc4": "PowerShell", 48 | "powershell_meterpreter": "Hacking tool", 49 | "locker_regedit": "Locker", 50 | "antianalysis_detectfile": "Anti-analysis", 51 | "pdf_attachments": "Suspicious PDF API", 52 | "application_using_the_camera": "Suspicious Android API", 53 | "antivirus_virustotal": "AntiVirus Hit", 54 | "antivm_generic_ide": "Anti-vm", 55 | "antidbg_windows": "Anti-Debug", 56 | "worm_psyokym": "Worm", 57 | "cloud_dropbox": "Cloud", 58 | "tufik_mutexes": "Virus", 59 | "rtf_unknown_character_set": "Suspicious Office", 60 | "modifies_desktop_wallpaper": "Ransomware", 61 | "credential_dumping_lsass_access": "Persistence", 62 | "injection_runpe": "Injection", 63 | "office_dde": "Dropper", 64 | "martian_command_process": "Suspicious Execution Chain", 65 | "trojan_dapato": "Trojan", 66 | "rat_naid_ip": "RAT", 67 | "multiple_useragents": "C2", 68 | "network_tor_service": "Tor", 69 | "smtp_yahoo": "Web Mail", 70 | "antisandbox_unhook": "Anti-sandbox", 71 | "stealth_system_procname": "Stealth", 72 | "packer_polymorphic": "Packer", 73 | "banker_zeus_mutex": "Banker", 74 | "pos_poscardstealer_url": "Point-of-sale", 75 | "applocker_bypass": "Bypass", 76 | "im_qq": "IM", 77 | "bootkit": "Rootkit", 78 | "installs_bho": "Adware", 79 | "disables_spdy_firefox": "Infostealer", 80 | "win32_process_create": "WMI", 81 | "downloader_cabby": "Downloader", 82 | "networkdyndns_checkip": "DynDNS", 83 | "warbot_url": "BOT", 84 | "stackpivot_shellcode_createprocess": "Rop", 85 | "clickfraud_cookies": "Fraud", 86 | "bitcoin_opencl": "Cryptocurrency", 87 | "powershell_dfsp": "PowerShell", 88 | "metasploit_shellcode": "Hacking tool", 89 | "locker_taskmgr": "Locker", 90 | "js_iframe": "Anti-analysis", 91 | "pdf_openaction": "Suspicious PDF API", 92 | "android_embedded_apk": "Suspicious Android API", 93 | "antivirus_irma": "Anti-antivirus", 94 | "antivm_virtualpc": "Anti-vm", 95 | "checks_debugger": "Anti-Debug", 96 | "krepper_mutexes": "Worm", 97 | "cloud_wetransfer": "Cloud", 98 | "dofoil": "Virus", 99 | "has_office_eps": "Suspicious Office", 100 | "ransomware_extensions": "Ransomware", 101 | "persistence_ads": "Persistence", 102 | "injection_createremotethread": "Injection", 103 | "exec_bits_admin": "Suspicious Execution Chain", 104 | "pidief": "Trojan", 105 | "bozok_key": "RAT", 106 | "dead_host": "C2", 107 | "network_torgateway": "Tor", 108 | "smtp_mail_ru": "Web Mail", 109 | "antisandbox_foregroundwindows": "Anti-sandbox", 110 | "modifies_security_center_warnings": "Stealth", 111 | "pe_features": "Packer", 112 | "banker_zeus_p2p": "Banker", 113 | "jackpos_file": "Point-of-sale", 114 | "bypass_firewall": "Bypass", 115 | "disables_spdy_ie": "Infostealer", 116 | "malicious_document_urls": "Downloader", 117 | "network_dns_txt_lookup": "DynDNS", 118 | "bot_vnloader_url": "BOT", 119 | "stack_pivot": "Rop", 120 | "browser_security": "Fraud", 121 | "miningpool": "Cryptocurrency", 122 | "dep_heap_bypass": "Exploit", 123 | "powershell_di": "PowerShell", 124 | "locates_sniffer": "Anti-analysis", 125 | "pdf_openaction_js": "Suspicious PDF API", 126 | "application_queried_phone_number": "Suspicious Android API", 127 | "antiav_bitdefender_libs": "Anti-antivirus", 128 | "antivm_vbox_devices": "Anti-vm", 129 | "checks_kernel_debugger": "Anti-Debug", 130 | "worm_allaple": "Worm", 131 | "cloud_mega": "Cloud", 132 | "office_indirect_call": "Suspicious Office", 133 | "ransomware_shadowcopy": "Ransomware", 134 | "deletes_executed_files": "Persistence", 135 | "injection_queueapcthread": "Injection", 136 | "uses_windows_utilities": "Suspicious Execution Chain", 137 | "obfus_mutexes": "Trojan", 138 | "rat_zegost": "RAT", 139 | "nolookup_communication": "C2", 140 | "smtp_live": "Web Mail", 141 | "antisandbox_sleep": "Anti-sandbox", 142 | "creates_null_reg_entry": "Stealth", 143 | "peid_packer": "Packer", 144 | "banker_prinimalka": "Banker", 145 | "alina_pos_file": "Point-of-sale", 146 | "amsi_bypass": "Bypass", 147 | "disables_spdy_chrome": "Infostealer", 148 | "network_wscript_downloader": "Downloader", 149 | "ponybot_url": "BOT", 150 | "TAPI_DP_mutex": "Fraud", 151 | "dep_stack_bypass": "Exploit", 152 | "powershell_unicorn": "PowerShell", 153 | "application_queried_private_information": "Suspicious Android API", 154 | "antivm_disk_size": "Anti-vm", 155 | "gaelicum": "Worm", 156 | "cloud_mediafire": "Cloud", 157 | "office_check_doc_name": "Suspicious Office", 158 | "ransomware_wbadmin": "Ransomware", 159 | "terminates_remote_process": "Persistence", 160 | "injection_resumethread": "Injection", 161 | "tnega_mutexes": "Trojan", 162 | "rat_plugx": "RAT", 163 | "snort_alert": "C2", 164 | "deepfreeze_mutex": "Anti-sandbox", 165 | "shutdown_system": "Stealth", 166 | "pe_unknown_resource_name": "Packer", 167 | "banker_spyeye_url": "Banker", 168 | "alina_pos_url": "Point-of-sale", 169 | "modifies_firefox_configuration": "Infostealer", 170 | "network_document_file": "Downloader", 171 | "solarbot_url": "BOT", 172 | "disables_browser_warn": "Fraud", 173 | "exploit_blackhole_url": "Exploit", 174 | "suspicious_powershell": "PowerShell", 175 | "android_native_code": "Suspicious Android API", 176 | "antiav_servicestop": "Anti-antivirus", 177 | "antivm_sandboxie": "Anti-vm", 178 | "worm_renocide": "Worm", 179 | "cloud_rapidshare": "Cloud", 180 | "office_platform_detect": "Suspicious Office", 181 | "ransomware_message": "Ransomware", 182 | "creates_service": "Persistence", 183 | "injection_modifies_memory": "Injection", 184 | "killdisk": "Trojan", 185 | "rat_netobserve": "RAT", 186 | "suricata_alert": "C2", 187 | "antisandbox_joe_anubis_files": "Anti-sandbox", 188 | "stealth_hidden_extension": "Stealth", 189 | "packer_upx": "Packer", 190 | "banker_spyeye_mutexes": "Banker", 191 | "jackpos_url": "Point-of-sale", 192 | "disables_ie_http2": "Infostealer", 193 | "network_downloader_exe": "Downloader", 194 | "ddos_blackrev_mutexes": "BOT", 195 | "sweetorange_mutexes": "Exploit", 196 | "powershell_c2dns": "PowerShell", 197 | "application_uses_location": "Suspicious Android API", 198 | "antiav_avast_libs": "Anti-antivirus", 199 | "antivm_xen_keys": "Anti-vm", 200 | "runouce_mutexes": "Worm", 201 | "document_close": "Suspicious Office", 202 | "ransomware_bcdedit": "Ransomware", 203 | "exe_appdata": "Persistence", 204 | "injection_write_memory": "Injection", 205 | "trojan_kilim": "Trojan", 206 | "rat_shadowbot": "RAT", 207 | "suspicious_tld": "C2", 208 | "antisandbox_threattrack_files": "Anti-sandbox", 209 | "moves_self": "Stealth", 210 | "packer_vmprotect": "Packer", 211 | "banker_cridex": "Banker", 212 | "dexter": "Point-of-sale", 213 | "emotet_behavior": "Infostealer", 214 | "creates_user_folder_exe": "Downloader", 215 | "ddos_darkddos_mutexes": "BOT", 216 | "js_eval": "Exploit", 217 | "powershell_reg_add": "PowerShell", 218 | "android_dangerous_permissions": "Suspicious Android API", 219 | "antiav_srp": "Anti-antivirus", 220 | "antivm_generic_scsi": "Anti-vm", 221 | "worm_kolabc": "Worm", 222 | "document_open": "Suspicious Office", 223 | "ransomware_file_moves": "Ransomware", 224 | "suspicious_command_tools": "Persistence", 225 | "task_for_pid": "Injection", 226 | "self_delete_bat": "Trojan", 227 | "rat_spynet": "RAT", 228 | "network_icmp": "C2", 229 | "antisandbox_restart": "Anti-sandbox", 230 | "reads_user_agent": "Stealth", 231 | "suspicious_process": "Suspicious Execution Chain", 232 | "banking_mutexes": "Banker", 233 | "decebal_mutexes": "Point-of-sale", 234 | "infostealer_derusbi_files": "Infostealer", 235 | "excel_datalink": "Downloader", 236 | "ddos_ipkiller_mutexes": "BOT", 237 | "js_suspicious": "Exploit", 238 | "powerworm": "PowerShell", 239 | "android_google_play_diff": "Suspicious Android API", 240 | "disables_security": "Anti-antivirus", 241 | "antivm_network_adapters": "Anti-vm", 242 | "vir_pykse": "Worm", 243 | "office_eps_strings": "Suspicious Office", 244 | "ransomware_appends_extensions": "Ransomware", 245 | "sysinternals_tools_usage": "Persistence", 246 | "darwin_code_injection": "Injection", 247 | "trojan_lockscreen": "Trojan", 248 | "rat_fynloski": "RAT", 249 | "network_http_post": "C2", 250 | "antisandbox_sunbelt_files": "Anti-sandbox", 251 | "disables_app_launch": "Stealth", 252 | "dyreza": "Banker", 253 | "infostealer_browser": "Infostealer", 254 | "ddos_eclipse_mutexes": "BOT", 255 | "powershell_download": "PowerShell", 256 | "application_queried_installed_apps": "Suspicious Android API", 257 | "antivm_generic_disk": "Anti-vm", 258 | "puce_mutexes": "Worm", 259 | "office_vuln_guid": "Suspicious Office", 260 | "ransomware_dropped_files": "Ransomware", 261 | "installs_appinit": "Persistence", 262 | "allocates_execute_remote_process": "Injection", 263 | "trojan_yoddos": "Trojan", 264 | "rat_turkojan": "RAT", 265 | "network_cnc_http": "C2", 266 | "antisandbox_idletime": "Anti-sandbox", 267 | "stealth_childproc": "Stealth", 268 | "dridex_behavior": "Banker", 269 | "sharpstealer_url": "Infostealer", 270 | "bot_russkill": "BOT", 271 | "powershell_request": "PowerShell", 272 | "application_aborted_broadcast_receiver": "Suspicious Android API", 273 | "stops_service": "Anti-antivirus", 274 | "antivm_firmware": "Anti-vm", 275 | "worm_palevo": "Worm", 276 | "office_vuln_modules": "Suspicious Office", 277 | "ransomware_recyclebin": "Ransomware", 278 | "persistence_registry_javascript": "Persistence", 279 | "injection_ntsetcontextthread": "Injection", 280 | "vir_nebuler": "Trojan", 281 | "rat_madness": "RAT", 282 | "p2p_cnc": "C2", 283 | "antisandbox_file": "Anti-sandbox", 284 | "disables_wer": "Stealth", 285 | "rovnix": "Banker", 286 | "pwdump_file": "Infostealer", 287 | "bot_athenahttp": "BOT", 288 | "application_deleted_app": "Suspicious Android API", 289 | "av_detect_china_key": "Anti-antivirus", 290 | "antivm_virtualpc_window": "Anti-vm", 291 | "worm_xworm": "Worm", 292 | "office_packager": "Suspicious Office", 293 | "ransomware_message_ocr": "Ransomware", 294 | "persistence_registry_exe": "Persistence", 295 | "injection_network_trafic": "Injection", 296 | "trojan_jorik": "Trojan", 297 | "rat_mybot": "RAT", 298 | "network_smtp": "C2", 299 | "antisandbox_clipboard": "Anti-sandbox", 300 | "creates_largekey": "Stealth", 301 | "banker_bancos": "Banker", 302 | "istealer_url": "Infostealer", 303 | "bot_madness": "BOT", 304 | "recon_checkip": "Exploit", 305 | "application_installed_app": "Suspicious Android API", 306 | "bagle": "Worm", 307 | "office_create_object": "Suspicious Office", 308 | "disables_system_restore": "Ransomware", 309 | "persistence_registry_powershell": "Persistence", 310 | "injection_write_memory_exe": "Injection", 311 | "banload": "Trojan", 312 | "rat_blackshades": "RAT", 313 | "network_irc": "C2", 314 | "antisandbox_fortinet_files": "Anti-sandbox", 315 | "modify_uac_prompt": "Stealth", 316 | "targeted_flame": "Infostealer", 317 | "bot_dirtjumper": "BOT", 318 | "recon_programs": "Exploit", 319 | "application_queried_account_info": "Suspicious Android API", 320 | "antivm_vbox_acpi": "Anti-vm", 321 | "worm_rungbu": "Worm", 322 | "office_check_project_name": "Suspicious Office", 323 | "ransomware_mass_file_delete": "Ransomware", 324 | "persistence_autorun": "Persistence", 325 | "powerfun": "Injection", 326 | "trojan_mrblack": "Trojan", 327 | "rat_beastdoor": "RAT", 328 | "memdump_tor_urls": "C2", 329 | "antisandbox_mouse_hook": "Anti-sandbox", 330 | "stealth_hidden_icons": "Stealth", 331 | "disables_proxy": "Infostealer", 332 | "bot_drive2": "BOT", 333 | "queries_programs": "Exploit", 334 | "android_reflection_code": "Suspicious Android API", 335 | "antivm_parallels_keys": "Anti-vm", 336 | "fesber_mutexes": "Worm", 337 | "office_count_dirs": "Suspicious Office", 338 | "ransomware_viruscoder": "Ransomware", 339 | "persistence_bootexecute": "Persistence", 340 | "allocates_rwx": "Injection", 341 | "trojan_vbinject": "Trojan", 342 | "rat_swrort": "RAT", 343 | "memdump_ip_urls": "C2", 344 | "antisandbox_sunbelt": "Anti-sandbox", 345 | "stealth_window": "Stealth", 346 | "infostealer_bitcoin": "Infostealer", 347 | "bot_drive": "BOT", 348 | "recon_systeminfo": "Exploit", 349 | "android_dynamic_code": "Suspicious Android API", 350 | "antivm_vbox_keys": "Anti-vm", 351 | "winsxsbot": "Worm", 352 | "office_appinfo_version": "Suspicious Office", 353 | "nymaim_behavior": "Ransomware", 354 | "javascript_commandline": "Persistence", 355 | "memdump_urls": "Injection", 356 | "trojan_pincav": "Trojan", 357 | "rat_beebus_mutexes": "RAT", 358 | "dns_freehosting_domain": "C2", 359 | "stealth_hiddenfile": "Stealth", 360 | "infostealer_clipboard": "Infostealer", 361 | "c24_url": "BOT", 362 | "application_stopped_processes": "Suspicious Android API", 363 | "antivm_vmware_window": "Anti-vm", 364 | "office_check_window": "Suspicious Office", 365 | "chanitor_mutexes": "Ransomware", 366 | "privilege_luid_check": "Persistence", 367 | "protection_rx": "Injection", 368 | "trojan_lethic": "Trojan", 369 | "rat_bifrose": "RAT", 370 | "creates_hidden_file": "Stealth", 371 | "infostealer_ftp": "Infostealer", 372 | "bot_kelihos": "BOT", 373 | "application_registered_receiver_runtime": "Suspicious Android API", 374 | "antivm_vmware_files": "Anti-vm", 375 | "office_http_request": "Suspicious Office", 376 | "cryptlocker": "Ransomware", 377 | "wmi_persistance": "Persistence", 378 | "shellcode_writeprocessmemory": "Injection", 379 | "trojan_sysn": "Trojan", 380 | "rat_fexel_ip": "RAT", 381 | "clears_event_logs": "Stealth", 382 | "perflogger": "Infostealer", 383 | "bot_kovter": "BOT", 384 | "application_executed_shell_command": "Suspicious Android API", 385 | "antivm_hyperv_keys": "Anti-vm", 386 | "office_recent_files": "Suspicious Office", 387 | "wmi_service": "Persistence", 388 | "injection_process_search": "Injection", 389 | "coinminer_mutexes": "Trojan", 390 | "rat_vertex": "RAT", 391 | "clear_permission_event_logs": "Stealth", 392 | "jintor_mutexes": "Infostealer", 393 | "application_recording_audio": "Suspicious Android API", 394 | "antivm_virtualpc_illegal_instruction": "Anti-vm", 395 | "creates_doc": "Suspicious Office", 396 | "creates_shortcut": "Persistence", 397 | "memdump_yara": "Injection", 398 | "trojan_ceatrg": "Trojan", 399 | "rat_hupigon": "RAT", 400 | "bad_certificate": "Stealth", 401 | "ardamax_mutexes": "Infostealer", 402 | "antivm_parallels_window": "Anti-vm", 403 | "modifies_boot_config": "Persistence", 404 | "dumped_buffer2": "Injection", 405 | "renostrojan": "Trojan", 406 | "rat_dibik": "RAT", 407 | "has_authenticode": "Stealth", 408 | "infostealer_keylogger": "Infostealer", 409 | "antivm_vbox_provname": "Anti-vm", 410 | "adds_user": "Persistence", 411 | "dumped_buffer": "Injection", 412 | "trojan_emotet": "Trojan", 413 | "rat_blackhole": "RAT", 414 | "removes_zoneid_ads": "Stealth", 415 | "infostealer_im": "Infostealer", 416 | "antivm_vbox_files": "Anti-vm", 417 | "adds_user_admin": "Persistence", 418 | "process_interest": "Injection", 419 | "athena_url": "Trojan", 420 | "modifies_zoneid": "Stealth", 421 | "antivm_generic_services": "Anti-vm", 422 | "disables_windowsupdate": "Persistence", 423 | "begseabugtd_mutexes": "Trojan", 424 | "rat_jewdo": "RAT", 425 | "modifies_proxy_autoconfig": "Infostealer", 426 | "creates_exe": "Persistence", 427 | "carberp_mutex": "Trojan", 428 | "rat_blackice": "RAT", 429 | "modifies_proxy_override": "Infostealer", 430 | "antivm_vbox_window": "Anti-vm", 431 | "upatretd_mutexes": "Trojan", 432 | "rat_adzok": "RAT", 433 | "antivm_vmware_in_instruction": "Anti-vm", 434 | "rat_pasta": "RAT", 435 | "isrstealer_url": "Infostealer", 436 | "antivm_generic_cpu": "Anti-vm", 437 | "rat_xtreme": "RAT", 438 | "console_output": "Infostealer", 439 | "antivm_generic_bios": "Anti-vm", 440 | "rat_rbot": "RAT", 441 | "antivm_shared_device": "Anti-vm", 442 | "rat_flystudio": "RAT", 443 | "antivm_vpc_keys": "Anti-vm", 444 | "rat_likseput": "RAT", 445 | "wmi_antivm": "Anti-vm", 446 | "rat_urxbot": "RAT", 447 | "antivm_queries_computername": "Anti-vm", 448 | "rat_pcclient": "RAT", 449 | "rat_hikit": "RAT", 450 | "rat_trogbot": "RAT", 451 | "rat_darkshell": "RAT", 452 | "rat_siggenflystudio": "RAT", 453 | "rat_travnet": "RAT", 454 | "rat_bottilda": "RAT", 455 | "rat_koutodoor": "RAT", 456 | "rat_buzus_mutexes": "RAT", 457 | "rat_comRAT": "RAT", 458 | "poebot": "RAT", 459 | "oldrea": "RAT", 460 | "ircbrute": "RAT", 461 | "expiro": "RAT", 462 | "staser": "RAT", 463 | "netshadow": "RAT", 464 | "shylock": "RAT", 465 | "ddos556": "RAT", 466 | "cybergate": "RAT", 467 | "kuluoz_mutexes": "RAT", 468 | "senna": "RAT", 469 | "ramnit": "RAT", 470 | "magania_mutexes": "RAT", 471 | "virut": "RAT", 472 | "njrat": "RAT", 473 | "evilbot": "RAT", 474 | "shiza": "RAT", 475 | "nakbot": "RAT", 476 | "sadbot": "RAT", 477 | "minerbot": "RAT", 478 | "upatre": "RAT", 479 | "trojan_bublik": "RAT", 480 | "uroburos_mutexes": "RAT", 481 | "darkcloud": "RAT", 482 | "farfli": "RAT", 483 | "urlspy": "RAT", 484 | "bladabindi_mutexes": "RAT", 485 | "ponfoy": "RAT", 486 | "decay": "RAT", 487 | "UFR_Stealer": "RAT", 488 | "qakbot": "RAT", 489 | "nitol": "RAT", 490 | "icepoint": "RAT", 491 | "andromeda": "RAT", 492 | "bandook": "RAT", 493 | "banker_tinba_mutexes": "RAT", 494 | "btc": "RAT", 495 | "fakeav_mutexes": "RAT", 496 | "ghostbot": "RAT", 497 | "hesperbot": "RAT", 498 | "infinity": "RAT", 499 | "karagany": "RAT", 500 | "karakum": "RAT", 501 | "katusha": "RAT", 502 | "koobface": "RAT", 503 | "luder": "RAT", 504 | "netwire": "RAT", 505 | "poisonivy": "RAT", 506 | "putterpanda_mutexes": "RAT", 507 | "ragebot": "RAT", 508 | "rdp_mutexes": "RAT", 509 | "spyrecorder": "RAT", 510 | "uroburos_file": "RAT", 511 | "vnc_mutexes": "RAT", 512 | "wakbot": "RAT", 513 | "generates_crypto_key": "Stealth", 514 | "network_http": "C2", 515 | "process_needed": "Suspicious Execution Chain", 516 | "winmgmts_process_create": "WMI", 517 | "dll_load_uncommon_file_types": "Suspicious DLL", 518 | "antiav_whitespace": "Anti-antivirus", 519 | "office_uses_wmi": "WMI", 520 | "network_ip_exe": "Downloader", 521 | } 522 | 523 | CUCKOO_SIGNATURE_CATEGORIES = { 524 | "Exploit": { 525 | "id": 1, 526 | "description": "Exploits an known software vulnerability or security flaw." 527 | }, 528 | "PowerShell": { 529 | "id": 2, 530 | "description": "Leverages Powershell to attack Windows operating systems." 531 | }, 532 | "Hacking tool": { 533 | "id": 3, 534 | "description": "Programs designed to crack or break computer and network security measures." 535 | }, 536 | "Locker": { 537 | "id": 4, 538 | "description": "Prevents access to system data and files." 539 | }, 540 | "Anti-analysis": { 541 | "id": 5, 542 | "description": "Constructed to conceal or obfuscate itself to prevent analysis." 543 | }, 544 | "Suspicious PDF API": { 545 | "id": 6, 546 | "description": "Makes API calls not consistent with expected/standard behaviour." 547 | }, 548 | "Suspicious Android API": { 549 | "id": 7, 550 | "description": "Makes API calls not consistent with expected/standard behaviour." 551 | }, 552 | "Anti-antivirus": { 553 | "id": 8, 554 | "description": "Attempts to conceal itself from detection by anti-virus." 555 | }, 556 | "Anti-vm": { 557 | "id": 9, 558 | "description": "Attempts to detect if it is being run in virtualized environment." 559 | }, 560 | "Anti-Debug": { 561 | "id": 10, 562 | "description": "Attempts to detect if it is being debugged." 563 | }, 564 | "Worm": { 565 | "id": 11, 566 | "description": "Attempts to replicate itself in order to spread to other systems." 567 | }, 568 | "Cloud": { 569 | "id": 12, 570 | "description": "Makes connection to cloud service." 571 | }, 572 | "Virus": { 573 | "id": 13, 574 | "description": "Malicious software program" 575 | }, 576 | "Suspicious Office": { 577 | "id": 14, 578 | "description": "Makes API calls not consistent with expected/standard behaviour" 579 | }, 580 | "Ransomware": { 581 | "id": 15, 582 | "description": "Designed to block access to a system until a sum of money is paid." 583 | }, 584 | "Persistence": { 585 | "id": 16, 586 | "description": "Technique used to maintain presence in system(s) across interruptions that could cut off access." 587 | }, 588 | "Injection": { 589 | "id": 17, 590 | "description": "Input is not properly validated and gets processed by an interpreter as part of a command or query." 591 | }, 592 | "Dropper": { 593 | "id": 18, 594 | "description": "Trojan that drops additional malware on an affected system." 595 | }, 596 | "Suspicious Execution Chain": { 597 | "id": 19, 598 | "description": "Command shell or script process was created by unexpected parent process." 599 | }, 600 | "Trojan": { 601 | "id": 20, 602 | "description": "Presents itself as legitimate in attempt to infiltrate a system." 603 | }, 604 | "RAT": { 605 | "id": 21, 606 | "description": "Designed to provide the capability of covert surveillance and/or unauthorized access to a target." 607 | }, 608 | "C2": { 609 | "id": 22, 610 | "description": "Communicates with a server controlled by a malicious actor." 611 | }, 612 | "Tor": { 613 | "id": 23, 614 | "description": "Intalls/Leverages Tor to enable anonymous communication." 615 | }, 616 | "Web Mail": { 617 | "id": 24, 618 | "description": "Connects to smtp.[domain] for possible spamming or data exfiltration." 619 | }, 620 | "Anti-sandbox": { 621 | "id": 25, 622 | "description": "Attempts to detect if it is in a sandbox." 623 | }, 624 | "Stealth": { 625 | "id": 26, 626 | "description": "Leverages/modifies internal processes and settings to conceal itself." 627 | }, 628 | "Packer": { 629 | "id": 27, 630 | "description": "Compresses, encrypts, and/or modifies a malicious file's format." 631 | }, 632 | "Banker": { 633 | "id": 28, 634 | "description": "Designed to gain access to confidential information stored or processed through online banking." 635 | }, 636 | "Point-of-sale": { 637 | "id": 29, 638 | "description": "Steals information related to financial transactions, including credit card information." 639 | }, 640 | "Bypass": { 641 | "id": 30, 642 | "description": "Attempts to bypass operating systems security controls (firewall, amsi, applocker, etc.)" 643 | }, 644 | "Crash": { 645 | "id": 31, 646 | "description": "Attempts to crash the system." 647 | }, 648 | "IM": { 649 | "id": 32, 650 | "description": "Leverages instant-messaging." 651 | }, 652 | "Rootkit": { 653 | "id": 33, 654 | "description": "Designed to provide continued privileged access to a system while actively hiding its presence." 655 | }, 656 | "Adware": { 657 | "id": 34, 658 | "description": "Displays unwanted, unsolicited advertisements." 659 | }, 660 | "Infostealer": { 661 | "id": 35, 662 | "description": "Collects and disseminates information such as login details, usernames, passwords, etc." 663 | }, 664 | "WMI": { 665 | "id": 36, 666 | "description": "Leverages Windows Management Instrumentation (WMI) to gather information and/or execute a process." 667 | }, 668 | "Downloader": { 669 | "id": 37, 670 | "description": "Trojan that downloads installs files." 671 | }, 672 | "DynDNS": { 673 | "id": 38, 674 | "description": "Utilizes dynamic DNS." 675 | }, 676 | "BOT": { 677 | "id": 39, 678 | "description": "Appears to be a bot or exhibits bot-like behaviour." 679 | }, 680 | "Rop": { 681 | "id": 40, 682 | "description": "Exploits trusted programs to execute malicious code from memory to evade data execution prevention." 683 | }, 684 | "Fraud": { 685 | "id": 41, 686 | "description": "Presents itself as a legitimate program and/or facilitates fraudulent activity." 687 | }, 688 | "URLshort": { 689 | "id": 42, 690 | "description": "Leverages URL shortening to obfuscate malicious destination." 691 | }, 692 | "Anti-emulation": { 693 | "id": 43, 694 | "description": "Detects the presence of an emulator." 695 | }, 696 | "Cryptocurrency": { 697 | "id": 44, 698 | "description": "Facilitates mining of cryptocurrency." 699 | }, 700 | "Bind": { 701 | "id": 45, 702 | "description": "Allows a resource to be sent or received across a network." 703 | }, 704 | "Suspicious DLL": { 705 | "id": 46, 706 | "description": "Attempts to load DLL that is inconsistent with expected/standard behaviour." 707 | }, 708 | "AntiVirus Hit": { 709 | "id": 1008, 710 | "description": "AntiVirus hit. File is infected." 711 | } 712 | } 713 | 714 | CUCKOO_DROPPED_SIGNATURES = [ 715 | 'origin_langid', 'apt_cloudatlas', 'apt_carbunak', 'apt_sandworm_ip', 716 | 'apt_turlacarbon', 'apt_sandworm_url', 'apt_inception', 'rat_lolbot', 717 | 'backdoor_vanbot', 'rat_sdbot', 'backdoor_tdss', 'backdoor_whimoo', 718 | 'madness_url', 'volatility_svcscan_2', 'volatility_svcscan_3', 719 | 'volatility_modscan_1', 'volatility_handles_1', 'volatility_devicetree_1', 720 | 'volatility_ldrmodules_1', 'volatility_ldrmodules_2', 'volatility_malfind_2', 721 | 'volatility_svcscan_1', 'detect_putty', 'powerworm', 'powershell_ddi_rc4', 722 | 'powershell_di', 'powerfun', 'powershell_dfsp', 'powershell_c2dns', 723 | 'powershell_unicorn', 'spreading_autoruninf', 'sniffer_winpcap', 724 | 'mutex_winscp', 'sharing_rghost', 'exp_3322_dom', 'mirc_file', 'vir_napolar', 725 | 'vertex_url', 'has_pdb', "process_martian", "rat_teamviewer", "antiav_detectfile", 726 | "antiav_detectreg", "api_hammering", "raises_exception", "antivm_memory_available", 727 | "recon_fingerprint", "application_raises_exception", "modifies_certificates", 728 | "modifies_proxy_wpad", "stack_pivot_shellcode_apis", "infostealer_mail", "locates_browser", 729 | "exploit_heapspray", "network_irc", 730 | ] 731 | 732 | 733 | def get_category_id(sig: str) -> int: 734 | """ 735 | This method returns the category ID for a given signature name 736 | :param sig: given signature name 737 | :return: the category ID 738 | """ 739 | category = CUCKOO_SIGNATURES.get(sig, "unknown") 740 | metadata = CUCKOO_SIGNATURE_CATEGORIES.get(category, {}) 741 | return metadata.get("id", 9999) 742 | 743 | 744 | def get_signature_category(sig: str) -> str: 745 | """ 746 | This method returns the category for a given signature name 747 | :param sig: given signature name 748 | :return: The category name 749 | """ 750 | return CUCKOO_SIGNATURES.get(sig, "unknown") 751 | 752 | 753 | SIGNATURE_TO_ATTRIBUTE_ACTION_MAP = { 754 | # Signature Name : attribute action that is relevant 755 | "dead_connect": "network_connection", 756 | "antidebug_setunhandledexceptionfilter": "process_tampering", 757 | "dynamic_function_loading": "driver_loaded", 758 | "process_needed": "process_access", 759 | "injection_network_traffic": "network_connection", 760 | "explorer_http": "network_connection", 761 | "deletes_self": "file_delete", 762 | "removes_zoneid_ads": "registry_delete", 763 | } 764 | -------------------------------------------------------------------------------- /tests/test_cuckoo_result.py: -------------------------------------------------------------------------------- 1 | import json 2 | from ipaddress import ip_network 3 | from json import dumps 4 | from os import remove 5 | 6 | import pytest 7 | from assemblyline_service_utilities.common.dynamic_service_helper import OntologyResults 8 | from assemblyline_v4_service.common.result import ( 9 | BODY_FORMAT, 10 | ProcessItem, 11 | ResultProcessTreeSection, 12 | ResultSection, 13 | ResultTableSection, 14 | TableRow, 15 | ) 16 | from cuckoo.cuckoo_result import * 17 | from cuckoo.cuckoo_result import ( 18 | _extract_iocs_from_encrypted_buffers, 19 | _get_dns_map, 20 | _get_dns_sec, 21 | _get_low_level_flows, 22 | _handle_http_headers, 23 | _is_signature_a_false_positive, 24 | _process_http_calls, 25 | _process_non_http_traffic_over_http, 26 | _remove_network_http_noise, 27 | _update_process_map, 28 | _write_console_output_to_file, 29 | _write_injected_exe_to_file, 30 | ) 31 | from test_cuckoo_main import check_section_equality, create_tmp_manifest, remove_tmp_manifest 32 | 33 | 34 | class TestCuckooResult: 35 | @classmethod 36 | def setup_class(cls): 37 | create_tmp_manifest() 38 | 39 | @classmethod 40 | def teardown_class(cls): 41 | remove_tmp_manifest() 42 | 43 | @staticmethod 44 | @pytest.mark.parametrize( 45 | "api_report", 46 | [({}), 47 | ({"info": {"id": "blah"}, 48 | "debug": "blah", "signatures": [{"name": "blah"}], 49 | "network": "blah", "behavior": {"blah": "blah"}, 50 | "curtain": "blah", "sysmon": {}, 51 | "hollowshunter": "blah"}), 52 | ({"info": {"id": "blah"}, 53 | "debug": "blah", "signatures": [{"name": "ransomware"}], 54 | "network": "blah", "behavior": {"blah": "blah"}, 55 | "curtain": "blah", "sysmon": {}, 56 | "hollowshunter": "blah"}), 57 | ({"signatures": [{"name": "blah"}], 58 | "info": {"id": "blah"}, 59 | "behavior": {"summary": "blah"}}), 60 | ({"signatures": [{"name": "blah"}], 61 | "info": {"id": "blah"}, 62 | "behavior": {"processtree": "blah"}}), 63 | ({"signatures": [{"name": "blah"}], 64 | "info": {"id": "blah"}, "behavior": {"processes": "blah"}}), ]) 65 | def test_generate_al_result(api_report, mocker): 66 | correct_process_map = {"blah": "blah"} 67 | mocker.patch("cuckoo.cuckoo_result.process_info") 68 | mocker.patch("cuckoo.cuckoo_result.process_debug") 69 | mocker.patch("cuckoo.cuckoo_result.get_process_map", return_value=correct_process_map) 70 | mocker.patch("cuckoo.cuckoo_result.process_signatures", return_value=False) 71 | mocker.patch("cuckoo.cuckoo_result.convert_sysmon_processes", return_value=None) 72 | mocker.patch("cuckoo.cuckoo_result.convert_sysmon_network", return_value=None) 73 | mocker.patch("cuckoo.cuckoo_result.process_behaviour", return_value=["blah"]) 74 | mocker.patch("cuckoo.cuckoo_result.process_network", return_value=["blah"]) 75 | mocker.patch("cuckoo.cuckoo_result.process_all_events") 76 | mocker.patch("cuckoo.cuckoo_result.build_process_tree") 77 | mocker.patch("cuckoo.cuckoo_result.process_curtain") 78 | mocker.patch("cuckoo.cuckoo_result.process_hollowshunter") 79 | mocker.patch("cuckoo.cuckoo_result.process_decrypted_buffers") 80 | so = OntologyResults() 81 | al_result = ResultSection("blah") 82 | file_ext = "blah" 83 | safelist = {} 84 | generate_al_result(api_report, al_result, file_ext, ip_network("192.0.2.0/24"), "blah", False, safelist, so) 85 | 86 | if api_report == {}: 87 | assert al_result.subsections == [] 88 | elif api_report.get("behavior") == {"blah": "blah"}: 89 | correct_result_section = ResultSection( 90 | title_text='Sample Did Not Execute', 91 | body=f'No program available to execute a file with the following extension: {file_ext}') 92 | assert check_section_equality(al_result.subsections[0], correct_result_section) 93 | else: 94 | assert al_result.subsections == [] 95 | 96 | @staticmethod 97 | @pytest.mark.parametrize( 98 | "info, correct_body, expected_am", 99 | [({"started": "blah", "ended": "blah", "duration": "blah", "id": 1, "route": "blah", "version": "blah"}, 100 | '{"Cuckoo Task ID": 1, "Duration": -1, "Routing": "blah", "Cuckoo Version": "blah"}', 101 | {"routing": "blah", "start_time": "1-01-01 00:00:00.000000", "end_time": "9999-12-31 23:59:59.999999", "task_id": 1}), 102 | ({"started": "1", "ended": "1", "duration": "1", "id": 1, "route": "blah", "version": "blah"}, 103 | '{"Cuckoo Task ID": 1, "Duration": "00h 00m 01s\\t(1970-01-01 00:00:01.000 to 1970-01-01 00:00:01.000)", "Routing": "blah", "Cuckoo Version": "blah"}', 104 | {"routing": "blah", "start_time": "1970-01-01 00:00:01.000", "end_time": "1970-01-01 00:00:01.000", "task_id": 1}), 105 | ({"id": 1, "started": "1", "ended": "1", "duration": "1", "route": "blah", "version": "blah"}, 106 | '{"Cuckoo Task ID": 1, "Duration": "00h 00m 01s\\t(1970-01-01 00:00:01.000 to 1970-01-01 00:00:01.000)", "Routing": "blah", "Cuckoo Version": "blah"}', 107 | {"routing": "blah", "start_time": "1970-01-01 00:00:01.000", "end_time": "1970-01-01 00:00:01.000", "task_id": 1}), ]) 108 | def test_process_info(info, correct_body, expected_am): 109 | al_result = ResultSection("blah") 110 | so = OntologyResults(service_name="Cuckoo") 111 | # default_am = so.analysis_metadata.as_primitives() 112 | process_info(info, "blah", al_result, so) 113 | correct_res_sec = ResultSection("Analysis Information") 114 | correct_res_sec.set_body(correct_body, BODY_FORMAT.KEY_VALUE) 115 | assert check_section_equality(al_result.subsections[0], correct_res_sec) 116 | # for key, value in expected_am.items(): 117 | # default_am[key] = value 118 | expected_am["machine_metadata"] = None 119 | assert so.sandboxes[0].analysis_metadata.as_primitives() == expected_am 120 | assert so.sandboxes[0].sandbox_version == "blah" 121 | 122 | @staticmethod 123 | @pytest.mark.parametrize( 124 | "debug, correct_body, expected_result", 125 | [ 126 | ({"errors": [], "log": [], "cuckoo": []}, None, False), 127 | ({"errors": ["BLAH"], "log": [], "cuckoo": []}, "BLAH", False), 128 | ({"errors": ["BLAH", "BLAH"], "log": [], "cuckoo": []}, "BLAH\nBLAH", False), 129 | ({"errors": [], "log": ["blah"], "cuckoo": []}, None, False), 130 | ({"errors": [], "log": ["ERROR: blah"], "cuckoo": []}, "blah", False), 131 | ({"errors": [], "log": ["ERROR: blah", "ERROR: blah\n"], "cuckoo": []}, "blah\nblah", False), 132 | ({"errors": [], "log": [], "cuckoo": ["blah"]}, None, False), 133 | ({"errors": [], "log": [], "cuckoo": ["blah", "\n"]}, "blah", False), 134 | ({"errors": [], "log": [], "cuckoo": ["blah", "\n", "ERROR: blah"]}, "blah\nblah", False), 135 | ({"errors": [], "log": [], "cuckoo": [ 136 | "Virtual Machine /status failed. This can indicate the guest losing network connectivity", 137 | "Virtual Machine /status failed. This can indicate the guest losing network connectivity", 138 | "Virtual Machine /status failed. This can indicate the guest losing network connectivity", 139 | "Virtual Machine /status failed. This can indicate the guest losing network connectivity", 140 | "Virtual Machine /status failed. This can indicate the guest losing network connectivity", 141 | "Virtual Machine /status failed. This can indicate the guest losing network connectivity", 142 | ]}, 143 | 'it appears that this Virtual Machine hasn\'t been configured properly as the Cuckoo Host wasn\'t able to connect to the Guest.', False), 144 | ({"errors": [], "log": [], "cuckoo": ["blah Unable to execute the initial process, analysis aborted. blah"]}, None, True), 145 | ] 146 | ) 147 | def test_process_debug(debug, correct_body, expected_result): 148 | al_result = ResultSection("blah") 149 | assert process_debug(debug, al_result) == expected_result 150 | 151 | if correct_body is None: 152 | assert al_result.subsections == [] 153 | else: 154 | correct_result_section = ResultSection(title_text='Analysis Errors') 155 | correct_result_section.set_body(correct_body) 156 | assert check_section_equality(al_result.subsections[0], correct_result_section) 157 | 158 | @staticmethod 159 | @pytest.mark.parametrize( 160 | "behaviour", 161 | [ 162 | ({"processes": []}), 163 | ({"processes": ["blah"], "apistats": {"blah": "blah"}}) 164 | ] 165 | ) 166 | def test_process_behaviour(behaviour, mocker): 167 | mocker.patch("cuckoo.cuckoo_result.get_process_api_sums", return_value={"blah": "blah"}) 168 | mocker.patch("cuckoo.cuckoo_result.convert_cuckoo_processes") 169 | safelist = {} 170 | so = OntologyResults() 171 | process_behaviour(behaviour, safelist, so) 172 | # Code coverage! 173 | assert True 174 | 175 | @staticmethod 176 | @pytest.mark.parametrize( 177 | "apistats, correct_api_sums", 178 | [ 179 | ({}, {}), 180 | ({"0": {"blah": 2}}, {"0": 2}), 181 | ] 182 | ) 183 | def test_get_process_api_sums(apistats, correct_api_sums): 184 | assert get_process_api_sums(apistats) == correct_api_sums 185 | 186 | @staticmethod 187 | @pytest.mark.parametrize( 188 | "processes, correct_event", 189 | [([{"pid": 0, "process_path": "blah", "command_line": "blah", "ppid": 1, 190 | "guid": "{12345678-1234-5678-1234-567812345678}", "pguid": "{12345678-1234-5678-1234-567812345679}", 191 | "first_seen": 1.0}], 192 | {'start_time': "1970-01-01 00:00:01.000", 'end_time': "9999-12-31 23:59:59.999999", 193 | 'objectid': 194 | {'guid': '{12345678-1234-5678-1234-567812345678}', 'tag': 'blah', 'treeid': None, 195 | 'time_observed': "1970-01-01 00:00:01.000", 'ontology_id': 'process_2YK9t8RtV7Kuz78PASKGw0', 'service_name': 'Cuckoo', 196 | 'processtree': None}, 197 | 'pobjectid': None, 198 | 'pimage': None, 'pcommand_line': None, 'ppid': 1, 'pid': 0, 'image': 'blah', 'command_line': 'blah', 199 | 'integrity_level': None, 'image_hash': None, 'original_file_name': None}), 200 | ([{"pid": 0, "process_path": "", "command_line": "blah", "ppid": 1, 201 | "guid": "{12345678-1234-5678-1234-567812345678}", "first_seen": 1.0}], 202 | {}), 203 | ([], 204 | {})]) 205 | def test_convert_cuckoo_processes(processes, correct_event, mocker): 206 | safelist = {} 207 | so = OntologyResults(service_name="Cuckoo") 208 | mocker.patch.object(so, "sandboxes", return_value="blah") 209 | convert_cuckoo_processes(processes, safelist, so) 210 | if correct_event: 211 | proc_as_prims = so.get_processes()[0].as_primitives() 212 | _ = proc_as_prims["objectid"].pop("session") 213 | assert proc_as_prims == correct_event 214 | else: 215 | assert so.get_processes() == [] 216 | 217 | @staticmethod 218 | @pytest.mark.parametrize( 219 | "events, is_process_martian, correct_body", 220 | [ 221 | ( 222 | [ 223 | { 224 | "pid": 0, 225 | "image": "blah", 226 | "command_line": "blah", 227 | "ppid": 1, 228 | "guid": "{12345678-1234-5678-1234-567812345678}", 229 | "start_time": "1970-01-01 00:00:01.000", 230 | "pguid": "{12345678-1234-5678-1234-567812345678}", 231 | "objectid": OntologyResults.create_objectid(tag="blah", ontology_id="blah", service_name="Cuckoo") 232 | } 233 | ], 234 | False, 235 | { 236 | "pid": 0, 237 | "name": "blah", 238 | "cmd": "blah", 239 | "signatures": {}, 240 | "children": [], 241 | } 242 | ), 243 | ( 244 | [ 245 | { 246 | "pid": 0, 247 | "image": "blah", 248 | "command_line": "blah", 249 | "ppid": 1, 250 | "guid": "{12345678-1234-5678-1234-567812345678}", 251 | "start_time": "1970-01-01 00:00:01.000", 252 | "pguid": "{12345678-1234-5678-1234-567812345678}", 253 | "objectid": OntologyResults.create_objectid(tag="blah", ontology_id="blah", service_name="Cuckoo") 254 | } 255 | ], 256 | True, 257 | { 258 | "pid": 0, 259 | "name": "blah", 260 | "cmd": "blah", 261 | "signatures": {}, 262 | "children": [], 263 | } 264 | ), 265 | ( 266 | [], 267 | False, 268 | None 269 | ), 270 | ( 271 | [ 272 | { 273 | "pid": 0, 274 | "image": "C:\\Users\\buddy\\AppData\\Local\\Temp\\blah.exe", 275 | "command_line": "blah", 276 | "ppid": 1, 277 | "guid": "{12345678-1234-5678-1234-567812345678}", 278 | "start_time": "1970-01-01 00:00:01.000", 279 | "pguid": "{12345678-1234-5678-1234-567812345678}", 280 | "objectid": OntologyResults.create_objectid(tag="blah", ontology_id="blah", service_name="Cuckoo") 281 | } 282 | ], 283 | False, 284 | { 285 | "pid": 0, 286 | "name": "C:\\Users\\buddy\\AppData\\Local\\Temp\\blah.exe", "cmd": "blah", 287 | "signatures": {}, 288 | "children": [], 289 | } 290 | ), 291 | ] 292 | ) 293 | def test_build_process_tree(events, is_process_martian, correct_body): 294 | default_so = OntologyResults() 295 | for event in events: 296 | p = default_so.create_process(**event) 297 | default_so.add_process(p) 298 | correct_res_sec = ResultProcessTreeSection(title_text="Spawned Process Tree") 299 | actual_res_sec = ResultSection("blah") 300 | if correct_body: 301 | correct_res_sec.add_process(ProcessItem(**correct_body)) 302 | if is_process_martian: 303 | correct_res_sec.set_heuristic(19) 304 | correct_res_sec.heuristic.add_signature_id("process_martian", score=10) 305 | build_process_tree(actual_res_sec, is_process_martian, default_so) 306 | assert actual_res_sec.subsections[0].section_body.__dict__ == correct_res_sec.section_body.__dict__ 307 | else: 308 | build_process_tree(actual_res_sec, is_process_martian, default_so) 309 | assert actual_res_sec.subsections == [] 310 | 311 | @staticmethod 312 | @pytest.mark.parametrize( 313 | "name, marks, filename, filename_remainder, nolookup_comms, expected_result", 314 | [ 315 | ("blah", [], "blah.txt", "blah.txt", True, False), 316 | ("creates_doc", [{"ioc": "blah.exe", "type": "blah"}], "blah.txt", "blah.txt", True, False), 317 | ("creates_doc", [{"ioc": "blah.txt"}], "blah.txt", "blah.txt", True, True), 318 | ("creates_doc", [{"ioc": "~blahblahblahblahblah"}], 319 | "blahblahblahblahblah.txt", "blahblahblahblahblah", True, True), 320 | ("creates_doc", [{"ioc": "blah.exe", "type": "blah"}, { 321 | "ioc": "blah.txt", "type": "blah"}], "blah.txt", "blah.txt", True, False), 322 | ("creates_hidden_file", [{"call": {"arguments": {"filepath": "blah.exe"}}}], "blah.txt", "blah.txt", True, False), 323 | ("creates_hidden_file", [{"call": {"arguments": {"filepath": "blah.txt"}}}], "blah.txt", "blah.txt", True, True), 324 | ("creates_hidden_file", [{"call": {"arguments": {"filepath": "desktop.ini"}}}], 325 | "blah.txt", "blah.txt", True, True), 326 | ("creates_exe", [{"ioc": "blah.lnk"}], "blah.txt", "blah.txt", True, True), 327 | ("creates_exe", [{"ioc": "AppData\\Roaming\\Microsoft\\Office\\Recent\\Temp.LNK"}], 328 | "blah.txt", "blah.txt", True, True), 329 | ("network_cnc_http", [{"suspicious_request": "evil http://blah.com", 330 | "type": "generic"}], "blah.txt", "blah.txt", True, False), 331 | ("network_cnc_http", [{"suspicious_request": "benign http://w3.org", 332 | "type": "generic"}], "blah.txt", "blah.txt", True, True), 333 | ("nolookup_communication", [{"host": "http://blah.com", "type": "generic"}], "blah.txt", "blah.txt", True, False), 334 | ("nolookup_communication", [{"host": "http://w3.org", "type": "generic"}], "blah.txt", "blah.txt", True, True), 335 | ("nolookup_communication", [{"host": "192.0.2.123", "type": "generic"}], "blah.txt", "blah.txt", True, True), 336 | ("nolookup_communication", [{"host": "193.0.2.123", "type": "generic"}], "blah.txt", "blah.txt", True, False), 337 | ("blah", [{"suspicious_features": "blah", "type": "generic"}], "blah.txt", "blah.txt", True, False), 338 | ("blah", [{"entropy": "blah", "type": "generic"}], "blah.txt", "blah.txt", True, False), 339 | ("blah", [{"process": "blah", "type": "generic"}], "blah.txt", "blah.txt", True, False), 340 | ("blah", [{"useragent": "blah", "type": "generic"}], "blah.txt", "blah.txt", True, False), 341 | ("blah", [{"blah": "blah", "type": "generic"}], "blah.txt", "blah.txt", True, False), 342 | ("blah", [{"blah": "http://w3.org", "type": "generic"}], "blah.txt", "blah.txt", True, True), 343 | ("blah", [{"blah": "193.0.2.123", "type": "generic"}], "blah.txt", "blah.txt", True, False), 344 | ("blah", [{"blah": "192.0.2.123", "type": "generic"}], "blah.txt", "blah.txt", True, True), 345 | ("blah", [{"ioc": "blah", "type": "ioc"}], "blah.txt", "blah.txt", True, False), 346 | ("blah", [{"ioc": "blah", "type": "ioc", "category": "section"}], "blah.txt", "blah.txt", True, False), 347 | ("blah", [{"ioc": "http://w3.org", "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, True), 348 | ("network_http", [{"ioc": "benign http://w3.org/", "type": "ioc", 349 | "category": "blah"}], "blah.txt", "blah.txt", True, True), 350 | ("network_http", [{"ioc": "super benign http://w3.org/", 351 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, True), 352 | ("network_http", [{"ioc": "super http://w3.org/benign", 353 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, True), 354 | ("network_http_post", [{"ioc": "benign http://w3.org/", 355 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, True), 356 | ("network_http_post", [{"ioc": "super benign http://w3.org/", 357 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, True), 358 | ("network_http_post", [{"ioc": "super http://w3.org/benign", 359 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, True), 360 | ("network_http_post", [{"ioc": "super http://evil.com", 361 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, False), 362 | ("persistence_autorun", [{"ioc": "super http://evil.com", 363 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, False), 364 | ("network_icmp", [{"ioc": "192.0.2.123", 365 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, False), 366 | ("creates_shortcut", [{"ioc": "super http://evil.com", 367 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, False), 368 | ("ransomware_mass_file_delete", [{"ioc": "super http://evil.com", 369 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, False), 370 | ("suspicious_process", [{"ioc": "super http://evil.com", 371 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, False), 372 | ("uses_windows_utilities", [{"ioc": "super http://evil.com", 373 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, False), 374 | ("creates_exe", [{"ioc": "super http://evil.com", "type": "ioc", 375 | "category": "blah"}], "blah.txt", "blah.txt", True, False), 376 | ("deletes_executed_files", [{"ioc": "super http://evil.com", 377 | "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, False), 378 | ("blah", [{"ioc": "blah", "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, False), 379 | ("blah", [{"ioc": "192.0.2.123", "type": "ioc", "category": "blah"}], "blah.txt", "blah.txt", True, True), 380 | ("nolookup_communication", [{"host": "193.0.2.123", "type": "generic"}], "blah.txt", "blah.txt", False, True), 381 | ] 382 | ) 383 | def test_is_signature_a_false_positive(name, marks, filename, filename_remainder, nolookup_comms, expected_result): 384 | inetsim_network = ip_network("192.0.2.0/24") 385 | safelist = {"match": {"file.path": ["desktop.ini"]}, "regex": {"network.dynamic.domain": ["w3\.org"]}} 386 | assert _is_signature_a_false_positive( 387 | name, marks, filename, filename_remainder, inetsim_network, safelist, nolookup_comms) == expected_result 388 | 389 | @staticmethod 390 | def test_write_console_output_to_file(): 391 | _write_console_output_to_file(1, [{"call": {"arguments": {"buffer": "blah"}}}]) 392 | remove("/tmp/1_console_output.txt") 393 | assert True 394 | 395 | @staticmethod 396 | def test_write_injected_exe_to_file(): 397 | _write_injected_exe_to_file(1, [{"call": {"arguments": {"buffer": "blah"}}}]) 398 | remove("/tmp/1_injected_memory_0.exe") 399 | assert True 400 | 401 | # TODO: complete unit tests for process_network 402 | @staticmethod 403 | def test_process_network(): 404 | pass 405 | 406 | @staticmethod 407 | def test_get_dns_sec(): 408 | resolved_ips = {} 409 | safelist = [] 410 | assert _get_dns_sec(resolved_ips, safelist) is None 411 | resolved_ips = {"1.1.1.1": {"domain": "blah.com"}} 412 | expected_res_sec = ResultSection( 413 | "Protocol: DNS", 414 | body_format=BODY_FORMAT.TABLE, 415 | body=dumps([{"domain": "blah.com", "ip": "1.1.1.1"}]) 416 | ) 417 | expected_res_sec.set_heuristic(1000) 418 | expected_res_sec.add_tag("network.protocol", "dns") 419 | expected_res_sec.add_tag("network.dynamic.ip", "1.1.1.1") 420 | expected_res_sec.add_tag("network.dynamic.domain", "blah.com") 421 | actual_res_sec = _get_dns_sec(resolved_ips, safelist) 422 | assert check_section_equality(actual_res_sec, expected_res_sec) 423 | 424 | resolved_ips = {"0": {"domain": "blah.com"}} 425 | expected_res_sec = ResultSection( 426 | "Protocol: DNS", body_format=BODY_FORMAT.TABLE, body=dumps([{"domain": "blah.com"}]) 427 | ) 428 | expected_res_sec.set_heuristic(1000) 429 | expected_res_sec.add_tag("network.protocol", "dns") 430 | expected_res_sec.add_tag("network.dynamic.domain", "blah.com") 431 | expected_res_sec.add_subsection(ResultSection( 432 | title_text="DNS services are down!", 433 | body="Contact the CAPE administrator for details.", 434 | )) 435 | actual_res_sec = _get_dns_sec(resolved_ips, safelist) 436 | assert check_section_equality(actual_res_sec, expected_res_sec) 437 | 438 | 439 | @staticmethod 440 | @pytest.mark.parametrize( 441 | "dns_calls, process_map, routing, expected_return", 442 | [ 443 | ([], {}, "", {}), 444 | ([{"answers": []}], {}, "", {}), 445 | ([{"answers": [{"data": "answer"}], "request": "request", "type": "dns_type"}], {}, "", { 446 | 'answer': {'domain': 'request', "guid": None, "process_id": None, "process_name": None, "time": None, "type": "dns_type"}}), 447 | ([{"answers": [{"data": "answer"}], "request": "request", "type": "dns_type"}], {}, "INetSim", { 448 | 'answer': {'domain': 'request', "guid": None, "process_id": None, "process_name": None, "time": None, "type": "dns_type"}}), 449 | ([{"answers": [{"data": "answer"}], "request": "request", "type": "PTR"}], {}, "INetSim", {}), 450 | ([{"answers": [{"data": "answer"}], "request": "10.10.10.10.in-addr.arpa", "type": "PTR"}], 451 | {}, "Internet", {'10.10.10.10': {'domain': 'answer'}}), 452 | ([{"answers": [{"data": "10.10.10.10"}], "request": "answer", "type": "A"}, {"answers": [{"data": "answer"}], "request": "10.10.10.10.in-addr.arpa", 453 | "type": "PTR"}], {}, "Internet", {'10.10.10.10': {'domain': 'answer', "guid": None, "process_id": None, "process_name": None, "time": None, "type": "A"}}), 454 | ([{"answers": [{"data": "answer"}], "request": "ya:ba:da:ba:do:oo.ip6.arpa", "type": "PTR"}], {}, "Internet", {}), 455 | ([{"answers": [{"data": "answer"}], 456 | "request": "request", "type": "dns_type"}], 457 | {1: {"network_calls": [{"blah": {"hostname": "blah"}}]}}, 458 | "", 459 | {'answer': {'domain': 'request', "guid": None, "process_id": None, "process_name": None, "time": None, "type": "dns_type"}}), 460 | ([{"answers": [{"data": "answer"}], 461 | "request": "request", "type": "dns_type"}], 462 | {1: {"name": "blah", "network_calls": [{"blah": {"hostname": "request"}}]}}, 463 | "", 464 | {'answer': {'domain': 'request', "guid": None, "process_id": None, "process_name": None, "time": None, "type": "dns_type"}}), 465 | ([{"answers": [{"data": "answer"}], 466 | "request": "request", "type": "dns_type"}], 467 | {1: {"name": "blah", "network_calls": [{"getaddrinfo": {"hostname": "request"}}]}}, 468 | "", 469 | {'answer': {'domain': 'request', 'process_id': 1, 'process_name': 'blah', "guid": None, "time": None, "type": "dns_type"}}), 470 | ([{"answers": [{"data": "answer"}], 471 | "request": "request", "type": "dns_type"}], 472 | {1: {"name": "blah", "network_calls": [{"InternetConnectW": {"hostname": "request"}}]}}, 473 | "", 474 | {'answer': {'domain': 'request', 'process_id': 1, 'process_name': 'blah', "guid": None, "time": None, "type": "dns_type"}}), 475 | ([{"answers": [{"data": "answer"}], 476 | "request": "request", "type": "dns_type"}], 477 | {1: {"name": "blah", "network_calls": [{"InternetConnectA": {"hostname": "request"}}]}}, 478 | "", 479 | {'answer': {'domain': 'request', 'process_id': 1, 'process_name': 'blah', "guid": None, "time": None, "type": "dns_type"}}), 480 | ([{"answers": [{"data": "answer"}], 481 | "request": "request", "type": "dns_type"}], 482 | {1: {"name": "blah", "network_calls": [{"GetAddrInfoW": {"hostname": "request"}}]}}, 483 | "", 484 | {'answer': {'domain': 'request', 'process_id': 1, 'process_name': 'blah', "guid": None, "time": None, "type": "dns_type"}}), 485 | ([{"answers": [{"data": "answer"}], 486 | "request": "request", "type": "dns_type"}], 487 | {1: {"name": "blah", "network_calls": [{"gethostbyname": {"hostname": "request"}}]}}, 488 | "", 489 | {'answer': {'domain': 'request', 'process_id': 1, 'process_name': 'blah', "guid": None, "time": None, "type": "dns_type"}}), 490 | ([{"answers": []}], {1: {"name": "blah", "network_calls": [{"gethostbyname": {"hostname": "request"}}]}}, "", {}), 491 | ([{"answers": [{"data": "1.1.1.1"}], 492 | "request": "request", "type": "dns_type"}], 493 | {1: {"network_calls": [{"blah": {"hostname": "blah"}}]}}, "", {}), 494 | ([{"answers": [], 495 | "request": "request", "type": "dns_type"}], 496 | {}, 497 | "", 498 | { 499 | '0': { 500 | 'domain': 'request', 501 | 'guid': None, 502 | 'process_id': None, 503 | 'process_name': None, 504 | 'time': None, 505 | 'type': 'dns_type' 506 | } 507 | }), 508 | ] 509 | ) 510 | def test_get_dns_map(dns_calls, process_map, routing, expected_return): 511 | dns_servers = ["1.1.1.1"] 512 | assert _get_dns_map(dns_calls, process_map, routing, dns_servers) == expected_return 513 | 514 | @staticmethod 515 | @pytest.mark.parametrize( 516 | "resolved_ips, flows, expected_return", 517 | [({}, 518 | {}, 519 | ([], 520 | "")), 521 | ({}, 522 | {"udp": []}, 523 | ([], 524 | "")), 525 | ({}, 526 | {"udp": [{"dst": "blah", "src": "1.1.1.1", "time": "blah", "dport": 123}]}, 527 | ([{'dest_ip': 'blah', 'dest_port': 123, 'domain': None, 'image': None, 'pid': None, 528 | 'protocol': 'udp', 'src_ip': None, 'src_port': None, 'timestamp': 'blah'}], 529 | "")), 530 | ({}, 531 | {"udp": [{"dst": "blah", "src": "blah", "sport": "blah", "time": "blah", "dport": 123}]}, 532 | ([{'dest_ip': 'blah', 'dest_port': 123, 'domain': None, 'image': None, 'pid': None, 533 | 'protocol': 'udp', 'src_ip': "blah", 'src_port': "blah", 'timestamp': 'blah'}], 534 | "")), 535 | ({"blah": {"domain": "blah"}}, 536 | {"udp": [{"dst": "blah", "src": "blah", "sport": "blah", "time": "blah", "dport": 123}]}, 537 | ([{'dest_ip': 'blah', 'dest_port': 123, 'domain': "blah", 'image': None, 'pid': None, 538 | 'protocol': 'udp', 'src_ip': "blah", 'src_port': "blah", 'timestamp': 'blah'}], 539 | "")), 540 | ({"blah": {"domain": "blah", "process_name": "blah", "process_id": "blah"}}, 541 | {"udp": [{"dst": "blah", "src": "blah", "sport": "blah", "time": "blah", "dport": 123}]}, 542 | ([{'dest_ip': 'blah', 'dest_port': 123, 'domain': "blah", 'image': "blah", 'pid': "blah", 543 | 'protocol': 'udp', 'src_ip': "blah", 'src_port': "blah", 'timestamp': 'blah'}], 544 | "")), 545 | ({}, 546 | {}, 547 | ([], 548 | "flag"))]) 549 | def test_get_low_level_flows(resolved_ips, flows, expected_return): 550 | expected_network_flows_table, expected_netflows_sec_body = expected_return 551 | correct_netflows_sec = ResultTableSection(title_text="TCP/UDP Network Traffic") 552 | if expected_netflows_sec_body == "flag": 553 | too_many_unique_ips_sec = ResultSection(title_text="Too Many Unique IPs") 554 | too_many_unique_ips_sec.set_body(f"The number of TCP calls displayed has been capped " 555 | f"at 100. The full results can be found " 556 | f"in the supplementary PCAP file included with the analysis.") 557 | correct_netflows_sec.add_subsection(too_many_unique_ips_sec) 558 | flows = {"udp": []} 559 | expected_network_flows_table = [] 560 | for i in range(101): 561 | flows["udp"].append({"dst": "blah", "src": "1.1.1.1", "dport": f"blah{i}", "time": "blah"}) 562 | expected_network_flows_table.append({"protocol": "udp", "domain": None, "dest_ip": "blah", 563 | "src_ip": None, "src_port": None, "dest_port": f"blah{i}", 564 | "timestamp": "blah", "image": None, "pid": None}) 565 | expected_network_flows_table = expected_network_flows_table[:100] 566 | 567 | safelist = {"regex": {"network.dynamic.ip": ["(^1\.1\.1\.1$)|(^8\.8\.8\.8$)"]}} 568 | network_flows_table, netflows_sec = _get_low_level_flows(resolved_ips, flows, safelist) 569 | assert network_flows_table == expected_network_flows_table 570 | assert check_section_equality(netflows_sec, correct_netflows_sec) 571 | 572 | @staticmethod 573 | @pytest.mark.parametrize( 574 | "process_map, http_level_flows, expected_req_table", 575 | [ 576 | ({}, {}, []), 577 | ({}, {"http": [], "https": [], "http_ex": [], "https_ex": []}, []), 578 | ({}, {"http": [{"host": "blah", "path": "blah", "data": "blah", "port": 123, "uri": "http://blah", "method": "blah"}], "https": [], "http_ex": [], "https_ex": []}, []), 579 | ({}, {"http": [{"host": "3.3.3.3", "path": "blah", "data": "blah", "port": 123, "uri": "http://blah.com", "method": "blah"}], "https": [], "http_ex": [], "https_ex": []}, [ 580 | {'request_uri': "http://blah.com", 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': None, 'response_body_path': None}]), 581 | ({}, {"http": [], "https": [{"host": "3.3.3.3", "path": "blah", "data": "blah", "port": 123, "uri": "http://blah.com", "method": "blah"}], "http_ex": [], "https_ex": []}, [ 582 | {'request_uri': "http://blah.com", 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': None, 'response_body_path': None}]), 583 | ({}, {"http": [], "https": [], "http_ex": [{"host": "blah", "request": "blah", "dst": "2.2.2.2", "dport": 123, "uri": "http://blah.com", "protocol": "http", "method": "blah"}], "https_ex": []}, [ 584 | {'request_uri': "http://blah.com", 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': None, 'response_body_path': None}]), 585 | ({}, {"http": [], "https": [], "http_ex": [{"host": "nope.com", "request": "blah", "dst": "2.2.2.2", "dport": 123, "uri": "/blah", "protocol": "http", "method": "blah"}], "https_ex": []}, [ 586 | {'request_uri': 'http://nope.com/blah', 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': None, 'response_body_path': None}]), 587 | ({}, {"http": [], "https": [], "http_ex": [], "https_ex": [{"host": "nope.com", "request": "blah", "dst": "2.2.2.2", "dport": 123, "uri": "/blah", "protocol": "https", "method": "blah"}]}, [ 588 | {'request_uri': 'https://nope.com/blah', 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': None, 'response_body_path': None}]), 589 | ({}, {"http": [{"host": "192.168.0.1", "path": "blah", "data": "blah", "port": 123, 590 | "uri": "blah", "method": "blah"}], "https": [], "http_ex": [], "https_ex": []}, []), 591 | ({}, {"http": [{"host": "something.adobe.com", "path": "blah", "data": "blah", "port": 123, 592 | "uri": "blah", "method": "blah"}], "https": [], "http_ex": [], "https_ex": []}, []), 593 | ({}, {"http": [{"host": "3.3.3.3", "path": "blah", "data": "blah", "port": 123, 594 | "uri": "http://localhost/blah", "method": "blah"}], "https": [], "http_ex": [], "https_ex": []}, []), 595 | ( 596 | {}, 597 | { 598 | "http": 599 | [{"host": "3.3.3.3", "path": "blah", "data": "blah", "port": 123, "uri": "http://blah.com", "method": "blah"}, 600 | {"host": "3.3.3.3", "path": "blah", "data": "blah", "port": 123, "uri": "http://blah.com", "method": "blah"}], 601 | "https": [], 602 | "http_ex": [], 603 | "https_ex": []}, 604 | [{'request_uri': "http://blah.com", 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': None, 'response_body_path': None}]), 605 | ({1: {"network_calls": [{"send": {"service": 3}}], "name": "blah"}}, {"http": [{"host": "3.3.3.3", "path": "blah", "data": "blah", "port": 123, "uri": "http://blah.com", "method": "blah"}], "https": [], "http_ex": [ 606 | ], "https_ex": []}, [{'request_uri': "http://blah.com", 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': None, 'response_body_path': None}]), 607 | ({1: {"network_calls": [{"InternetConnectW": {"buffer": "check me"}}], "name": "blah"}}, {"http": [{"host": "3.3.3.3", "path": "blah", "data": "check me", "port": 123, "uri": "http://blah.com", "method": "blah"}], "https": [ 608 | ], "http_ex": [], "https_ex": []}, [{'request_uri': "http://blah.com", 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': None, 'response_body_path': None}]), 609 | ({1: {"network_calls": [{"InternetConnectA": {"buffer": "check me"}}], "name": "blah"}}, {"http": [{"host": "3.3.3.3", "path": "blah", "data": "check me", "port": 123, "uri": "http://blah.com", "method": "blah"}], "https": [ 610 | ], "http_ex": [], "https_ex": []}, [{'request_uri': "http://blah.com", 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': None, 'response_body_path': None}]), 611 | ({1: {"network_calls": [{"URLDownloadToFileW": {"url": "http://bad.evil"}}], "name": "blah"}}, {"http": [{"host": "3.3.3.3", "path": "blah", "data": "check me", "port": 123, "uri": "http://bad.evil", "method": "blah"}], "https": [ 612 | ], "http_ex": [], "https_ex": []}, [{'request_uri': 'http://bad.evil', 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': None, 'response_body_path': None}]), 613 | ({}, {"http": [], "https": [], "http_ex": [], "https_ex": [{"host": "nope.com", "req": {"path": "/blahblah/network/blahblah"}, "resp": {"path": "blahblah/network/blahblah"}, "dport": 123, "uri": "/blah", "protocol": "https", "method": "blah", "sport": 123, "dst": "blah", "src": "blah", "response": "blah", "request": "blah"}]}, [ 614 | {'request_uri': 'https://nope.com/blah', 'request_headers': {}, 'request_body': None, 'request_method': 'blah', 'response_headers': {}, 'response_status_code': None, 'response_body': None, 'request_body_path': 'network/blahblah', 'response_body_path': 'network/blahblah'}]), 615 | 616 | ] 617 | ) 618 | def test_process_http_calls(process_map, http_level_flows, expected_req_table, mocker): 619 | default_so = OntologyResults(service_name="Cuckoo") 620 | mocker.patch.object(default_so, "sandboxes", return_value="blah") 621 | safelist = { 622 | "regex": 623 | {"network.dynamic.ip": ["(?:127\.|10\.|192\.168|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[01]\.).*"], 624 | "network.dynamic.domain": [".*\.adobe\.com$"], 625 | "network.dynamic.uri": ["(?:ftp|http)s?://localhost(?:$|/.*)"]}} 626 | dns_servers = [] 627 | _process_http_calls(http_level_flows, process_map, dns_servers, safelist, default_so) 628 | actual_req_table = [] 629 | for nh in default_so.get_network_http(): 630 | nh_as_prim = nh.__dict__ 631 | actual_req_table.append(nh_as_prim) 632 | assert expected_req_table == actual_req_table 633 | 634 | @staticmethod 635 | @pytest.mark.parametrize( 636 | "header_string, expected_header_dict", 637 | [("", {}), 638 | (None, {}), 639 | ("GET /blah/blah/blah.doc HTTP/1.1", {}), 640 | ("GET /blah/blah/blah.doc HTTP/1.1\r\n", {}), 641 | ("GET /blah/blah/blah.doc HTTP/1.1\r\nblah", {}), 642 | ( 643 | "GET /blah/blah/blah.doc HTTP/1.1\r\nConnection: Keep-Alive\r\nAccept: */*\r\nIf-Modified-Since: Sat, 01 Jul 2022 00:00:00 GMT\r\nUser-Agent: Microsoft-CryptoAPI/10.0\r\nHost: blah.blah.com", 644 | {'Connection': 'Keep-Alive', 'Accept': '*/*', 'IfModifiedSince': 'Sat, 01 Jul 2022 00:00:00 GMT', 645 | 'UserAgent': 'Microsoft-CryptoAPI/10.0', 'Host': 'blah.blah.com'})]) 646 | def test_handle_http_headers(header_string, expected_header_dict): 647 | assert _handle_http_headers(header_string) == expected_header_dict 648 | 649 | @staticmethod 650 | def test_extract_iocs_from_encrypted_buffers(): 651 | test_parent_section = ResultSection("blah") 652 | correct_result_section = ResultTableSection("IOCs found in encrypted buffers used in network calls") 653 | correct_result_section.set_heuristic(1006) 654 | correct_result_section.add_row(TableRow({"ioc_type": "domain", "ioc": "blah.ca"})) 655 | correct_result_section.add_row(TableRow({"ioc_type": "domain", "ioc": "blah.com"})) 656 | correct_result_section.add_tag("network.dynamic.domain", "blah.ca") 657 | correct_result_section.add_tag("network.dynamic.domain", "blah.com") 658 | safelist = {} 659 | _extract_iocs_from_encrypted_buffers({1: {"network_calls": [{"send": {"buffer": "blah.com"}}]}, 2: { 660 | "network_calls": [{"send": {"buffer": "blah.ca"}}]}}, test_parent_section, safelist) 661 | assert check_section_equality(test_parent_section.subsections[0], correct_result_section) 662 | 663 | @staticmethod 664 | def test_process_non_http_traffic_over_http(): 665 | test_parent_section = ResultSection("blah") 666 | network_flows = [{"dest_port": 80, "dest_ip": "127.0.0.1", "domain": "blah.com"}, 667 | {"dest_port": 443, "dest_ip": "127.0.0.2", "domain": "blah2.com"}] 668 | correct_result_section = ResultSection("Non-HTTP Traffic Over HTTP Ports") 669 | correct_result_section.set_heuristic(1005) 670 | correct_result_section.add_tag("network.dynamic.ip", "127.0.0.1") 671 | correct_result_section.add_tag("network.dynamic.ip", "127.0.0.2") 672 | correct_result_section.add_tag("network.dynamic.domain", "blah.com") 673 | correct_result_section.add_tag("network.dynamic.domain", "blah2.com") 674 | correct_result_section.add_tag("network.port", 80) 675 | correct_result_section.add_tag("network.port", 443) 676 | correct_result_section.set_body(dumps(network_flows), BODY_FORMAT.TABLE) 677 | _process_non_http_traffic_over_http(test_parent_section, network_flows) 678 | assert check_section_equality(test_parent_section.subsections[0], correct_result_section) 679 | 680 | @staticmethod 681 | def test_process_all_events(): 682 | default_so = OntologyResults() 683 | al_result = ResultSection("blah") 684 | p = default_so.create_process( 685 | pid=1, ppid=1, guid="{12345678-1234-5678-1234-567812345679}", command_line="blah blah.com", image="blah", 686 | start_time="1970-01-01 00:00:01.000", pguid="{12345678-1234-5678-1234-567812345679}", 687 | objectid=OntologyResults.create_objectid(tag="blah", ontology_id="blah", service_name="Cuckoo") 688 | ) 689 | default_so.add_process(p) 690 | nc = default_so.create_network_connection( 691 | source_port=1, destination_ip="1.1.1.1", source_ip="2.2.2.2", destination_port=1, 692 | transport_layer_protocol="udp", direction="outbound", process=p, 693 | objectid=OntologyResults.create_objectid(tag="blah", ontology_id="blah", service_name="Cuckoo", time_observed="1970-01-01 00:00:02.000") 694 | ) 695 | 696 | default_so.add_network_connection(nc) 697 | dns = default_so.create_network_dns(domain="blah", resolved_ips=["1.1.1.1"], lookup_type="A") 698 | default_so.add_network_dns(dns) 699 | 700 | correct_result_section = ResultTableSection(title_text="Event Log") 701 | 702 | correct_result_section.add_tag("dynamic.process.command_line", "blah blah.com") 703 | correct_result_section.add_tag("dynamic.process.file_name", "blah") 704 | 705 | correct_result_section.add_row( 706 | TableRow( 707 | ** 708 | {"time_observed": "1970-01-01 00:00:01.000", "process_name": "blah (1)", 709 | "details": {"command_line": "blah blah.com"}})) 710 | correct_result_section.add_row( 711 | TableRow( 712 | ** 713 | {"time_observed": "1970-01-01 00:00:02.000", "process_name": "blah (1)", 714 | "details": {"protocol": "udp", "domain": "blah", "dest_ip": "1.1.1.1", "dest_port": 1}})) 715 | 716 | correct_ioc_table = ResultTableSection("Event Log IOCs") 717 | correct_ioc_table.add_tag("network.dynamic.domain", "blah.com") 718 | table_data = [{"ioc_type": "domain", "ioc": "blah.com"}] 719 | for item in table_data: 720 | correct_ioc_table.add_row(TableRow(**item)) 721 | correct_result_section.add_subsection(correct_ioc_table) 722 | 723 | process_all_events(al_result, default_so) 724 | assert check_section_equality(al_result.subsections[0], correct_result_section) 725 | 726 | @staticmethod 727 | @pytest.mark.parametrize( 728 | "curtain, process_map", 729 | [ 730 | ({}, {0: {"blah": "blah"}}), 731 | ({"1": {"events": [{"command": {"original": "blah", "altered": "blah"}}], 732 | "behaviors": ["blah"]}}, {0: {"blah": "blah"}}), 733 | ({"1": {"events": [{"command": {"original": "blah", "altered": "No alteration of event"}}], 734 | "behaviors": ["blah"]}}, {0: {"blah": "blah"}}), 735 | ({"1": {"events": [{"command": {"original": "blah", "altered": "No alteration of event"}}], 736 | "behaviors": ["blah"]}}, {1: {"name": "blah.exe"}}), 737 | ]) 738 | def test_process_curtain(curtain, process_map): 739 | al_result = ResultSection("blah") 740 | 741 | curtain_body = [] 742 | correct_result_section = ResultSection(title_text="PowerShell Activity") 743 | for pid in curtain.keys(): 744 | process_name = process_map[int(pid)]["name"] if process_map.get(int(pid)) else "powershell.exe" 745 | for event in curtain[pid]["events"]: 746 | for command in event.keys(): 747 | curtain_item = { 748 | "process_name": process_name, 749 | "original": event[command]["original"], 750 | "reformatted": None 751 | } 752 | altered = event[command]["altered"] 753 | if altered != "No alteration of event.": 754 | curtain_item["reformatted"] = altered 755 | curtain_body.append(curtain_item) 756 | for behaviour in curtain[pid]["behaviors"]: 757 | correct_result_section.add_tag("file.powershell.cmdlet", behaviour) 758 | correct_result_section.set_body(json.dumps(curtain_body), BODY_FORMAT.TABLE) 759 | 760 | process_curtain(curtain, al_result, process_map) 761 | if len(al_result.subsections) > 0: 762 | assert check_section_equality(al_result.subsections[0], correct_result_section) 763 | else: 764 | assert al_result.subsections == [] 765 | 766 | @staticmethod 767 | def test_process_hollowshunter(): 768 | hollowshunter = {} 769 | process_map = {123: {"name": "blah"}} 770 | al_result = ResultSection("blah") 771 | 772 | process_hollowshunter(hollowshunter, al_result, process_map) 773 | assert al_result.subsections == [] 774 | 775 | hollowshunter = {"123": {"scanned": {"modified": {"implanted_pe": 1}}, "scans": [{"workingset_scan": {"has_pe": 1, "module": "400000"}}]}} 776 | hollowshunter_body = [{"Process": "blah (123)", "Indicator": "Implanted PE", "Description": "Modules found: ['400000']"}] 777 | correct_result_section = ResultTableSection("HollowsHunter Analysis") 778 | [correct_result_section.add_row(TableRow(**row)) for row in hollowshunter_body] 779 | 780 | process_hollowshunter(hollowshunter, al_result, process_map) 781 | assert check_section_equality(al_result.subsections[0], correct_result_section) 782 | 783 | 784 | @staticmethod 785 | @pytest.mark.parametrize("process_map, correct_buffer_body, correct_tags, correct_body", 786 | [({0: {"decrypted_buffers": []}}, 787 | None, {}, 788 | []), 789 | ({0: {"decrypted_buffers": [{"blah": "blah"}]}}, 790 | None, {}, 791 | []), 792 | ({0: {"decrypted_buffers": [{"CryptDecrypt": {"buffer": "blah"}}]}}, 793 | '[{"Decrypted Buffer": "blah"}]', {}, 794 | []), 795 | ({0: {"decrypted_buffers": [{"OutputDebugStringA": {"string": "blah"}}]}}, 796 | '[{"Decrypted Buffer": "blah"}]', {}, 797 | []), 798 | ({0: {"decrypted_buffers": [{"OutputDebugStringA": {"string": "127.0.0.1"}}]}}, 799 | '[{"Decrypted Buffer": "127.0.0.1"}]', {'network.dynamic.ip': ['127.0.0.1']}, 800 | [{"ioc_type": "ip", "ioc": "127.0.0.1"}]), 801 | ({0: {"decrypted_buffers": [{"OutputDebugStringA": {"string": "blah.ca"}}]}}, 802 | '[{"Decrypted Buffer": "blah.ca"}]', {'network.dynamic.domain': ['blah.ca']}, 803 | [{"ioc_type": "domain", "ioc": "blah.ca"}]), 804 | ({0: {"decrypted_buffers": [{"OutputDebugStringA": {"string": "127.0.0.1:999"}}]}}, 805 | '[{"Decrypted Buffer": "127.0.0.1:999"}]', 806 | {'network.dynamic.ip': ['127.0.0.1']}, 807 | [{"ioc_type": "ip", "ioc": "127.0.0.1"}]), ]) 808 | def test_process_decrypted_buffers(process_map, correct_buffer_body, correct_tags, correct_body): 809 | parent_section = ResultSection("blah") 810 | process_decrypted_buffers(process_map, parent_section) 811 | 812 | if correct_buffer_body is None: 813 | assert parent_section.subsections == [] 814 | else: 815 | correct_result_section = ResultSection(title_text="Decrypted Buffers") 816 | correct_result_section.set_body(correct_buffer_body, BODY_FORMAT.TABLE) 817 | buffer_ioc_table = ResultTableSection("Decrypted Buffer IOCs") 818 | 819 | for item in correct_body: 820 | buffer_ioc_table.add_row(TableRow(**item)) 821 | if correct_body: 822 | correct_result_section.add_subsection(buffer_ioc_table) 823 | correct_result_section.set_heuristic(1006) 824 | for tag, values in correct_tags.items(): 825 | for value in values: 826 | buffer_ioc_table.add_tag(tag, value) 827 | assert check_section_equality(parent_section.subsections[0], correct_result_section) 828 | 829 | @staticmethod 830 | @pytest.mark.parametrize( 831 | "processes, correct_process_map", 832 | [ 833 | ([], {}), 834 | ([{"process_path": "C:\\windows\\System32\\lsass.exe", "calls": [], "pid": 1}], {}), 835 | ([{"process_path": "blah.exe", "calls": [], "pid": 1}], { 836 | 1: {'name': 'blah.exe', 'network_calls': [], 'decrypted_buffers': []}}), 837 | ([{"process_path": "blah.exe", "calls": [{"api": "blah"}], "pid": 1}], { 838 | 1: {'name': 'blah.exe', 'network_calls': [], 'decrypted_buffers': []}}), 839 | ([{"process_path": "blah.exe", "calls": [{"category": "network", "api": "getaddrinfo", "arguments": {"hostname": "blah"}}], "pid": 1}], { 840 | 1: {'name': 'blah.exe', 'network_calls': [{"getaddrinfo": {"hostname": "blah"}}], 'decrypted_buffers': []}}), 841 | ([{"process_path": "blah.exe", "calls": [{"category": "network", "api": "GetAddrInfoW", "arguments": {"hostname": "blah"}}], "pid": 1}], { 842 | 1: {'name': 'blah.exe', 'network_calls': [{"GetAddrInfoW": {"hostname": "blah"}}], 'decrypted_buffers': []}}), 843 | ([{"process_path": "blah.exe", "calls": [{"category": "network", "api": "connect", "arguments": {"ip_address": "blah", "port": 123}}], "pid": 1}], { 844 | 1: {'name': 'blah.exe', 'network_calls': [{"connect": {"ip_address": "blah", "port": 123}}], 'decrypted_buffers': []}}), 845 | ([{"process_path": "blah.exe", "calls": [{"category": "network", "api": "InternetConnectW", "arguments": {"username": "blah", "service": "blah", "password": "blah", "hostname": "blah", "port": 123}}], "pid": 1}], { 846 | 1: {'name': 'blah.exe', 'network_calls': [{"InternetConnectW": {"username": "blah", "service": "blah", "password": "blah", "hostname": "blah", "port": 123}}], 'decrypted_buffers': []}}), 847 | ([{"process_path": "blah.exe", "calls": [{"category": "network", "api": "InternetConnectA", "arguments": {"username": "blah", "service": "blah", "password": "blah", "hostname": "blah", "port": 123}}], "pid": 1}], { 848 | 1: {'name': 'blah.exe', 'network_calls': [{"InternetConnectA": {"username": "blah", "service": "blah", "password": "blah", "hostname": "blah", "port": 123}}], 'decrypted_buffers': []}}), 849 | ([{"process_path": "blah.exe", "calls": [{"category": "network", "api": "send", "arguments": {"buffer": "blah"}}], "pid": 1}], { 850 | 1: {'name': 'blah.exe', 'network_calls': [{"send": {"buffer": "blah"}}], 'decrypted_buffers': []}}), 851 | ([{"process_path": "blah.exe", "calls": [{"category": "crypto", "api": "CryptDecrypt", "arguments": {"buffer": "blah"}}], "pid": 1}], { 852 | 1: {'name': 'blah.exe', 'network_calls': [], 'decrypted_buffers': [{"CryptDecrypt": {"buffer": "blah"}}]}}), 853 | ([{"process_path": "blah.exe", "calls": [{"category": "system", "api": "OutputDebugStringA", "arguments": { 854 | "string": "blah"}}], "pid": 1}], {1: {'name': 'blah.exe', 'network_calls': [], 'decrypted_buffers': []}}), 855 | ([{"process_path": "blah.exe", "calls": [{"category": "system", "api": "OutputDebugStringA", "arguments": {"string": "cfg:blah"}}], "pid": 1}], { 856 | 1: {'name': 'blah.exe', 'network_calls': [], 'decrypted_buffers': [{"OutputDebugStringA": {"string": "cfg:blah"}}]}}), 857 | ([{"process_path": "blah.exe", "calls": [{"category": "network", "api": "URLDownloadToFileW", "arguments": {"url": "bad.evil"}}], "pid": 1}], { 858 | 1: {'name': 'blah.exe', 'network_calls': [{"URLDownloadToFileW": {"url": "bad.evil"}}], 'decrypted_buffers': []}}), 859 | ([{"process_path": "blah.exe", "calls": [{"category": "network", "api": "WSASend", "arguments": {"buffer": "blahblahblah bad.evil blahblahblah"}}], "pid": 1}], { 860 | 1: {'name': 'blah.exe', 'network_calls': [{"WSASend": {"buffer": "blahblahblah bad.evil blahblahblah"}}], 'decrypted_buffers': []}}), 861 | ] 862 | ) 863 | def test_get_process_map(processes, correct_process_map): 864 | safelist = {"regex": {"dynamic.process.file_name": [r"C:\\Windows\\System32\\lsass\.exe"]}} 865 | assert get_process_map(processes, safelist) == correct_process_map 866 | 867 | @staticmethod 868 | @pytest.mark.parametrize( 869 | "sigs, correct_sigs", 870 | [ 871 | ([], []), 872 | ([{"name": "network_cnc_http"}], [{"name": "network_cnc_http"}]), 873 | ([{"name": "network_cnc_http"}, {"name": "network_http"}], [{"name": "network_cnc_http"}]), 874 | ] 875 | ) 876 | def test_remove_network_http_noise(sigs, correct_sigs): 877 | assert _remove_network_http_noise(sigs) == correct_sigs 878 | 879 | @staticmethod 880 | def test_update_process_map(): 881 | process_map = {} 882 | _update_process_map(process_map, []) 883 | assert process_map == {} 884 | 885 | default_so = OntologyResults() 886 | p = default_so.create_process( 887 | start_time="1970-01-01 00:00:02", 888 | pid=1, 889 | image="blah", 890 | objectid=OntologyResults.create_objectid(tag="blah", ontology_id="blah", service_name="CAPE") 891 | ) 892 | 893 | _update_process_map(process_map, [p]) 894 | assert process_map == {1: {"name": "blah", "network_calls": [], "decrypted_buffers": []}} 895 | --------------------------------------------------------------------------------